205 lines
7.1 KiB
PHP
205 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Auth;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use App\Models\User;
|
|
use App\Models\PasswordOtp;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\Hash;
|
|
|
|
class OtpPasswordController extends Controller
|
|
{
|
|
/**
|
|
* Tampilkan form request OTP
|
|
*/
|
|
public function showRequestForm()
|
|
{
|
|
return view('auth.forgot-password-otp');
|
|
}
|
|
|
|
/**
|
|
* Kirim OTP ke email
|
|
*/
|
|
public function sendOtp(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email|exists:users,email',
|
|
], [
|
|
'email.exists' => 'Email tidak terdaftar dalam sistem.'
|
|
]);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
|
|
// Generate OTP 6 digit
|
|
$otp = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
|
|
|
|
// Simpan OTP ke database (expired 5 menit)
|
|
PasswordOtp::updateOrCreate(
|
|
['email' => $request->email],
|
|
[
|
|
'otp' => $otp,
|
|
'expires_at' => Carbon::now()->addMinutes(5),
|
|
]
|
|
);
|
|
|
|
// Kirim email OTP
|
|
try {
|
|
$this->sendOtpEmail($user->email, $user->name, $otp);
|
|
|
|
return redirect()->route('password.otp.verify.form', ['email' => $request->email])
|
|
->with('success', 'Kode OTP telah dikirim ke email Anda. Cek inbox/spam folder.');
|
|
} catch (\Exception $e) {
|
|
// Log error
|
|
\Log::error('OTP Email error: ' . $e->getMessage());
|
|
|
|
// Untuk development, tampilkan OTP di session
|
|
if (app()->environment('local')) {
|
|
return redirect()->route('password.otp.verify.form', ['email' => $request->email])
|
|
->with('dev_otp', $otp)
|
|
->with('success', '🔧 Mode Development - Kode OTP Anda:');
|
|
}
|
|
|
|
return back()->with('error', 'Gagal mengirim email. Silakan coba lagi.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tampilkan form verifikasi OTP
|
|
*/
|
|
public function showVerifyForm(Request $request)
|
|
{
|
|
return view('auth.verify-otp', ['email' => $request->email]);
|
|
}
|
|
|
|
/**
|
|
* Verifikasi OTP
|
|
*/
|
|
public function verifyOtp(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
'otp' => 'required|string|size:6',
|
|
]);
|
|
|
|
$otpRecord = PasswordOtp::where('email', $request->email)
|
|
->where('otp', $request->otp)
|
|
->first();
|
|
|
|
if (!$otpRecord) {
|
|
return back()->with('error', 'Kode OTP tidak valid.');
|
|
}
|
|
|
|
// Cek apakah OTP sudah expired
|
|
if (Carbon::now()->gt($otpRecord->expires_at)) {
|
|
$otpRecord->delete();
|
|
return back()->with('error', 'Kode OTP sudah kadaluarsa. Silakan minta kode baru.');
|
|
}
|
|
|
|
// OTP valid, arahkan ke form reset password
|
|
return redirect()->route('password.otp.reset.form', [
|
|
'email' => $request->email,
|
|
'otp' => $request->otp
|
|
])->with('success', 'Kode valid. Silakan buat password baru.');
|
|
}
|
|
|
|
/**
|
|
* Tampilkan form reset password
|
|
*/
|
|
public function showResetForm(Request $request)
|
|
{
|
|
return view('auth.reset-password-otp', [
|
|
'email' => $request->email,
|
|
'otp' => $request->otp
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Reset password dengan OTP
|
|
*/
|
|
public function resetPassword(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
'otp' => 'required|string|size:6',
|
|
'password' => 'required|string|min:8|confirmed',
|
|
]);
|
|
|
|
// Verifikasi OTP sekali lagi
|
|
$otpRecord = PasswordOtp::where('email', $request->email)
|
|
->where('otp', $request->otp)
|
|
->first();
|
|
|
|
if (!$otpRecord || Carbon::now()->gt($otpRecord->expires_at)) {
|
|
return back()->with('error', 'Kode OTP tidak valid atau sudah kadaluarsa.');
|
|
}
|
|
|
|
// Update password user
|
|
$user = User::where('email', $request->email)->first();
|
|
$user->password = Hash::make($request->password);
|
|
$user->save();
|
|
|
|
// Hapus data OTP
|
|
$otpRecord->delete();
|
|
|
|
return redirect()->route('login')
|
|
->with('success', 'Password berhasil direset. Silakan login dengan password baru.');
|
|
}
|
|
|
|
/**
|
|
* Kirim email OTP
|
|
*/
|
|
private function sendOtpEmail($toEmail, $toName, $otp)
|
|
{
|
|
$subject = "Kode OTP Reset Password - LearnMood";
|
|
|
|
$message = "
|
|
<html>
|
|
<head>
|
|
<title>Kode OTP Reset Password</title>
|
|
</head>
|
|
<body style='font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;'>
|
|
<div style='max-width: 500px; margin: 0 auto; background-color: white; border-radius: 10px; padding: 30px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);'>
|
|
<div style='text-align: center; margin-bottom: 25px;'>
|
|
<h1 style='color: #4A90E2; margin: 0;'>Learn<span style='color: #333;'>Mood</span></h1>
|
|
</div>
|
|
|
|
<p style='font-size: 16px; color: #333;'>Halo <strong>{$toName}</strong>,</p>
|
|
|
|
<p style='font-size: 14px; color: #666;'>Kami menerima permintaan reset password untuk akun Anda. Gunakan kode OTP berikut untuk melanjutkan:</p>
|
|
|
|
<div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; text-align: center; border-radius: 8px; margin: 25px 0;'>
|
|
<p style='margin: 0; font-size: 14px; color: rgba(255,255,255,0.9);'>Kode Verifikasi OTP</p>
|
|
<h1 style='font-size: 48px; letter-spacing: 8px; color: white; margin: 10px 0; font-family: monospace;'>{$otp}</h1>
|
|
</div>
|
|
|
|
<div style='background-color: #f8f9fa; padding: 15px; border-radius: 8px; margin: 20px 0;'>
|
|
<p style='margin: 0; font-size: 13px; color: #666;'>
|
|
<strong>⏰ Berlaku selama:</strong> 5 menit<br>
|
|
<strong>📧 Email:</strong> {$toEmail}
|
|
</p>
|
|
</div>
|
|
|
|
<p style='font-size: 13px; color: #999; border-top: 1px solid #eee; padding-top: 20px; margin-top: 20px;'>
|
|
Jika Anda tidak meminta reset password, abaikan email ini.
|
|
</p>
|
|
|
|
<p style='font-size: 12px; color: #999; text-align: center; margin-top: 20px;'>
|
|
© " . date('Y') . " LearnMood. All rights reserved.
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
";
|
|
|
|
$headers = "MIME-Version: 1.0" . "\r\n";
|
|
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
|
|
$headers .= 'From: LearnMood <' . env('MAIL_FROM_ADDRESS') . '>' . "\r\n";
|
|
$headers .= 'Reply-To: ' . env('MAIL_FROM_ADDRESS') . "\r\n";
|
|
$headers .= 'X-Mailer: PHP/' . phpversion();
|
|
|
|
mail($toEmail, $subject, $message, $headers);
|
|
}
|
|
} |