PasswordRecoveryController.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace App\Controllers\Auth;
  3. use App\Controllers\Controller;
  4. use App\Web\Mail;
  5. use Psr\Http\Message\ResponseInterface as Response;
  6. use Psr\Http\Message\ServerRequestInterface as Request;
  7. use Slim\Exception\HttpNotFoundException;
  8. class PasswordRecoveryController extends Controller
  9. {
  10. /**
  11. * @param Request $request
  12. * @param Response $response
  13. * @return Response
  14. * @throws \Twig\Error\LoaderError
  15. * @throws \Twig\Error\RuntimeError
  16. * @throws \Twig\Error\SyntaxError
  17. */
  18. public function recover(Request $request, Response $response): Response
  19. {
  20. return view()->render($response, 'auth/recover_mail.twig');
  21. }
  22. /**
  23. * @param Request $request
  24. * @param Response $response
  25. * @return Response
  26. * @throws \Exception
  27. */
  28. public function recoverMail(Request $request, Response $response): Response
  29. {
  30. if ($this->session->get('logged', false)) {
  31. return redirect($response, route('home'));
  32. }
  33. $user = $this->database->query('SELECT `id`, `username` FROM `users` WHERE `email` = ? LIMIT 1', param($request, 'email'))->fetch();
  34. if (!isset($user->id)) {
  35. $this->session->alert(lang('recover_email_sent'), 'success');
  36. return redirect($response, route('recover'));
  37. }
  38. $resetToken = bin2hex(random_bytes(16));
  39. $this->database->query('UPDATE `users` SET `reset_token`=? WHERE `id` = ?', [
  40. $resetToken,
  41. $user->id,
  42. ]);
  43. Mail::make()
  44. ->from('no-reply@'.str_ireplace('www.', '', parse_url($this->config['base_url'], PHP_URL_HOST)), $this->config['app_name'])
  45. ->to(param($request, 'email'))
  46. ->subject(lang('mail.recover_password', [$this->config['app_name']]))
  47. ->message(lang('mail.recover_text', [
  48. $user->username,
  49. route('recover.password', ['resetToken' => $resetToken]),
  50. ]))
  51. ->send();
  52. $this->session->alert(lang('recover_email_sent'), 'success');
  53. return redirect($response, route('recover'));
  54. }
  55. /**
  56. * @param Request $request
  57. * @param Response $response
  58. * @param string $resetToken
  59. * @return Response
  60. * @throws \Twig\Error\LoaderError
  61. * @throws \Twig\Error\RuntimeError
  62. * @throws \Twig\Error\SyntaxError
  63. * @throws HttpNotFoundException
  64. */
  65. public function recoverPasswordForm(Request $request, Response $response, string $resetToken): Response
  66. {
  67. $user = $this->database->query('SELECT `id` FROM `users` WHERE `reset_token` = ? LIMIT 1', $resetToken)->fetch();
  68. if (!$user) {
  69. throw new HttpNotFoundException($request);
  70. }
  71. return view()->render($response, 'auth/recover_password.twig', [
  72. 'reset_token' => $resetToken
  73. ]);
  74. }
  75. /**
  76. * @param Request $request
  77. * @param Response $response
  78. * @param string $resetToken
  79. * @return Response
  80. * @throws HttpNotFoundException
  81. */
  82. public function recoverPassword(Request $request, Response $response, string $resetToken): Response
  83. {
  84. $user = $this->database->query('SELECT `id` FROM `users` WHERE `reset_token` = ? LIMIT 1', $resetToken)->fetch();
  85. if (!$user) {
  86. throw new HttpNotFoundException($request);
  87. }
  88. if (param($request, 'password') === null) {
  89. $this->session->alert(lang('password_required'), 'danger');
  90. return redirect($response, route('recover.password', ['resetToken' => $resetToken]));
  91. }
  92. if (param($request, 'password') !== param($request, 'password_repeat')) {
  93. $this->session->alert(lang('password_match'), 'danger');
  94. return redirect($response, route('recover.password', ['resetToken' => $resetToken]));
  95. }
  96. $this->database->query('UPDATE `users` SET `password`=?, `reset_token`=? WHERE `id` = ?', [
  97. password_hash(param($request, 'password'), PASSWORD_DEFAULT),
  98. null,
  99. $user->id,
  100. ]);
  101. $this->session->alert(lang('password_restored'), 'success');
  102. return redirect($response, route('login.show'));
  103. }
  104. }