validate([ 'email' => 'required|email|exists:users,email', ], [ 'email.exists' => 'Email tidak ditemukan. Pastikan email sudah terdaftar.', ]); $otp = rand(100000, 999999); // Simpan OTP di cache selama 5 menit Cache::put('otp_' . $request->email, $otp, now()->addMinutes(5)); Cache::put('otp_email', $request->email, now()->addMinutes(5)); // Coba kirim email, kalau gagal tetap lanjut (untuk development) try { Mail::raw("Kode OTP kamu: $otp (berlaku 5 menit)", function ($message) use ($request) { $message->to($request->email)->subject('Kode OTP Reset Password'); }); } catch (\Exception $e) { // Log error tapi jangan crash — tampilkan OTP langsung untuk testing \Log::error('Mail gagal: ' . $e->getMessage()); } // Untuk keperluan development: flash OTP ke session agar bisa dilihat session()->flash('otp_debug', "OTP kamu: $otp"); return redirect()->route('password.otp.form'); } // STEP 2 — Tampilkan form OTP public function showOtpForm() { return view('auth.otp'); } // STEP 2 — Verifikasi OTP public function verifyOtp(Request $request) { $request->validate(['otp' => 'required|digits:6']); $email = Cache::get('otp_email'); $cachedOtp = Cache::get('otp_' . $email); if (!$cachedOtp || $request->otp != $cachedOtp) { return back()->withErrors(['otp' => 'OTP salah atau sudah kadaluarsa.']); } // Tandai OTP sudah diverifikasi Cache::put('otp_verified_' . $email, true, now()->addMinutes(10)); return redirect()->route('password.reset.form'); } // STEP 2 — Resend OTP public function resendOtp(Request $request) { $email = Cache::get('otp_email'); if (!$email) { return redirect()->route('password.email')->withErrors(['email' => 'Sesi habis, ulangi dari awal.']); } $otp = rand(100000, 999999); Cache::put('otp_' . $email, $otp, now()->addMinutes(5)); Mail::raw("Kode OTP kamu: $otp (berlaku 5 menit)", function ($message) use ($email) { $message->to($email)->subject('Kode OTP Reset Password'); }); return back()->with('status', 'OTP baru telah dikirim.'); } // STEP 3 — Tampilkan form reset password public function showResetForm() { $email = Cache::get('otp_email'); if (!$email || !Cache::get('otp_verified_' . $email)) { return redirect()->route('password.email')->withErrors(['email' => 'Verifikasi OTP terlebih dahulu.']); } return view('auth.reset-password'); } // STEP 3 — Proses reset password public function resetPassword(Request $request) { $request->validate([ 'password' => 'required|min:8|confirmed', ]); $email = Cache::get('otp_email'); if (!$email || !Cache::get('otp_verified_' . $email)) { return redirect()->route('password.email')->withErrors(['email' => 'Sesi tidak valid.']); } User::where('email', $email)->update([ 'password' => Hash::make($request->password), ]); // Hapus semua cache terkait Cache::forget('otp_' . $email); Cache::forget('otp_email'); Cache::forget('otp_verified_' . $email); return redirect()->route('login')->with('status', 'Password berhasil direset!'); } }