diff --git a/core/modules/user/src/Controller/UserController.php b/core/modules/user/src/Controller/UserController.php
index 74d59da..183650b 100644
--- a/core/modules/user/src/Controller/UserController.php
+++ b/core/modules/user/src/Controller/UserController.php
@@ -99,7 +99,7 @@ public function resetPass($uid, $timestamp, $hash) {
/**
* Redirects to the user password reset form.
*
- * In order to never disclose a redirect link via a referrer header this
+ * In order to never disclose a reset link via a referrer header this
* controller must always return a redirect response.
*
* @param \Symfony\Component\HttpFoundation\Request $request
@@ -113,18 +113,8 @@ public function resetPass($uid, $timestamp, $hash) {
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* The redirect response.
- *
- * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
- * If the login link is for a blocked user or invalid user ID.
*/
public function resetPassRedirect(Request $request, $uid, $timestamp, $hash) {
- $reset_link_user = $this->userStorage->load($uid);
- if ($reset_link_user === NULL || !$reset_link_user->isActive()) {
- // Blocked or invalid user ID, so deny access. The parameters will be in the
- // watchdog's URL for the administrator to check.
- throw new AccessDeniedHttpException();
- }
-
$account = $this->currentUser();
// When processing the one-time login link, we have to make sure that a user
// isn't already logged in.
@@ -145,9 +135,17 @@ public function resetPassRedirect(Request $request, $uid, $timestamp, $hash) {
}
// A different user is already logged in on the computer.
else {
- drupal_set_message($this->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 log out and try using the link again.',
- array('%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout'))), 'warning');
-
+ /** @var \Drupal\user\UserInterface $reset_link_user */
+ if ($reset_link_user = $this->userStorage->load($uid)) {
+ drupal_set_message($this->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 log out and try using the link again.',
+ ['%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout')]
+ ), 'warning');
+ }
+ else {
+ // Invalid one-time link specifies an unknown user.
+ drupal_set_message($this->t('The one-time login link you clicked is invalid.'), 'error');
+ }
return $this->redirect('');
}
}
@@ -185,11 +183,15 @@ public function getResetPassForm($uid, Request $request) {
// the user does not click on the log in button on the form.
$session->remove('pass_reset_timeout');
$session->remove('pass_reset_hash');
+ if (!$hash || !$timestamp) {
+ throw new AccessDeniedHttpException();
+ }
/** @var \Drupal\user\UserInterface $user */
$user = $this->userStorage->load($uid);
-
- if (!$hash || !$timestamp || $user === NULL || !$user->isActive()) {
+ if ($user === NULL || !$user->isActive()) {
+ // Blocked or invalid user ID, so deny access. The parameters will be in
+ // the watchdog's URL for the administrator to check.
throw new AccessDeniedHttpException();
}
diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php
index 979be75..a26790d 100644
--- a/core/modules/user/src/Tests/UserPasswordResetTest.php
+++ b/core/modules/user/src/Tests/UserPasswordResetTest.php
@@ -2,6 +2,7 @@
namespace Drupal\user\Tests;
+use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Url;
use Drupal\system\Tests\Cache\PageCacheTagsTestBase;
use Drupal\user\Entity\User;
@@ -217,6 +218,25 @@ public function getResetURL() {
* Test user password reset while logged in.
*/
public function testUserPasswordResetLoggedIn() {
+ $another_account = $this->drupalCreateUser();
+ $this->drupalLogin($another_account);
+ $this->drupalGet('user/password');
+ $this->drupalPostForm(NULL, NULL, t('Submit'));
+
+ // Click the reset URL while logged and change our password.
+ $resetURL = $this->getResetURL();
+ // Log in as a different user.
+ $this->drupalLogin($this->account);
+ $this->drupalGet($resetURL);
+ $this->assertRaw(new FormattableMarkup(
+ '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 log out and try using the link again.',
+ ['%other_user' => $this->account->getUsername(), '%resetting_user' => $another_account->getUsername(), ':logout' => Url::fromRoute('user.logout')->toString()]
+ ));
+
+ $another_account->delete();
+ $this->drupalGet($resetURL);
+ $this->assertText('The one-time login link you clicked is invalid.');
+
// Log in.
$this->drupalLogin($this->account);
@@ -234,6 +254,8 @@ public function testUserPasswordResetLoggedIn() {
$edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password);
$this->drupalPostForm(NULL, $edit, t('Save'));
$this->assertText(t('The changes have been saved.'), 'Password changed.');
+
+ $this->drupalLogin($this->drupalCreateUser());
}
/**