diff --git a/app/assets/stylesheets/components/_password.scss b/app/assets/stylesheets/components/_password.scss index 7ea776858a3..741656eece5 100644 --- a/app/assets/stylesheets/components/_password.scss +++ b/app/assets/stylesheets/components/_password.scss @@ -1,7 +1,7 @@ // password strength module $weak: #e80e0e; -$so-so: #ffac00; +$average: #ffac00; $good: #9ac056; $great: #00b200; @@ -20,9 +20,9 @@ $great: #00b200; } } -.pw-so-so { +.pw-average { .pw-bar:nth-child(-n + 2) { - background-color: $so-so; + background-color: $average; } } diff --git a/app/javascript/packs/pw-strength.js b/app/javascript/packs/pw-strength.js index 0e792f1dea2..0e067dfb07c 100644 --- a/app/javascript/packs/pw-strength.js +++ b/app/javascript/packs/pw-strength.js @@ -8,7 +8,7 @@ import { t } from '@18f/identity-i18n'; const scale = { 0: ['pw-very-weak', t('instructions.password.strength.i')], 1: ['pw-weak', t('instructions.password.strength.ii')], - 2: ['pw-so-so', t('instructions.password.strength.iii')], + 2: ['pw-average', t('instructions.password.strength.iii')], 3: ['pw-good', t('instructions.password.strength.iv')], 4: ['pw-great', t('instructions.password.strength.v')], }; @@ -26,13 +26,21 @@ function getStrength(z) { return z && z.password.length ? scale[z.score] : fallback; } -export function getFeedback(z) { - if (!z || !z.password || z.score > 2) { +export function getFeedback(z, { minimumLength }) { + if (!z || !z.password) { return ' '; } const { warning, suggestions } = z.feedback; + if (!warning && !suggestions.length) { + if (z.password.length < minimumLength) { + return t('errors.attributes.password.too_short.other', { count: minimumLength }); + } + + return ' '; + } + function lookup(str) { // i18n-tasks-use t('zxcvbn.feedback.a_word_by_itself_is_easy_to_guess') // i18n-tasks-use t('zxcvbn.feedback.add_another_word_or_two_uncommon_words_are_better') @@ -66,9 +74,6 @@ export function getFeedback(z) { return t(`zxcvbn.feedback.${snakeCase(str)}`); } - if (!warning && !suggestions.length) { - return ' '; - } if (warning) { return lookup(warning); } @@ -96,11 +101,7 @@ function analyzePw() { const pwFeedback = document.getElementById('pw-strength-feedback'); const forbiddenPasswordsElement = document.querySelector('[data-forbidden]'); const forbiddenPasswords = getForbiddenPasswords(forbiddenPasswordsElement); - - // the pw strength module is hidden by default ("display-none" CSS class) - // (so that javascript disabled browsers won't see it) - // thus, first step is unhiding it - pwCntnr.className = ''; + const minPasswordLength = +pwCntnr.getAttribute('data-pw-min-length'); function updatePasswordFeedback(cls, strength, feedback) { pwCntnr.className = cls; @@ -118,8 +119,9 @@ function analyzePw() { function checkPasswordStrength(password) { const z = zxcvbn(password, forbiddenPasswords); + const [cls, strength] = getStrength(z); - const feedback = getFeedback(z); + const feedback = getFeedback(z, { minimumLength: minPasswordLength }); validatePasswordField(z.score); updatePasswordFeedback(cls, strength, feedback); diff --git a/app/views/devise/shared/_password_strength.html.erb b/app/views/devise/shared/_password_strength.html.erb index 1003611b6b1..98eae167a2f 100644 --- a/app/views/devise/shared/_password_strength.html.erb +++ b/app/views/devise/shared/_password_strength.html.erb @@ -1,4 +1,4 @@ -