diff --git a/core/modules/user/config/user.settings.yml b/core/modules/user/config/user.settings.yml index b4c8a58..3b53e41 100644 --- a/core/modules/user/config/user.settings.yml +++ b/core/modules/user/config/user.settings.yml @@ -14,3 +14,4 @@ register: visitors signatures: '0' cancel_method: user_cancel_block password_reset_timeout: '86400' +password_strength: '1' diff --git a/core/modules/user/lib/Drupal/user/Tests/UserCreateTest.php b/core/modules/user/lib/Drupal/user/Tests/UserCreateTest.php index f728123..565e40e 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserCreateTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserCreateTest.php @@ -36,6 +36,17 @@ protected function testUserAdd() { $this->assertFieldbyId('edit-status-1', 1, 'The user status option Active exists.', 'User login'); $this->assertFieldByXPath('//input[@type="radio" and @id="edit-status-1" and @checked="checked"]', NULL, 'Default setting for user status is active.'); + // Test that the password strength indicator displays. + $config = config('user.settings'); + + $config->set('password_strength', TRUE)->save(); + $this->drupalGet('admin/people/create'); + $this->assertRaw(t('Password strength:'), 'The password strength indicator is displayed.'); + + $config->set('password_strength', FALSE)->save(); + $this->drupalGet('admin/people/create'); + $this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.'); + // We create two users, notifying one and not notifying the other, to // ensure that the tests work in both cases. foreach (array(FALSE, TRUE) as $notify) { diff --git a/core/modules/user/lib/Drupal/user/Tests/UserEditTest.php b/core/modules/user/lib/Drupal/user/Tests/UserEditTest.php index 0cd38e4..178ddda 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserEditTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserEditTest.php @@ -76,6 +76,18 @@ function testUserEdit() { $user1->pass_raw = $new_pass; $this->drupalLogin($user1); $this->drupalLogout(); + + // Test that the password strength indicator displays. + $config = config('user.settings'); + $this->drupalLogin($user1); + + $config->set('password_strength', TRUE)->save(); + $this->drupalPost("user/$user1->uid/edit", $edit, t('Save')); + $this->assertRaw(t('Password strength:'), 'The password strength indicator is displayed.'); + + $config->set('password_strength', FALSE)->save(); + $this->drupalPost("user/$user1->uid/edit", $edit, t('Save')); + $this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.'); } /** diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index 198bd9b..b8f6d42 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -361,6 +361,11 @@ function user_admin_settings($form, &$form_state) { '#default_value' => $config->get('verify_mail'), '#description' => t('New users will be required to validate their e-mail address prior to logging into the site, and will be assigned a system-generated password. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.') ); + $form['registration_cancellation']['user_password_strength'] = array( + '#type' => 'checkbox', + '#title' => t('Enable password strength indicator'), + '#default_value' => $config->get('password_strength'), + ); form_load_include($form_state, 'inc', 'user', 'user.pages'); $form['registration_cancellation']['user_cancel_method'] = array( '#type' => 'radios', @@ -631,6 +636,7 @@ function user_admin_settings_submit($form, &$form_state) { ->set('anonymous', $form_state['values']['anonymous']) ->set('admin_role', $form_state['values']['user_admin_role']) ->set('register', $form_state['values']['user_register']) + ->set('password_strength', $form_state['values']['user_password_strength']) ->set('verify_mail', $form_state['values']['user_email_verification']) ->set('signatures', $form_state['values']['user_signatures']) ->set('cancel_method', $form_state['values']['user_cancel_method']) diff --git a/core/modules/user/user.js b/core/modules/user/user.js index e5f6142..bfb6845 100644 --- a/core/modules/user/user.js +++ b/core/modules/user/user.js @@ -23,70 +23,61 @@ Drupal.behaviors.password = { var confirmResult = outerWrapper.find('div.password-confirm'); var confirmChild = confirmResult.find('span'); - // Add the description box. - var passwordMeter = '
' + translate.strengthTitle + '
'; - confirmInput.parent().after('
'); - innerWrapper.append(passwordMeter); - var passwordDescription = outerWrapper.find('div.password-suggestions').hide(); + // If the password strength indicator is enabled, add it's markup. + if (settings.password.showStrengthIndicator) { + var passwordMeter = '
' + translate.strengthTitle + '
'; + confirmInput.parent().after('
'); + innerWrapper.prepend(passwordMeter); + var passwordDescription = outerWrapper.find('div.password-suggestions').hide(); + } - // Check the password strength. - var passwordCheck = function () { - - // Evaluate the password strength. - var result = Drupal.evaluatePasswordStrength(passwordInput.val(), settings.password); + // Check that password and confirmation inputs match. + var passwordCheckMatch = function (confirmInputVal) { + var success = passwordInput.val() === confirmInputVal; + var confirmClass = success ? 'ok' : 'error'; - // Update the suggestions for how to improve the password. - if (passwordDescription.html() !== result.message) { - passwordDescription.html(result.message); - } + // Fill in the success message and set the class accordingly. + confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]) + .removeClass('ok error').addClass(confirmClass); + }; - // Only show the description box if there is a weakness in the password. - if (result.strength === 100) { - passwordDescription.hide(); - } - else { - passwordDescription.show(); - } + // Check the password strength. + var passwordCheck = function () { + if (settings.password.showStrengthIndicator) { + // Evaluate the password strength. + var result = Drupal.evaluatePasswordStrength(passwordInput.val(), settings.password); - // Adjust the length of the strength indicator. - innerWrapper.find('.indicator') - .css('width', result.strength + '%') - .css('background-color', result.indicatorColor); + // Update the suggestions for how to improve the password. + if (passwordDescription.html() !== result.message) { + passwordDescription.html(result.message); + } - // Update the strength indication text. - innerWrapper.find('.password-strength-text').html(result.indicatorText); + // Only show the description box if a weakness exists in the password. + result.strength === 100 ? passwordDescription.hide() : passwordDescription.show(); - passwordCheckMatch(); - }; + // Adjust the length of the strength indicator. + innerWrapper.find('.indicator') + .css('width', result.strength + '%') + .css('background-color', result.indicatorColor); - // Check that password and confirmation inputs match. - var passwordCheckMatch = function () { + // Update the strength indication text. + innerWrapper.find('.password-strength-text').html(result.indicatorText); + } + // Check the value in the confirm input and show results. if (confirmInput.val()) { - var success = passwordInput.val() === confirmInput.val(); - - // Show the confirm result. + passwordCheckMatch(confirmInput.val()); confirmResult.css({ visibility: 'visible' }); - - // Remove the previous styling if any exists. - if (this.confirmClass) { - confirmChild.removeClass(this.confirmClass); - } - - // Fill in the success message and set the class accordingly. - var confirmClass = success ? 'ok' : 'error'; - confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]).addClass(confirmClass); - this.confirmClass = confirmClass; } else { confirmResult.css({ visibility: 'hidden' }); } }; - // Monitor keyup and blur events. - // Blur must be used because a mouse paste does not trigger keyup. - passwordInput.keyup(passwordCheck).focus(passwordCheck).blur(passwordCheck); - confirmInput.keyup(passwordCheckMatch).blur(passwordCheckMatch); + // Monitor input events. + $.each([passwordInput, confirmInput], function () { + this.bind('input', passwordCheck); + }); }); } }; diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 19dc974..5570313 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -2440,10 +2440,18 @@ function _user_mail_notify($op, $account, $langcode = NULL) { * @see system_element_info() */ function user_form_process_password_confirm($element) { - global $user; + $password_settings = array( + 'confirmTitle' => t('Passwords match:'), + 'confirmSuccess' => t('yes'), + 'confirmFailure' => t('no'), + 'showStrengthIndicator' => FALSE, + ); - $js_settings = array( - 'password' => array( + if (config('user.settings')->get('password_strength')) { + + global $user; + $password_settings['showStrengthIndicator'] = TRUE; + $password_settings += array( 'strengthTitle' => t('Password strength:'), 'hasWeaknesses' => t('To make your password stronger:'), 'tooShort' => t('Make it at least 6 characters'), @@ -2452,15 +2460,16 @@ function user_form_process_password_confirm($element) { 'addNumbers' => t('Add numbers'), 'addPunctuation' => t('Add punctuation'), 'sameAsUsername' => t('Make it different from your username'), - 'confirmSuccess' => t('yes'), - 'confirmFailure' => t('no'), 'weak' => t('Weak'), 'fair' => t('Fair'), 'good' => t('Good'), 'strong' => t('Strong'), - 'confirmTitle' => t('Passwords match:'), 'username' => (isset($user->name) ? $user->name : ''), - ), + ); + } + + $js_settings = array( + 'password' => $password_settings, ); $element['#attached']['library'][] = array('user', 'drupal.user');