diff --git a/app/Console/Commands/ResetCardsCommand.php b/app/Console/Commands/ResetCardsCommand.php index d3c3db6..b8068e0 100644 --- a/app/Console/Commands/ResetCardsCommand.php +++ b/app/Console/Commands/ResetCardsCommand.php @@ -19,7 +19,15 @@ class ResetCardsCommand extends Command public function handle() { - $this->adminService->resetAllCards(); - $this->info('Successfully reset all cards for active members to 0!'); + try { + $this->adminService->resetAllCards(); + $this->info('Successfully reset all cards for active members to 0!'); + } catch (\Throwable $e) { + \Illuminate\Support\Facades\Log::error('Lỗi xảy ra khi chạy command reset thẻ hàng tháng (cards:reset): ' . $e->getMessage()); + $this->error('Reset cards failed: ' . $e->getMessage()); + return Command::FAILURE; + } + + return Command::SUCCESS; } } diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index 41605d8..caa1271 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -74,4 +74,26 @@ class AuthController extends Controller $this->authService->logout($request); return redirect('/login'); } + + public function forgotPassword(Request $request) + { + $validator = \Illuminate\Support\Facades\Validator::make($request->all(), [ + 'mail' => 'required|email|max:255', + ], [ + 'mail.required' => config('constants.MSG_FORGOT_PWD_EMAIL_REQUIRED'), + 'mail.email' => config('constants.MSG_FORGOT_PWD_EMAIL_INVALID'), + ]); + + if ($validator->fails()) { + return back()->withInput()->with('dialog_forgot_error', $validator->errors()->first()); + } + + $result = $this->authService->forgotPassword($request->input('mail')); + + if (!$result['success']) { + return back()->withInput()->with('dialog_forgot_error', $result['error_msg']); + } + + return back()->with('dialog_forgot_success', $result['message']); + } } diff --git a/app/Mail/ResetPasswordMail.php b/app/Mail/ResetPasswordMail.php new file mode 100644 index 0000000..30c4933 --- /dev/null +++ b/app/Mail/ResetPasswordMail.php @@ -0,0 +1,39 @@ +count(); + User::where('status', config('constants.STATUS_ACTIVE'))->update([ 'card' => 0, 'flag_send' => config('constants.FLAG_SEND_DISABLED'), ]); + + \Illuminate\Support\Facades\Log::info("Thực hiện reset thẻ hàng tháng thành công cho {$activeUserCount} tài khoản active."); } public function updateAddCard(int $id, array $data): void diff --git a/app/Services/Auth/AuthService.php b/app/Services/Auth/AuthService.php index b5d87d2..b1cfbe7 100644 --- a/app/Services/Auth/AuthService.php +++ b/app/Services/Auth/AuthService.php @@ -47,4 +47,36 @@ class AuthService implements AuthServiceInterface return route('user.dashboard'); } + + public function forgotPassword(string $email): array + { + $email = \Illuminate\Support\Str::lower(trim($email)); + $user = User::where('mail', $email)->first(); + + if (!$user) { + return ['success' => false, 'error_msg' => config('constants.MSG_FORGOT_PWD_EMAIL_NOT_FOUND')]; + } + + if ($user->status != config('constants.STATUS_ACTIVE')) { + return ['success' => false, 'error_msg' => config('constants.MSG_FORGOT_PWD_ACCOUNT_INACTIVE')]; + } + + // Generate random password (8 characters) + $newPassword = \Illuminate\Support\Str::random(8); + + // Update password with md5 and set first_login flag to 1 + $user->pass = md5($newPassword); + $user->first_login = config('constants.FIRST_LOGIN_TRUE'); + $user->save(); + + // Send Email + try { + \Illuminate\Support\Facades\Mail::to($user->mail)->send(new \App\Mail\ResetPasswordMail($user, $newPassword)); + } catch (\Exception $e) { + \Illuminate\Support\Facades\Log::error('Failed to send reset password email: ' . $e->getMessage()); + return ['success' => false, 'error_msg' => config('constants.MSG_FORGOT_PWD_MAIL_FAILED')]; + } + + return ['success' => true, 'message' => config('constants.MSG_FORGOT_PWD_SUCCESS')]; + } } \ No newline at end of file diff --git a/app/Services/Auth/Contracts/AuthServiceInterface.php b/app/Services/Auth/Contracts/AuthServiceInterface.php index b11b29a..e474c6e 100644 --- a/app/Services/Auth/Contracts/AuthServiceInterface.php +++ b/app/Services/Auth/Contracts/AuthServiceInterface.php @@ -12,4 +12,6 @@ interface AuthServiceInterface public function logout(Request $request): void; public function getRedirectRouteForUser(User $user): string; + + public function forgotPassword(string $email): array; } \ No newline at end of file diff --git a/config/constants.php b/config/constants.php index 989e45f..02c4aaa 100644 --- a/config/constants.php +++ b/config/constants.php @@ -38,4 +38,11 @@ return [ 'CHATOPS_API_URL' => env('CHATOPS_API_URL', 'http://10.1.12.160/aiapi/sent-message-user'), 'CHATOPS_API_TOKEN' => env('CHATOPS_API_TOKEN', 'ifOgk13pXIa6p2q6vvJB'), + + 'MSG_FORGOT_PWD_EMAIL_REQUIRED' => 'Vui lòng nhập địa chỉ email.', + 'MSG_FORGOT_PWD_EMAIL_INVALID' => 'Địa chỉ email không đúng định dạng.', + 'MSG_FORGOT_PWD_EMAIL_NOT_FOUND' => 'Email không tồn tại trong hệ thống. Vui lòng kiểm tra lại.', + 'MSG_FORGOT_PWD_ACCOUNT_INACTIVE' => 'Tài khoản của bạn đã bị khóa hoặc ngừng hoạt động. Vui lòng liên hệ quản trị viên.', + 'MSG_FORGOT_PWD_MAIL_FAILED' => 'Không thể gửi email lúc này. Vui lòng thử lại sau.', + 'MSG_FORGOT_PWD_SUCCESS' => 'Mật khẩu mới đã được gửi tới email của bạn. Vui lòng kiểm tra hòm thư!', ]; diff --git a/config/mail.php b/config/mail.php index e32e88d..0a6e89d 100644 --- a/config/mail.php +++ b/config/mail.php @@ -112,7 +112,7 @@ return [ 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), - 'name' => env('MAIL_FROM_NAME', env('APP_NAME', 'Laravel')), + 'name' => env('MAIL_FROM_NAME', 'Thanks Card'), ], ]; diff --git a/resources/views/emails/reset_password.blade.php b/resources/views/emails/reset_password.blade.php new file mode 100644 index 0000000..569292f --- /dev/null +++ b/resources/views/emails/reset_password.blade.php @@ -0,0 +1,107 @@ + + +
+ + +| + + + | +