This is a one-time login for %user_name.
Click on this button to log in to the site and change your password.
', array('%user_name' => $user->getUsername()))); + } + else { + $form['message'] = array('#markup' => $this->t('This is a one-time login for %user_name and will expire on %expiration_date.
Click on this button to log in to the site and change your password.
', array('%user_name' => $user->getUsername(), '%expiration_date' => $this->date->format($timestamp + $timeout)))); + } + $form['#title'] = 'Reset Password'; + $form['uid'] = array( + '#type' => 'value', + '#value' => $uid, + ); + $form['timestamp'] = array( + '#type' => 'value', + '#value' => $timestamp, + ); + $form['hash'] = array( + '#type' => 'value', + '#value' => $hash, + ); + $form['operation'] = array( + '#type' => 'value', + '#value' => $operation, + ); + $form['help'] = array('#markup' => '' . $this->t('This login can be used only once.') . '
'); + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Log in')); + $form['#action'] = $this->url('user.reset', array('uid' => $uid, 'timestamp' => $timestamp, 'hash' => $hash, 'operation' => 'login')); + return $form; + } + else { + drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); + return new RedirectResponse($this->url('user.pass')); + } + } + else { + // Deny access, no more clues. + // Everything will be in the watchdog's URL for the administrator to check. + throw new AccessDeniedHttpException(); + } + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $uid = $form_state['values']['uid']; + $timestamp = $form_state['values']['timestamp']; + $hash = $form_state['values']['hash']; + $config = $this->configFactory->get('user.settings'); + // Time out, in seconds, until login URL expires. + $timeout = $config->get('password_reset_timeout'); + $current = REQUEST_TIME; + $user = $this->userStorageController->load($uid); + // Verify that the user exists and is active. + if ($user->isActive()) { + // No time out for first time login. + if ($user->getLastLoginTime() && $current - $timestamp > $timeout) { + drupal_set_message($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.')); + $form_state['redirect_route']['route_name'] = 'user.pass'; + } + elseif ($user->isAuthenticated() && $timestamp >= $user->getLastLoginTime() && $timestamp <= $current && $hash == user_pass_rehash($user->getPassword(), $timestamp, $user->getLastLoginTime())) { + user_login_finalize($user); + watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $user->getUsername(), '%timestamp' => $timestamp)); + drupal_set_message($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.')); + // Let the user's password be changed without the current password check. + $token = Crypt::randomStringHashed(55); + $_SESSION['pass_reset_' . $user->id()] = $token; + $form_state['redirect_route']['route_name'] = 'user.edit'; + $form_state['redirect_route']['route_parameters'] = array('user' => $user->id()); + $form_state['redirect_route']['options'] = array( + 'query' => array('pass-reset-token' => $token), + 'absolute' => TRUE, + ); + } + else { + drupal_set_message($this->t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); + $form_state['redirect_route']['route_name'] = 'user.pass'; + } + } + else { + // Deny access, no more clues. + // Everything will be in the watchdog's URL for the administrator to check. + throw new AccessDeniedHttpException(); + } + } + +} diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc index 2977253..f1df715 100644 --- a/core/modules/user/user.pages.inc +++ b/core/modules/user/user.pages.inc @@ -5,96 +5,8 @@ * User page callback file for the user module. */ -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Drupal\Component\Utility\Crypt; - -/** - * Menu callback; process one time login link and redirects to the user page on success. - * - * @deprecated Use \Drupal\user\Form\UserForm::resetPass() - */ -function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) { - global $user; - - // When processing the one-time login link, we have to make sure that a user - // isn't already logged in. - if ($user->isAuthenticated()) { - // The existing user is already logged in. - if ($user->id() == $uid) { - drupal_set_message(t('You are logged in as %user. Change your password.', array('%user' => $user->getUsername(), '!user_edit' => url("user/" . $user->id() . "/edit")))); - } - // A different user is already logged in on the computer. - else { - $reset_link_account = user_load($uid); - if (!empty($reset_link_account)) { - drupal_set_message(t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please logout and try using the link again.', - array('%other_user' => $user->getUsername(), '%resetting_user' => $reset_link_account->getUsername(), '!logout' => url('user/logout')))); - } else { - // Invalid one-time link specifies an unknown user. - drupal_set_message(t('The one-time login link you clicked is invalid.')); - } - } - return new RedirectResponse(url('This is a one-time login for %user_name.
Click on this button to log in to the site and change your password.
', array('%user_name' => $account->getUsername()))); - } - else { - $form['message'] = array('#markup' => t('This is a one-time login for %user_name and will expire on %expiration_date.
Click on this button to log in to the site and change your password.
', array('%user_name' => $account->getUsername(), '%expiration_date' => format_date($timestamp + $timeout)))); - } - $form['help'] = array('#markup' => '' . t('This login can be used only once.') . '
'); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in')); - $form['#action'] = url("user/reset/$uid/$timestamp/$hashed_pass/login"); - return $form; - } - } - else { - drupal_set_message(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); - return new RedirectResponse(url('user/password', array('absolute' => TRUE))); - } - } - else { - // Deny access, no more clues. - // Everything will be in the watchdog's URL for the administrator to check. - throw new AccessDeniedHttpException(); - } - } -} /** * Prepares variables for user templates. diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index bbc2053..5f2430e 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -175,7 +175,7 @@ user.cancel_confirm: user.reset: path: '/user/reset/{uid}/{timestamp}/{hash}/{operation}' defaults: - _content: '\Drupal\user\Form\UserForm::resetPass' + _form: '\Drupal\user\Form\UserPasswordResetForm' _title: 'Reset password' operation: NULL requirements: