Loading core/modules/user/src/AccountForm.php +1 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public function form(array $form, FormStateInterface $form_state) { // To skip the current password field, the user must have logged in via a // 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') && ($token = $this->getRequest()->get('pass-reset-token'))) { if (!$form_state->get('user_pass_reset') && ($token = $this->getRequest()->query->get('pass-reset-token'))) { $session_key = 'pass_reset_' . $account->id(); $user_pass_reset = isset($_SESSION[$session_key]) && hash_equals($_SESSION[$session_key], $token); $form_state->set('user_pass_reset', $user_pass_reset); Loading core/modules/user/tests/src/Kernel/UserAccountFormPasswordResetTest.php 0 → 100644 +94 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\user\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\user\Entity\User; /** * Verifies that the password reset behaves as expected with form elements. * * @group user */ class UserAccountFormPasswordResetTest extends KernelTestBase { /** * Modules to enable. * * @var array */ protected static $modules = ['system', 'user']; /** * User object. * * @var \Drupal\user\UserInterface */ protected $user; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); // Install default configuration; required for AccountFormController. $this->installConfig(['user']); $this->installSchema('system', ['sequences']); $this->installEntitySchema('user'); // Create an user to login. $this->user = User::create(['name' => 'test']); $this->user->save(); // Set current user. $this->container->set('current_user', $this->user); // Install the router table and then rebuild. \Drupal::service('router.builder')->rebuild(); } /** * Tests the reset token used only from query string. */ public function testPasswordResetToken() { $token = 'VALID_TOKEN'; $_SESSION['pass_reset_1'] = $token; /** @var \Symfony\Component\HttpFoundation\Request $request */ $request = $this->container->get('request_stack')->getCurrentRequest(); // Set token in query string. $request->query->set('pass-reset-token', $token); $form = $this->buildAccountForm('default'); // User shouldn't see current password field. $this->assertFalse($form['account']['current_pass']['#access']); $request->query->set('pass-reset-token', NULL); $request->attributes->set('pass-reset-token', $token); $form = $this->buildAccountForm('default'); $this->assertTrue($form['account']['current_pass']['#access']); } /** * Builds the user account form for a given operation. * * @param string $operation * The entity operation; one of 'register' or 'default'. * * @return array * The form array. */ protected function buildAccountForm($operation) { // @see HtmlEntityFormController::getFormObject() $entity_type = 'user'; $fields = []; if ($operation != 'register') { $fields['uid'] = $this->user->id(); } $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->create($fields); // @see EntityFormBuilder::getForm() return $this->container->get('entity.form_builder')->getForm($entity, $operation); } } Loading
core/modules/user/src/AccountForm.php +1 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public function form(array $form, FormStateInterface $form_state) { // To skip the current password field, the user must have logged in via a // 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') && ($token = $this->getRequest()->get('pass-reset-token'))) { if (!$form_state->get('user_pass_reset') && ($token = $this->getRequest()->query->get('pass-reset-token'))) { $session_key = 'pass_reset_' . $account->id(); $user_pass_reset = isset($_SESSION[$session_key]) && hash_equals($_SESSION[$session_key], $token); $form_state->set('user_pass_reset', $user_pass_reset); Loading
core/modules/user/tests/src/Kernel/UserAccountFormPasswordResetTest.php 0 → 100644 +94 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\user\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\user\Entity\User; /** * Verifies that the password reset behaves as expected with form elements. * * @group user */ class UserAccountFormPasswordResetTest extends KernelTestBase { /** * Modules to enable. * * @var array */ protected static $modules = ['system', 'user']; /** * User object. * * @var \Drupal\user\UserInterface */ protected $user; /** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); // Install default configuration; required for AccountFormController. $this->installConfig(['user']); $this->installSchema('system', ['sequences']); $this->installEntitySchema('user'); // Create an user to login. $this->user = User::create(['name' => 'test']); $this->user->save(); // Set current user. $this->container->set('current_user', $this->user); // Install the router table and then rebuild. \Drupal::service('router.builder')->rebuild(); } /** * Tests the reset token used only from query string. */ public function testPasswordResetToken() { $token = 'VALID_TOKEN'; $_SESSION['pass_reset_1'] = $token; /** @var \Symfony\Component\HttpFoundation\Request $request */ $request = $this->container->get('request_stack')->getCurrentRequest(); // Set token in query string. $request->query->set('pass-reset-token', $token); $form = $this->buildAccountForm('default'); // User shouldn't see current password field. $this->assertFalse($form['account']['current_pass']['#access']); $request->query->set('pass-reset-token', NULL); $request->attributes->set('pass-reset-token', $token); $form = $this->buildAccountForm('default'); $this->assertTrue($form['account']['current_pass']['#access']); } /** * Builds the user account form for a given operation. * * @param string $operation * The entity operation; one of 'register' or 'default'. * * @return array * The form array. */ protected function buildAccountForm($operation) { // @see HtmlEntityFormController::getFormObject() $entity_type = 'user'; $fields = []; if ($operation != 'register') { $fields['uid'] = $this->user->id(); } $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->create($fields); // @see EntityFormBuilder::getForm() return $this->container->get('entity.form_builder')->getForm($entity, $operation); } }