validate([ 'id_petugas' => 'required', 'password' => 'required' ]); $petugas = DB::table('petugas') ->where('id_petugas', $request->id_petugas) ->first(); if (!$petugas) { return back()->with('error', 'ID tidak ditemukan!'); } if ($petugas->status != 'aktif') { return back()->with('error', 'Akun tidak aktif. Silakan hubungi super admin.'); } if (!Hash::check($request->password, $petugas->password)) { return back()->with('error', 'Password salah!'); } $request->session()->invalidate(); $request->session()->regenerateToken(); $request->session()->regenerate(); // Cek apakah petugas punya fasyankes $nama_fasyankes = null; if ($petugas->role != 'super_admin' && $petugas->id_fasyankes) { $fasyankes = DB::table('fasyankes') ->where('id_fasyankes', $petugas->id_fasyankes) ->first(); $nama_fasyankes = $fasyankes ? $fasyankes->nama_fasyankes : null; } session([ 'petugas_db_id' => $petugas->id, 'petugas_id' => $petugas->id_petugas, 'nama_petugas' => $petugas->nama_petugas, 'nama_fasyankes' => $nama_fasyankes, 'role' => $petugas->role, 'id_fasyankes' => $petugas->id_fasyankes ]); DB::table('log_aktivitas')->insert([ 'id_petugas' => $petugas->id_petugas, 'aktivitas' => 'Login ke sistem', 'created_at' => now(), 'updated_at' => now() ]); return redirect('/dashboard'); } public function logout(Request $request) { $id_petugas = session('petugas_id'); if ($id_petugas) { DB::table('log_aktivitas')->insert([ 'id_petugas' => $id_petugas, 'aktivitas' => 'Logout dari sistem', 'created_at' => now(), 'updated_at' => now() ]); } $request->session()->forget([ 'petugas_id', 'nama_petugas', 'nama_fasyankes', 'role', 'id_fasyankes' ]); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/')->with('success', 'Anda telah berhasil logout.'); } public function sendOtp(Request $request) { $request->validate([ 'id_petugas' => 'required', 'email' => 'required|email' ], [ 'id_petugas.required' => 'ID Petugas wajib diisi.', 'email.required' => 'Email wajib diisi.', 'email.email' => 'Format email tidak valid.' ]); // Cari data petugas $petugas = DB::table('petugas') ->where('id_petugas', trim($request->id_petugas)) ->whereRaw( 'LOWER(TRIM(email)) = ?', [strtolower(trim($request->email))] ) ->first(); // Jika tidak ditemukan if (!$petugas) { return redirect()->back()->with( 'forgot_error', 'ID Petugas atau Email tidak sesuai.' ); } // Generate OTP $otp = rand(100000, 999999); // Simpan OTP DB::table('petugas') ->where('id_petugas', $petugas->id_petugas) ->update([ 'otp_code' => $otp, 'otp_expired_at' => Carbon::now()->addMinutes(5) ]); try { $html = '
🔐

Reset Password

Gunakan kode OTP berikut untuk reset password akun Anda.

'.$otp.'

OTP berlaku selama 5 menit.

Jangan bagikan kode OTP ini kepada siapapun.

'; Mail::html($html, function ($message) use ($petugas) { $message->to(trim($petugas->email)) ->subject('OTP Reset Password Sistem TB'); }); } catch (\Exception $e) { return redirect()->back()->with( 'forgot_error', 'Gagal mengirim OTP: '.$e->getMessage() ); } $nama_fasyankes = null; if ($petugas->role != 'super_admin' && $petugas->id_fasyankes) { $fasyankes = DB::table('fasyankes') ->where('id_fasyankes', $petugas->id_fasyankes) ->first(); $nama_fasyankes = $fasyankes ? $fasyankes->nama_fasyankes : null; } // Simpan session session([ 'petugas_id' => $petugas->id_petugas, 'nama_petugas' => $petugas->nama_petugas, 'nama_fasyankes' => $nama_fasyankes, 'role' => $petugas->role, 'id_fasyankes' => $petugas->id_fasyankes ]); return redirect('/verifikasi-otp') ->with( 'success', 'Kode OTP berhasil dikirim ke email.' ); } public function sendOtpMobile(Request $request) { $validator = Validator::make($request->all(), [ 'nik' => 'required', 'email' => 'required|email' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } // CEK USER BERDASARKAN NIK + EMAIL $user = DB::table('users') ->where('nik', trim($request->nik)) ->whereRaw( 'LOWER(TRIM(email)) = ?', [strtolower(trim($request->email))] ) ->first(); if (!$user) { return response()->json([ 'success' => false, 'message' => 'NIK atau Email tidak sesuai.' ], 404); } // GENERATE OTP $otp = rand(100000, 999999); // SIMPAN OTP DB::table('users') ->where('id_user', $user->id_user) ->update([ 'otp_code' => $otp, 'otp_expired_at' => Carbon::now()->addMinutes(5) ]); try { $html = '

Reset Password

Gunakan kode OTP berikut:

'.$otp.'

OTP berlaku selama 5 menit.

'; Mail::html($html, function ($message) use ($user) { $message->to(trim($user->email)) ->subject('OTP Reset Password'); }); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Gagal mengirim OTP: '.$e->getMessage() ], 500); } return response()->json([ 'success' => true, 'message' => 'OTP berhasil dikirim ke email.' ]); } public function verifyOtpOnlyMobile(Request $request) { $validator = Validator::make($request->all(), [ 'nik' => 'required', 'email' => 'required|email', 'otp' => 'required|digits:6', ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } $user = DB::table('users') ->where('nik', $request->nik) ->where('email', $request->email) ->where('otp_code', $request->otp) ->first(); if (!$user) { return response()->json([ 'success' => false, 'message' => 'Kode OTP salah.' ], 400); } if ( Carbon::now()->gt( Carbon::parse($user->otp_expired_at) ) ) { return response()->json([ 'success' => false, 'message' => 'Kode OTP sudah kadaluarsa.' ], 400); } return response()->json([ 'success' => true, 'message' => 'OTP berhasil diverifikasi.' ]); } public function resetPasswordMobile(Request $request) { $validator = Validator::make($request->all(), [ 'nik' => 'required', 'password' => 'required|min:8', ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } // CARI USER $user = DB::table('users') ->where('nik', $request->nik) ->first(); // USER TIDAK DITEMUKAN if (!$user) { return response()->json([ 'success' => false, 'message' => 'User tidak ditemukan.' ], 404); } // PASSWORD BARU TIDAK BOLEH SAMA if (Hash::check($request->password, $user->password)) { return response()->json([ 'success' => false, 'message' => 'Password baru tidak boleh sama dengan password lama.' ], 400); } // UPDATE PASSWORD DB::table('users') ->where('id_user', $user->id_user) ->update([ 'password' => bcrypt($request->password), 'otp_code' => null, 'otp_expired_at' => null ]); return response()->json([ 'success' => true, 'message' => 'Password berhasil diperbarui.' ]); } public function verifyOtp(Request $request) { $request->validate([ 'id_petugas' => 'required', 'email' => 'required|email', 'otp' => 'required|digits:6', 'password' => 'required|min:8|confirmed' ], [ 'otp.required' => 'Kode OTP wajib diisi.', 'otp.digits' => 'Kode OTP harus 6 digit.', 'password.confirmed' => 'Konfirmasi password tidak cocok.' ]); // Cari data petugas $petugas = DB::table('petugas') ->where('id_petugas', $request->id_petugas) ->where('email', $request->email) ->where('otp_code', $request->otp) ->first(); // Jika OTP salah if (!$petugas) { return redirect()->back()->with( 'forgot_error', 'Kode OTP salah.' ); } // Jika OTP expired if ( Carbon::now()->gt( Carbon::parse($petugas->otp_expired_at) ) ) { return redirect()->back()->with( 'forgot_error', 'Kode OTP sudah kadaluarsa.' ); } // Update password DB::table('petugas') ->where('id_petugas', $request->id_petugas) ->update([ 'password' => bcrypt($request->password), 'otp_code' => null, 'otp_expired_at' => null ]); // Hapus session reset session()->forget([ 'reset_id_petugas', 'reset_email' ]); return redirect('/') ->with( 'success', 'Password berhasil diperbarui.' ); } public function verifyOtpMobile(Request $request) { $validator = Validator::make($request->all(), [ 'nik' => 'required', 'email' => 'required|email', 'otp' => 'required|digits:6', 'password' => 'required|min:8' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } // CEK USER + OTP $user = DB::table('users') ->where('nik', $request->nik) ->where('email', $request->email) ->where('otp_code', $request->otp) ->first(); // OTP SALAH if (!$user) { return response()->json([ 'success' => false, 'message' => 'Kode OTP salah.' ], 400); } // OTP EXPIRED if ( Carbon::now()->gt( Carbon::parse($user->otp_expired_at) ) ) { return response()->json([ 'success' => false, 'message' => 'Kode OTP sudah kadaluarsa.' ], 400); } // PASSWORD BARU TIDAK BOLEH SAMA if (Hash::check($request->password, $user->password)) { return response()->json([ 'success' => false, 'message' => 'Password baru tidak boleh sama dengan password lama.' ], 400); } // UPDATE PASSWORD DB::table('users') ->where('id_user', $user->id_user) ->update([ 'password' => bcrypt($request->password), 'otp_code' => null, 'otp_expired_at' => null ]); return response()->json([ 'success' => true, 'message' => 'Password berhasil diperbarui.' ]); } public function logoutToken(Request $request) { DB::table('fcm_tokens') ->where('id_user', $request->id_user) ->delete(); return response()->json([ 'success' => true ]); } public function sendOtpJson(Request $request) { $validator = Validator::make($request->all(), [ 'id_petugas' => 'required', 'email' => 'required|email' ], [ 'id_petugas.required' => 'ID Petugas wajib diisi.', 'email.required' => 'Email wajib diisi.', 'email.email' => 'Format email tidak valid.' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } $petugas = DB::table('petugas') ->where('id_petugas', trim($request->id_petugas)) ->whereRaw( 'LOWER(TRIM(email)) = ?', [strtolower(trim($request->email))] ) ->first(); if (!$petugas) { return response()->json([ 'success' => false, 'message' => 'ID Petugas atau Email tidak sesuai.' ], 404); } $otp = rand(100000, 999999); DB::table('petugas') ->where('id_petugas', $petugas->id_petugas) ->update([ 'otp_code' => $otp, 'otp_expired_at' => Carbon::now()->addMinutes(5) ]); try { $html = '
🔐

Reset Password

Gunakan kode OTP berikut untuk reset password akun Anda.

'.$otp.'

OTP berlaku selama 5 menit.

Jangan bagikan kode OTP ini kepada siapapun.

'; Mail::html($html, function ($message) use ($petugas) { $message->to(trim($petugas->email)) ->subject('OTP Reset Password Sistem TB'); }); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Gagal mengirim OTP: '.$e->getMessage() ], 500); } return response()->json([ 'success' => true, 'message' => 'Kode OTP berhasil dikirim ke email.' ]); } public function verifyOtpJson(Request $request) { $validator = Validator::make($request->all(), [ 'id_petugas' => 'required', 'email' => 'required|email', 'otp' => 'required|digits:6', 'cek_otp' => 'nullable', 'password' => 'nullable|min:8' ], [ 'otp.required' => 'Kode OTP wajib diisi.', 'otp.digits' => 'Kode OTP harus 6 digit.', 'password.min' => 'Password minimal 8 karakter.' ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => $validator->errors()->first() ], 422); } $petugas = DB::table('petugas') ->where('id_petugas', $request->id_petugas) ->whereRaw( 'LOWER(TRIM(email)) = ?', [strtolower(trim($request->email))] ) ->where('otp_code', $request->otp) ->first(); if (!$petugas) { return response()->json([ 'success' => false, 'message' => 'Kode OTP salah.' ], 400); } if (Carbon::now()->gt(Carbon::parse($petugas->otp_expired_at))) { return response()->json([ 'success' => false, 'message' => 'Kode OTP sudah kadaluarsa.' ], 400); } // JIKA HANYA CEK OTP (TANPA UPDATE PASSWORD) if ($request->cek_otp) { return response()->json([ 'success' => true, 'message' => 'OTP valid.' ]); } if (!$request->password) { return response()->json([ 'success' => false, 'message' => 'Password baru wajib diisi.' ], 422); } // PASSWORD BARU TIDAK BOLEH SAMA if (Hash::check($request->password, $petugas->password)) { return response()->json([ 'success' => false, 'message' => 'Password baru tidak boleh sama dengan password lama.' ], 400); } DB::table('petugas') ->where('id_petugas', $request->id_petugas) ->update([ 'password' => bcrypt($request->password), 'otp_code' => null, 'otp_expired_at' => null ]); return response()->json([ 'success' => true, 'message' => 'Password berhasil diperbarui.' ]); } }