PasswordResetService.php 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <?php
  2. namespace App\Services;
  3. use App\Mail\PasswordResetCode;
  4. use App\Models\User;
  5. use App\Enums\UserTypeEnum;
  6. use Illuminate\Support\Facades\DB;
  7. use Illuminate\Support\Facades\Hash;
  8. use Illuminate\Support\Facades\Mail;
  9. use Carbon\Carbon;
  10. class PasswordResetService
  11. {
  12. private const CODE_TTL_MINUTES = 15;
  13. public function sendCode(string $email, string $tipo): bool
  14. {
  15. $user = User::where('email', $email)->first();
  16. if (!$user || $user->type->value !== $tipo) {
  17. return false;
  18. }
  19. $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
  20. DB::table('password_reset_tokens')->updateOrInsert(
  21. ['email' => $email],
  22. [
  23. 'token' => Hash::make($code),
  24. 'created_at' => Carbon::now(),
  25. ]
  26. );
  27. Mail::to($email)->send(new PasswordResetCode($code, $user->name));
  28. return true;
  29. }
  30. public function verifyCode(string $email, string $code): bool
  31. {
  32. $record = DB::table('password_reset_tokens')
  33. ->where('email', $email)
  34. ->first();
  35. if (!$record) {
  36. return false;
  37. }
  38. if (Carbon::parse($record->created_at)->addMinutes(self::CODE_TTL_MINUTES)->isPast()) {
  39. return false;
  40. }
  41. return Hash::check($code, $record->token);
  42. }
  43. public function resetPassword(string $email, string $code, string $password): bool
  44. {
  45. if (!$this->verifyCode($email, $code)) {
  46. return false;
  47. }
  48. User::where('email', $email)->update([
  49. 'password' => Hash::make($password),
  50. ]);
  51. DB::table('password_reset_tokens')->where('email', $email)->delete();
  52. return true;
  53. }
  54. }