diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php index 7cf5ad6e2e8..7ed3cbde07a 100644 --- a/core/modules/user/src/AccountForm.php +++ b/core/modules/user/src/AccountForm.php @@ -123,15 +123,19 @@ abstract class AccountForm extends ContentEntityForm { ); // To skip the current password field, the user must have logged in via a - // one-time link and have the token in the URL. - $pass_reset = isset($_SESSION['pass_reset_' . $account->id()]) && (\Drupal::request()->query->get('pass-reset-token') == $_SESSION['pass_reset_' . $account->id()]); + // one-time link and have the token in the URL. Store this in $form_state + // so it persists even on subsequent Ajax requests. + if (!$form_state->get('user_pass_reset')) { + $user_pass_reset = $pass_reset = isset($_SESSION['pass_reset_' . $account->id()]) && (\Drupal::request()->query->get('pass-reset-token') == $_SESSION['pass_reset_' . $account->id()]); + $form_state->set('user_pass_reset', $user_pass_reset); + } $protected_values = array(); $current_pass_description = ''; // The user may only change their own password without their current // password if they logged in via a one-time login link. - if (!$pass_reset) { + if (!$form_state->get('user_pass_reset')) { $protected_values['mail'] = $form['account']['mail']['#title']; $protected_values['pass'] = $this->t('Password'); $request_new = $this->l($this->t('Reset your password'), new Url('user.pass', diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php index c8a1f4be1dd..3d8958188f7 100644 --- a/core/modules/user/src/Tests/UserPasswordResetTest.php +++ b/core/modules/user/src/Tests/UserPasswordResetTest.php @@ -15,6 +15,18 @@ use Drupal\simpletest\WebTestBase; * @group user */ class UserPasswordResetTest extends WebTestBase { + + /** + * The profile to install as a basis for testing. + * + * This test uses the standard profile to test the password reset in + * combination with an ajax request provided by the user picture configuration + * in the standard profile. + * + * @var string + */ + protected $profile = 'standard'; + /** * The user object to test password resetting. * @@ -89,6 +101,14 @@ class UserPasswordResetTest extends WebTestBase { $this->assertLink(t('Log out')); $this->assertTitle(t('@name | @site', array('@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name'))), 'Logged in using password reset link.'); + // Make sure the ajax request from uploading a user picture does not + // invalidate the reset token. + $image = current($this->drupalGetTestFiles('image')); + $edit = array( + 'files[user_picture_0]' => drupal_realpath($image->uri), + ); + $this->drupalPostAjaxForm(NULL, $edit, 'user_picture_0_upload_button'); + // Change the forgotten password. $password = user_password(); $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password);