diff --git a/core/modules/user/config/install/user.settings.yml b/core/modules/user/config/install/user.settings.yml
index ca46109..677add0 100644
--- a/core/modules/user/config/install/user.settings.yml
+++ b/core/modules/user/config/install/user.settings.yml
@@ -14,6 +14,5 @@ notify:
register: visitors
cancel_method: user_cancel_block
password_reset_timeout: 86400
-mail_change_timeout: 86400
password_strength: true
langcode: en
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 206a853..40a8475 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -53,9 +53,6 @@ user.settings:
password_reset_timeout:
type: integer
label: 'Password reset timeout'
- mail_change_timeout:
- type: integer
- label: 'Mail change timeout'
password_strength:
type: boolean
label: 'Enable password strength indicator'
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 9bbf9fb..9fdd4ce 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -396,7 +396,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
_user_mail_notify('mail_change_notification', $account);
// The user's mail address will be updated only after verification.
$form_state->setValue('mail', $old_mail);
- drupal_set_message($this->t('Your new email address needs to be validated. Further instructions have been sent to your new email address.'), 'warning');
+ drupal_set_message($this->t('Your updated email address needs to be validated. Further instructions have been sent to your new email address.'), 'warning');
}
}
diff --git a/core/modules/user/src/Controller/MailChangeController.php b/core/modules/user/src/Controller/MailChangeController.php
index 487c70d..14649e3 100644
--- a/core/modules/user/src/Controller/MailChangeController.php
+++ b/core/modules/user/src/Controller/MailChangeController.php
@@ -5,6 +5,7 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
@@ -29,27 +30,28 @@ class MailChangeController extends ControllerBase {
* An HTTP response doing a redirect.
*/
public function page(UserInterface $user, $new_mail, $timestamp, $hash) {
- $timeout = $this->config('user.settings')->get('mail_change_timeout');
+ $timeout = Settings::get('mail_change_timeout', 86400);
/** @var \Drupal\Core\Session\AccountProxyInterface $current_user */
$current_user = $this->currentUser();
+ $request_time = \Drupal::time()->getRequestTime();
// Other user is authenticated.
if ($current_user->isAuthenticated() && $current_user->id() != $user->id()) {
drupal_set_message($this->t('You are currently logged in as %user, and are attempting to confirm an email address change for another account. Please log out and try using the link again.', ['%user' => $current_user->getAccountName(), ':logout' => Url::fromRoute('user.logout')->toString()]), 'error');
}
// The link has expired.
- elseif (REQUEST_TIME - $timestamp > $timeout) {
+ elseif ($request_time - $timestamp > $timeout) {
drupal_set_message($this->t('You have tried to use an email address change link that has expired. Please visit your account and change your email again.'), 'error');
}
// The link is valid.
- elseif ($timestamp <= REQUEST_TIME && $timestamp >= $user->getLastLoginTime() && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp, $new_mail))) {
+ elseif ($timestamp <= $request_time && $timestamp >= $user->getLastLoginTime() && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp, $new_mail))) {
// Save the new email but refresh also the last login time so that this
- // mail change link get expired.
- $user->setEmail($new_mail)->setLastLoginTime(REQUEST_TIME)->save();
+ // mail change link gets expired.
+ $user->setEmail($new_mail)->setLastLoginTime($request_time)->save();
/** @var \Drupal\user\UserStorageInterface $user_storage */
$user_storage = $this->entityTypeManager()->getStorage('user');
$user_storage->updateLastLoginTimestamp($user);
- // Reflect the changes in the session if the user is user is logged in.
+ // Reflect the changes in the session if the user is logged in.
if ($current_user->isAuthenticated() && $current_user->id() == $user->id()) {
$current_user->setAccount($user);
}
@@ -96,7 +98,8 @@ public function access(UserInterface $user) {
* @return \Drupal\Core\Url
* A unique url that provides a one-time email change confirmation.
*/
- public static function getUrl(UserInterface $account, array $options = [], $timestamp = REQUEST_TIME, $hash = NULL) {
+ public static function getUrl(UserInterface $account, array $options = [], $timestamp = NULL, $hash = NULL) {
+ $timestamp = $timestamp ?: \Drupal::time()->getRequestTime();
$langcode = isset($options['langcode']) ? $options['langcode'] : $account->getPreferredLangcode();
$hash = empty($hash) ? user_pass_rehash($account, $timestamp) : $hash;
$url_options = ['absolute' => TRUE, 'language' => \Drupal::service('language_manager')->getLanguage($langcode)];
diff --git a/core/modules/user/src/Tests/Update/UpdateMailChangeTest.php b/core/modules/user/src/Tests/Update/UpdateMailChangeTest.php
index 78d31dd..f5098e9 100644
--- a/core/modules/user/src/Tests/Update/UpdateMailChangeTest.php
+++ b/core/modules/user/src/Tests/Update/UpdateMailChangeTest.php
@@ -33,7 +33,6 @@ public function testMailChangeUpdate() {
// Check that mail change notifications settings are not set.
$this->assertNull($user_settings->get('notify.mail_change_notification'));
$this->assertNull($user_settings->get('notify.mail_change_verification'));
- $this->assertNull($user_settings->get('mail_change_timeout'));
// Check that mail change configurations are not set.
$this->assertNull($user_mail->get('mail_change_notification'));
@@ -47,8 +46,6 @@ public function testMailChangeUpdate() {
// Check that mail change notifications were set to FALSE.
$this->assertFalse($user_settings->get('notify.mail_change_notification'));
$this->assertFalse($user_settings->get('notify.mail_change_verification'));
- // Check that mail change timeout was set.
- $this->assertIdentical($user_settings->get('mail_change_timeout'), 86400);
$config = Yaml::parse(file_get_contents(__DIR__ . '/../../../config/install/user.mail.yml'));
diff --git a/core/modules/user/tests/src/Functional/UserMailChangeTest.php b/core/modules/user/tests/src/Functional/UserMailChangeTest.php
index cdc1b4e..1d376f5 100644
--- a/core/modules/user/tests/src/Functional/UserMailChangeTest.php
+++ b/core/modules/user/tests/src/Functional/UserMailChangeTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\user\Functional;
+use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\Core\Url;
use Drupal\Component\Utility\Unicode;
@@ -26,12 +27,20 @@ class UserMailChangeTest extends BrowserTestBase {
protected $account;
/**
+ * The date/time service.
+ *
+ * @var \Drupal\Component\Datetime\TimeInterface
+ */
+ protected $time;
+
+ /**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create a user.
$this->account = $this->drupalCreateUser();
+ $this->time = $this->container->get('datetime.time');
}
/**
@@ -46,10 +55,10 @@ public function testMailChange() {
'mail' => $new_mail,
'current_pass' => $this->account->pass_raw,
];
- $this->drupalPostForm($this->account->toUrl('edit-form'), $edit, t('Save'));
+ $this->drupalPostForm($this->account->toUrl('edit-form'), $edit, 'Save');
// Check that the validation status message has been displayed.
- $this->assertSession()->pageTextContains(t('Your new email address needs to be validated. Further instructions have been sent to your new email address.'));
+ $this->assertSession()->pageTextContains('Your updated email address needs to be validated. Further instructions have been sent to your new email address.');
$user_mail = $this->config('user.mail');
@@ -70,12 +79,12 @@ public function testMailChange() {
// Check that the email has been successfully updated.
$this->drupalGet($sent_mail_change_url);
- $this->assertSession()->responseContains(t('Your email address has been changed to %mail.', ['%mail' => $new_mail]));
+ $this->assertSession()->responseContains(new FormattableMarkup('Your email address has been changed to %mail.', ['%mail' => $new_mail]));
// Check that the change mail URL is not cached and expires after first use.
$this->drupalGet($sent_mail_change_url);
$this->assertNull($this->drupalGetHeader('X-Drupal-Cache'));
- $this->assertSession()->responseContains(t('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.'));
+ $this->assertSession()->responseContains('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.');
// Check that the user mail has been changed.
self::assertSame(User::load($this->account->id())->getEmail(), $new_mail);
@@ -97,10 +106,10 @@ public function testMailChangeNoVerification() {
'mail' => $new_mail,
'current_pass' => $this->account->pass_raw,
];
- $this->drupalPostForm($this->account->toUrl('edit-form'), $edit, t('Save'));
+ $this->drupalPostForm($this->account->toUrl('edit-form'), $edit, 'Save');
// Check that the validation status message has not been displayed.
- $this->assertSession()->pageTextNotContains(t('Your new email address needs to be validated. Further instructions have been sent to your new email address.'));
+ $this->assertSession()->pageTextNotContains('Your updated email address needs to be validated. Further instructions have been sent to your new email address.');
// Check that no E-mail was sent to the old or to the new address.
$this->assertEmpty($this->getMails());
@@ -113,7 +122,7 @@ public function testMailChangeNoVerification() {
* Tests change of email for blocked users.
*/
public function testBlockedUser() {
- $timestamp = REQUEST_TIME - 1;
+ $timestamp = $this->time->getRequestTime() - 1;
$account_cloned = clone $this->account;
$account_cloned->block()->save();
$this->drupalGet(MailChangeController::getUrl($account_cloned, [], $timestamp)->getInternalPath());
@@ -124,16 +133,16 @@ public function testBlockedUser() {
* Tests change of email for expired timestamp.
*/
public function testExpiredTimestamp() {
- $timestamp = REQUEST_TIME - (24 * 60 * 60 + 1);
+ $timestamp = $this->time->getRequestTime() - (24 * 60 * 60 + 1);
$this->drupalGet(MailChangeController::getUrl($this->account, [], $timestamp)->getInternalPath());
- $this->assertSession()->responseContains(t('You have tried to use an email address change link that has expired. Please visit your account and change your email again.'));
+ $this->assertSession()->responseContains('You have tried to use an email address change link that has expired. Please visit your account and change your email again.');
}
/**
* Tests change of email when other user is logged in.
*/
public function testOtherUserLoggedIn() {
- $timestamp = REQUEST_TIME - 1;
+ $timestamp = $this->time->getRequestTime() - 1;
// Create other account and login with it.
$current_account = $this->drupalCreateUser();
$this->drupalLogin($current_account);
@@ -143,33 +152,33 @@ public function testOtherUserLoggedIn() {
$this->account->setEmail($new_mail);
$path = MailChangeController::getUrl($this->account, [], $timestamp)->getInternalPath();
$this->drupalGet($path);
- $this->assertSession()->responseContains(t('You are currently logged in as %user, and are attempting to confirm an email address change for another account. Please log out and try using the link again.', ['%user' => $current_account->getAccountName(), ':logout' => Url::fromRoute('user.logout')->toString()]));
+ $this->assertSession()->responseContains(new FormattableMarkup('You are currently logged in as %user, and are attempting to confirm an email address change for another account. Please log out and try using the link again.', ['%user' => $current_account->getAccountName(), ':logout' => Url::fromRoute('user.logout')->toString()]));
// Retry as anonymous.
$this->drupalLogout();
$this->drupalGet($path);
- $this->assertSession()->responseContains(t('Your email address has been changed to %mail.', ['%mail' => $new_mail]));
+ $this->assertSession()->responseContains(new FormattableMarkup('Your email address has been changed to %mail.', ['%mail' => $new_mail]));
}
/**
* Tests change of email for timestamp in the future.
*/
public function testFutureTimestamp() {
- $timestamp = REQUEST_TIME + 60 * 60;
+ $timestamp = $this->time->getRequestTime() + 60 * 60;
$this->drupalGet(MailChangeController::getUrl($this->account, [], $timestamp)->getInternalPath());
- $this->assertSession()->responseContains(t('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.'));
+ $this->assertSession()->responseContains('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.');
}
/**
* Tests change of email with the wrong hash.
*/
public function testWrongHash() {
- $timestamp = REQUEST_TIME - 1;
+ $timestamp = $this->time->getRequestTime() - 1;
// Generate the hash for other user.
$other_account = $this->drupalCreateUser();
$hash = user_pass_rehash($other_account, $timestamp);
$this->drupalGet(MailChangeController::getUrl($this->account, [], $timestamp, $hash)->getInternalPath());
- $this->assertSession()->responseContains(t('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.'));
+ $this->assertSession()->responseContains('You have tried to use an email address change link that has either been used or is no longer valid. Please visit your account and change your email again.');
}
/**
diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php
index c463cc7..7d41a35 100644
--- a/core/modules/user/user.post_update.php
+++ b/core/modules/user/user.post_update.php
@@ -21,13 +21,20 @@ function user_post_update_mail_change() {
$config_factory->getEditable('user.settings')
->set('notify.mail_change_notification', FALSE)
->set('notify.mail_change_verification', FALSE)
- ->set('mail_change_timeout', 86400)
->save();
- $config = Yaml::parse(file_get_contents(__DIR__ . '/config/install/user.mail.yml'));
+ $mail_change_notification = [
+ 'body' => "[user:display-name],\n\nA request to change your email address has been made at [site:name]. In order to complete the change you will need to follow the instructions sent to your new email address within one day.",
+ 'subject' => 'Email change information for [user:display-name] at [site:name]',
+ ];
+ $mail_change_verification = [
+ 'body' => "[user:display-name],\n\nA request to change your email address has been made at [site:name]. You need to verify the change by clicking on the link below or copying and pasting it in your browser:\n\n[user:mail-change-url]\n\nThis is a one-time URL, so it can be used only once. It expires after one day. If not used, your email address at [site:name] will not change.",
+ 'subject' => 'Email change information for [user:display-name] at [site:name]',
+ ];
+
$config_factory->getEditable('user.mail')
- ->set('mail_change_notification', $config['mail_change_notification'])
- ->set('mail_change_verification', $config['mail_change_verification'])
+ ->set('mail_change_notification', $mail_change_notification)
+ ->set('mail_change_verification', $mail_change_verification)
->save();
}