? modules/.DS_Store Index: modules/system/system.css =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.css,v retrieving revision 1.51 diff -u -p -r1.51 system.css --- modules/system/system.css 5 May 2008 21:10:48 -0000 1.51 +++ modules/system/system.css 17 Sep 2008 21:44:08 -0000 @@ -516,36 +516,44 @@ html.js .js-hide { /* ** Password strength indicator */ -span.password-strength { - visibility: hidden; +.password-strength-title { + float: left; +} +#password-indicator { + border: 1px solid silver; + float: right; + height: 0.9em; + margin: 0.4em 0.85em 0 0; + width: 6.3em; +} +#password-indicator div { + height: 100%; + width: 0%; + background-color: #96F6AA; } input.password-field { - margin-right: 10px; /* LTR */ + margin-right: 0.8em; /* LTR */ } div.password-description { - padding: 0 2px; - margin: 4px 0 0 0; + padding: 0.2em 0.5em; + margin: 0.4em 0 0 0; font-size: 0.85em; - max-width: 500px; + width: 39.3em; + border: 1px solid silver; } div.password-description ul { margin-bottom: 0; } .password-parent { margin: 0 0 0 0; + float: left; } /* ** Password confirmation checker */ -input.password-confirm { - margin-right: 10px; /* LTR */ -} .confirm-parent { - margin: 5px 0 0 0; + margin: 0.5em 0 0 0; } -span.password-confirm { +div.password-confirm { visibility: hidden; } -span.password-confirm span { - font-weight: normal; -} Index: modules/user/user.js =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.js,v retrieving revision 1.6 diff -u -p -r1.6 user.js --- modules/user/user.js 12 Sep 2007 18:29:32 -0000 1.6 +++ modules/user/user.js 17 Sep 2008 21:44:08 -0000 @@ -5,72 +5,61 @@ * that its confirmation is correct. */ Drupal.behaviors.password = function(context) { + var translate = Drupal.settings.password; $("input.password-field:not(.password-processed)", context).each(function() { var passwordInput = $(this).addClass('password-processed'); - var parent = $(this).parent(); - // Wait this number of milliseconds before checking password. - var monitorDelay = 700; + var innerWrapper = $(this).parent(); + var outerWrapper = $(this).parent().parent(); // Add the password strength layers. - $(this).after(''+ translate.strengthTitle +' ').parent(); - var passwordStrength = $("span.password-strength", parent); + var passwordStrength = $("span.password-strength", innerWrapper); var passwordResult = $("span.password-result", passwordStrength); - parent.addClass("password-parent"); + innerWrapper.addClass("password-parent"); + + // Add the description box at the end. + var passwordMeter = '
' + translate.strengthTitle + '
'; + $(".password-confirm", outerWrapper).after('
'); + $(innerWrapper).append(passwordMeter); + var passwordDescription = $("div.password-description", outerWrapper).hide(); // Add the password confirmation layer. var outerItem = $(this).parent().parent(); - $("input.password-confirm", outerItem).after(''+ translate["confirmTitle"] +' ').parent().addClass("confirm-parent"); - var confirmInput = $("input.password-confirm", outerItem); - var confirmResult = $("span.password-confirm", outerItem); + $("input.password-confirm", outerWrapper).after('
' + translate["confirmTitle"] + '
').parent().addClass("confirm-parent"); + var confirmInput = $("input.password-confirm", outerWrapper); + var confirmResult = $("div.password-confirm", outerWrapper); var confirmChild = $("span", confirmResult); - // Add the description box at the end. - $(confirmInput).parent().after('
'); - var passwordDescription = $("div.password-description", $(this).parent().parent()).hide(); - - // Check the password fields. + // Check the password strength. var passwordCheck = function () { - // Remove timers for a delayed check if they exist. - if (this.timer) { - clearTimeout(this.timer); - } - - // Verify that there is a password to check. - if (!passwordInput.val()) { - passwordStrength.css({ visibility: "hidden" }); - passwordDescription.hide(); - return; - } // Evaluate password strength. - var result = Drupal.evaluatePasswordStrength(passwordInput.val()); - passwordResult.html(result.strength == "" ? "" : translate[result.strength +"Strength"]); - // Map the password strength to the relevant drupal CSS class. - var classMap = { low: "error", medium: "warning", high: "ok" }; - var newClass = classMap[result.strength] || ""; - - // Remove the previous styling if any exists; add the new class. - if (this.passwordClass) { - passwordResult.removeClass(this.passwordClass); - passwordDescription.removeClass(this.passwordClass); - } passwordDescription.html(result.message); - passwordResult.addClass(newClass); - if (result.strength == "high") { + + if (result.strength == 100) { passwordDescription.hide(); } else { - passwordDescription.addClass(newClass); + passwordDescription.show(); + } + + // adjust the length of the strength indicator + $("#indicator").css('width', result.strength + '%'); + + //if the confirmation box has a result then check that they are the same. + if (confirmInput.val()) { + passwordCheckMatch(); } - this.passwordClass = newClass; - // Check that password and confirmation match. + }; + + // Check that password and confirmation match. + var passwordCheckMatch = function () { // Hide the result layer if confirmation is empty, otherwise show the layer. - confirmResult.css({ visibility: (confirmInput.val() == "" ? "hidden" : "visible") }); + confirmResult.css({ visibility: "visible" }); var success = passwordInput.val() == confirmInput.val(); @@ -80,36 +69,16 @@ Drupal.behaviors.password = function(con } // Fill in the correct message and set the class accordingly. - var confirmClass = success ? "ok" : "error"; - confirmChild.html(translate["confirm"+ (success ? "Success" : "Failure")]).addClass(confirmClass); + var confirmClass = success ? "ok" : 'error'; + confirmChild.html(translate["confirm" + (success ? "Success" : "Failure")]).addClass(confirmClass); this.confirmClass = confirmClass; - // Show the indicator and tips. - passwordStrength.css({ visibility: "visible" }); - passwordDescription.show(); - }; - - // Do a delayed check on the password fields. - var passwordDelayedCheck = function() { - // Postpone the check since the user is most likely still typing. - if (this.timer) { - clearTimeout(this.timer); - } - - // When the user clears the field, hide the tips immediately. - if (!passwordInput.val()) { - passwordStrength.css({ visibility: "hidden" }); - passwordDescription.hide(); - return; - } + } - // Schedule the actual check. - this.timer = setTimeout(passwordCheck, monitorDelay); - }; // Monitor keyup and blur events. // Blur must be used because a mouse paste does not trigger keyup. - passwordInput.keyup(passwordDelayedCheck).blur(passwordCheck); - confirmInput.keyup(passwordDelayedCheck).blur(passwordCheck); + passwordInput.keyup(passwordCheck).focus(passwordCheck).blur(passwordCheck); + confirmInput.keyup(passwordCheckMatch).blur(passwordCheckMatch); }); }; @@ -119,51 +88,49 @@ Drupal.behaviors.password = function(con * Returns the estimated strength and the relevant output message. */ Drupal.evaluatePasswordStrength = function(value) { - var strength = "", msg = "", translate = Drupal.settings.password; + var strength = 100, msg = [], translate = Drupal.settings.password; var hasLetters = value.match(/[a-zA-Z]+/); var hasNumbers = value.match(/[0-9]+/); var hasPunctuation = value.match(/[^a-zA-Z0-9]+/); var hasCasing = value.match(/[a-z]+.*[A-Z]+|[A-Z]+.*[a-z]+/); - // Check if the password is blank. - if (!value.length) { - strength = ""; - msg = ""; - } + // add messages and remove points from 100 for password weaknesses + // Check if length is less than 6 characters. - else if (value.length < 6) { - strength = "low"; - msg = translate.tooShort; + if (value.length < 6) { + msg.push(translate.tooShort); + strength -= 55; + if (!value.length) { + strength -= 15; + } } - // Check if password is the same as the username (convert both to lowercase). - else if (value.toLowerCase() == translate.username.toLowerCase()) { - strength = "low"; - msg = translate.sameAsUsername; + + if (!hasLetters || !hasCasing) { + msg.push(translate.addLetters); + strength = strength - 10; } - // Check if it contains letters, numbers, punctuation, and upper/lower case. - else if (hasLetters && hasNumbers && hasPunctuation && hasCasing) { - strength = "high"; + + if (!hasNumbers) { + strength -= 10; + msg.push(translate.addNumbers); } - // Password is not secure enough so construct the medium-strength message. - else { - // Extremely bad passwords still count as low. - var count = (hasLetters ? 1 : 0) + (hasNumbers ? 1 : 0) + (hasPunctuation ? 1 : 0) + (hasCasing ? 1 : 0); - strength = count > 1 ? "medium" : "low"; - - msg = []; - if (!hasLetters || !hasCasing) { - msg.push(translate.addLetters); - } - if (!hasNumbers) { - msg.push(translate.addNumbers); - } - if (!hasPunctuation) { - msg.push(translate.addPunctuation); - } - msg = translate.needsMoreVariation +""; + + if (!hasPunctuation) { + strength -= 10; + msg.push(translate.addPunctuation); } + // Check if password is the same as the username (convert both to lowercase). + if (value.toLowerCase() == translate.username.toLowerCase()) { + msg.push(translate.sameAsUsername); + // passwords the same as username are always very weak. + strength = 5; + } + + //assemble the final message. + msg = translate.hasWeaknesses + ""; + return { strength: strength, message: msg }; }; Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.922 diff -u -p -r1.922 user.module --- modules/user/user.module 17 Sep 2008 07:11:59 -0000 1.922 +++ modules/user/user.module 17 Sep 2008 21:44:10 -0000 @@ -2132,15 +2132,12 @@ function _user_password_dynamic_validati drupal_add_js(array( 'password' => array( 'strengthTitle' => t('Password strength:'), - 'lowStrength' => t('Low'), - 'mediumStrength' => t('Medium'), - 'highStrength' => t('High'), - 'tooShort' => t('It is recommended to choose a password that contains at least six characters. It should include numbers, punctuation, and both upper and lowercase letters.'), - 'needsMoreVariation' => t('The password does not include enough variation to be secure. Try:'), - 'addLetters' => t('Adding both upper and lowercase letters.'), - 'addNumbers' => t('Adding numbers.'), - 'addPunctuation' => t('Adding punctuation.'), - 'sameAsUsername' => t('It is recommended to choose a password different from the username.'), + 'hasWeaknesses' => t('To make your password more secure:'), + 'tooShort' => t('Make it at least 6 characters'), + 'addLetters' => t('Use both upper and lowercase letters'), + 'addNumbers' => t('Add numbers'), + 'addPunctuation' => t('Add punctuation'), + 'sameAsUsername' => t('Make it different from your username'), 'confirmSuccess' => t('Yes'), 'confirmFailure' => t('No'), 'confirmTitle' => t('Passwords match:'),