From eb7a40a70d4844070fd57cac4e2eea14d619a7bd Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Tue, 5 Nov 2024 17:17:14 +0100 Subject: [PATCH] ResetPassword: introduce requestResetKey and verifyResetKey methods --- controllers/ResetPassword.php | 118 ++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/controllers/ResetPassword.php b/controllers/ResetPassword.php index 2a6f500..dc4c806 100644 --- a/controllers/ResetPassword.php +++ b/controllers/ResetPassword.php @@ -16,66 +16,72 @@ class ResetPassword extends HTMLController // Verifying an existing reset key? if (isset($_GET['step'], $_GET['email'], $_GET['key']) && $_GET['step'] == 2) - { - $email = rawurldecode($_GET['email']); - $user = Member::fromEmailAddress($email); - if (!$user) - throw new UserFacingException('Invalid email address. Please make sure you copied the full link in the email you received.'); - - $key = $_GET['key']; - if (!Authentication::checkResetKey($user->getUserId(), $key)) - throw new UserFacingException('Invalid reset token. Please make sure you copied the full link in the email you received. Note: you cannot use the same token twice.'); - - parent::__construct('Reset password - ' . SITE_TITLE); - $form = new PasswordResetForm($email, $key); - $this->page->adopt($form); - - // Are they trying to set something already? - if (isset($_POST['password1'], $_POST['password2'])) - { - $missing = []; - if (strlen($_POST['password1']) < 6 || !preg_match('~[^A-z]~', $_POST['password1'])) - $missing[] = 'Please fill in a password that is at least six characters long and contains at least one non-alphabetic character (e.g. a number or symbol).'; - if ($_POST['password1'] != $_POST['password2']) - $missing[] = 'The passwords you entered do not match.'; - - // So, are we good to go? - if (empty($missing)) - { - Authentication::updatePassword($user->getUserId(), Authentication::computeHash($_POST['password1'])); - $_SESSION['login_msg'] = ['Your password has been reset', 'You can now use the form below to log in to your account.', 'success']; - header('Location: ' . BASEURL . '/login/'); - exit; - } - else - $form->adopt(new Alert('Some fields require your attention', '', 'danger')); - } - } + $this->verifyResetKey(); else + $this->requestResetKey(); + } + + private function requestResetKey() + { + parent::__construct('Reset password - ' . SITE_TITLE); + $form = new ForgotPasswordForm(); + $this->page->adopt($form); + + // Have they submitted an email address yet? + if (isset($_POST['emailaddress']) && preg_match('~^.+@.+\.[a-z]+$~', trim($_POST['emailaddress']))) { - parent::__construct('Reset password - ' . SITE_TITLE); - $form = new ForgotPasswordForm(); - $this->page->adopt($form); - - // Have they submitted an email address yet? - if (isset($_POST['emailaddress']) && preg_match('~^.+@.+\.[a-z]+$~', trim($_POST['emailaddress']))) + $user = Member::fromEmailAddress($_POST['emailaddress']); + if (!$user) { - $user = Member::fromEmailAddress($_POST['emailaddress']); - if (!$user) - { - $form->adopt(new Alert('Invalid email address', 'The email address you provided could not be found in our system. Please try again.', 'danger')); - return; - } - - Authentication::setResetKey($user->getUserId()); - Email::resetMail($user->getUserId()); - - // Show the success message - $this->page->clear(); - $box = new DummyBox('An email has been sent'); - $box->adopt(new Alert('', 'We have sent an email to ' . $_POST['emailaddress'] . ' containing details on how to reset your password.', 'success')); - $this->page->adopt($box); + $form->adopt(new Alert('Invalid email address', 'The email address you provided could not be found in our system. Please try again.', 'danger')); + return; } + + Authentication::setResetKey($user->getUserId()); + Email::resetMail($user->getUserId()); + + // Show the success message + $this->page->clear(); + $box = new DummyBox('An email has been sent'); + $box->adopt(new Alert('', 'We have sent an email to ' . $_POST['emailaddress'] . ' containing details on how to reset your password.', 'success')); + $this->page->adopt($box); + } + } + + private function verifyResetKey() + { + $email = rawurldecode($_GET['email']); + $user = Member::fromEmailAddress($email); + if (!$user) + throw new UserFacingException('Invalid email address. Please make sure you copied the full link in the email you received.'); + + $key = $_GET['key']; + if (!Authentication::checkResetKey($user->getUserId(), $key)) + throw new UserFacingException('Invalid reset token. Please make sure you copied the full link in the email you received. Note: you cannot use the same token twice.'); + + parent::__construct('Reset password - ' . SITE_TITLE); + $form = new PasswordResetForm($email, $key); + $this->page->adopt($form); + + // Are they trying to set something already? + if (isset($_POST['password1'], $_POST['password2'])) + { + $missing = []; + if (strlen($_POST['password1']) < 6 || !preg_match('~[^A-z]~', $_POST['password1'])) + $missing[] = 'Please fill in a password that is at least six characters long and contains at least one non-alphabetic character (e.g. a number or symbol).'; + if ($_POST['password1'] != $_POST['password2']) + $missing[] = 'The passwords you entered do not match.'; + + // So, are we good to go? + if (empty($missing)) + { + Authentication::updatePassword($user->getUserId(), Authentication::computeHash($_POST['password1'])); + $_SESSION['login_msg'] = ['Your password has been reset', 'You can now use the form below to log in to your account.', 'success']; + header('Location: ' . BASEURL . '/login/'); + exit; + } + else + $form->adopt(new Alert('Some fields require your attention', '', 'danger')); } } }