From 7ed91837bce02c6a467d594d8883032d4444ac4b Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 26 Feb 2021 10:03:32 -0500 Subject: [PATCH 1/2] Remove password strength meter component --- CHANGELOG.md | 1 + docs/_components/password-strength-meters.md | 42 -------- src/js/components/index.js | 2 - src/js/components/inputPasswordStrength.js | 95 ------------------- src/scss/components/_password.scss | 61 ------------ src/scss/styles.scss | 1 - test/components/passwordStrengthMeter.test.js | 50 ---------- 7 files changed, 1 insertion(+), 251 deletions(-) delete mode 100644 docs/_components/password-strength-meters.md delete mode 100644 src/js/components/inputPasswordStrength.js delete mode 100644 src/scss/components/_password.scss delete mode 100644 test/components/passwordStrengthMeter.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index bb1d88e8..b37b1d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Dropdown (`usa-button--dropdown`) - Small (`usa-button--small`) - Tiny (`usa-button--tiny`) +- The Password Strength Meter component has been removed. ### Bug Fixes diff --git a/docs/_components/password-strength-meters.md b/docs/_components/password-strength-meters.md deleted file mode 100644 index aa8e4b02..00000000 --- a/docs/_components/password-strength-meters.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Password strength meters ---- - -The password strength indicator should be used when users are trying to create a password. - -## Password component example - -{% capture example %} - -
-
- - -
-
-
-
-
-
-
-
-
-
-
-
- Password strength: - - ... - -
 
-
-
-
-
- -
-
- -{% endcapture %} -{% include helpers/code-example.html code=example %} diff --git a/src/js/components/index.js b/src/js/components/index.js index efa788e2..ef11de50 100644 --- a/src/js/components/index.js +++ b/src/js/components/index.js @@ -14,7 +14,6 @@ import timePicker from 'uswds/src/js/components/time-picker'; import tooltip from 'uswds/src/js/components/tooltip'; import validator from 'uswds/src/js/components/validator'; import accordionCloseButton from './accordionCloseButton'; -import inputPasswordMeter from './inputPasswordStrength'; export { accordion, @@ -33,5 +32,4 @@ export { tooltip, validator, accordionCloseButton, - inputPasswordMeter, }; diff --git a/src/js/components/inputPasswordStrength.js b/src/js/components/inputPasswordStrength.js deleted file mode 100644 index 0b3fca74..00000000 --- a/src/js/components/inputPasswordStrength.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable prefer-destructuring */ -import behavior from 'uswds/src/js/utils/behavior'; -import zxcvbn from 'zxcvbn'; - -// zxcvbn returns a strength score from 0 to 4 -// we map those scores to: -// 1. a CSS class to the pw strength module -// 2. text describing the score - -const scale = { - 0: ['lg-password-strength--very-weak', 'Very weak'], - 1: ['lg-password-strength--weak', 'Weak'], - 2: ['lg-password-strength--so-so', 'So - so'], - 3: ['lg-password-strength--good', 'Good'], - 4: ['lg-password-strength--great', 'Great!'], -}; - -// fallback if zxcvbn lookup fails / field is empty -const fallback = ['lg-password-strength--na', '...']; - -const getStrength = (z) => { - // override the strength value to 2 if the password is < 12 - if (!(z && z.password.length && z.password.length >= 12)) { - if (z.score >= 3) { - // eslint-disable-next-line no-param-reassign - z.score = 2; - } - } - return z && z.password.length ? scale[z.score] : fallback; -}; - -const getExplanation = (z) => { - if (!z || z.score > 2) return ' '; - - const { warning, suggestions } = z.feedback; - - if (!warning && !suggestions.length) return ' '; - if (warning) return warning; - - return suggestions; -}; - -const toggleSubmitInput = (submitEl, length = 0, score = 0) => { - if (!submitEl) return; - - if (score < 3 || length < 12) { - submitEl.setAttribute('disabled', true); - } else { - submitEl.removeAttribute('disabled'); - } -}; - -const checkPasswordStrength = (e, submit, forbiddenPasswords) => { - const passwordStrengthResponse = zxcvbn(e.target.value, JSON.parse(forbiddenPasswords)); - const [strengthClass, strength] = getStrength(passwordStrengthResponse); - const explanation = getExplanation(passwordStrengthResponse); - toggleSubmitInput( - submit, - passwordStrengthResponse.password.length, - passwordStrengthResponse.score, - ); - return { strengthClass, strength, explanation }; -}; - -const updatePasswordStrength = (e, submit) => { - const forbiddenPasswordsElement = document.querySelector('[data-forbidden-passwords]'); - const forbiddenPasswords = forbiddenPasswordsElement.dataset.forbiddenPasswords; - - // the pw strength module is hidden by default ("hide" CSS class) - // (so that javascript disabled browsers won't see it) - // thus, first step is unhiding it - const passwordContainer = document.querySelector('#lg-password-strength--container'); - passwordContainer.className = ''; - - const { strengthClass, strength, explanation } = checkPasswordStrength( - e, - submit, - forbiddenPasswords, - ); - - passwordContainer.className = strengthClass; - document.querySelector('.lg-password--summary').innerHTML = strength; - document.querySelector('.lg-password--explanation').innerHTML = explanation; -}; - -const inputPasswordMeter = behavior({ - keyup: { - '.usa-input--lg-password': function keyPress(event) { - const submit = document.querySelector('input[type="submit"]'); - updatePasswordStrength(event, submit); - }, - }, -}); - -export default inputPasswordMeter; diff --git a/src/scss/components/_password.scss b/src/scss/components/_password.scss deleted file mode 100644 index 13313896..00000000 --- a/src/scss/components/_password.scss +++ /dev/null @@ -1,61 +0,0 @@ -// password strength module - -$space-tiny: .25rem !default; - -.usa-input--lg-password { - @extend .usa-input; -} - -.lg-password--bar { - background-color: #e9e9e9; - border: $space-tiny solid map-get($site-palette, 'site-white'); - border-radius: 6px; - box-sizing: border-box; - height: 16px; - float: left; - width: 25%; - margin-top: .25rem; -} - -.lg-password--bar:first-child { - margin-left: -.25rem; -} - -.lg-password--bar:last-child { - padding-right: .25rem; -} - -.lg-password--explanation { - font-size: .9rem; - font-style: italic; -} - -.lg-password--guidance { - margin-bottom: .5rem; -} - -.lg-password-strength--weak, -.lg-password-strength--so-so, -.lg-password-strength--good, -.lg-password-strength--great, -.lg-password-strength--na, -.lg-password-strength--very-weak { - width: 100%; - max-width: 30.5rem; -} - -.lg-password-strength--weak { - .lg-password--bar:nth-child(-n+1) { background-color: map-get($site-palette, 'site-red'); } -} - -.lg-password-strength--so-so { - .lg-password--bar:nth-child(-n+2) { background-color: map-get($site-palette, 'site-yellow'); } -} - -.lg-password-strength--good { - .lg-password--bar:nth-child(-n+3) { background-color: map-get($site-palette, 'site-green'); } -} - -.lg-password-strength--great { - .lg-password--bar { background-color: map-get($site-palette, 'site-dark-green'); } -} diff --git a/src/scss/styles.scss b/src/scss/styles.scss index e4b2bd47..008aa09d 100644 --- a/src/scss/styles.scss +++ b/src/scss/styles.scss @@ -26,5 +26,4 @@ @import 'components/sidenav'; @import 'components/spinner'; @import 'components/typography'; -@import 'components/password'; @import 'components/verification-badge'; diff --git a/test/components/passwordStrengthMeter.test.js b/test/components/passwordStrengthMeter.test.js deleted file mode 100644 index 421acb6a..00000000 --- a/test/components/passwordStrengthMeter.test.js +++ /dev/null @@ -1,50 +0,0 @@ -const host = `http://localhost:${process.env.JEST_PORT}`; - -beforeEach(async () => page.goto(`${host}/components/password-strength-meters/`)); - -test('expect input to be weak', async () => { - await page.focus('.usa-input--lg-password'); - await expect(page).toMatchElement('input[type="submit"][disabled]'); - await expect(page).toMatchElement('.lg-password-strength--na'); - - await page.type('.usa-input--lg-password', 'aaa'); - await expect(page).toMatch('Repeats like "aaa" are easy to guess'); - await expect(page).toMatchElement('.lg-password-strength--very-weak'); -}); - -test('expect input to be weak', async () => { - await page.focus('.usa-input--lg-password'); - await expect(page).toMatchElement('input[type="submit"][disabled]'); - await expect(page).toMatchElement('.lg-password-strength--na'); - - await page.type('.usa-input--lg-password', 'aaa123'); - await expect(page).toMatch('This is a very common password'); - await expect(page).toMatchElement('.lg-password-strength--weak'); -}); - -test('expect input to be so-so', async () => { - await page.focus('.usa-input--lg-password'); - await expect(page).toMatchElement('input[type="submit"][disabled]'); - - await page.type('.usa-input--lg-password', 'aaa123cool'); - await expect(page).toMatch('This is similar to a commonly used password'); - await expect(page).toMatchElement('.lg-password-strength--so-so'); -}); - -test('expect input to be good', async () => { - await page.focus('.usa-input--lg-password'); - await expect(page).toMatchElement('input[type="submit"][disabled]'); - - await page.type('.usa-input--lg-password', 'aaa123coolme'); - await expect(page).toMatch('Password strength: Good'); - await expect(page).toMatchElement('.lg-password-strength--good'); -}); - -test('expect input to be great', async () => { - await page.focus('.usa-input--lg-password'); - await expect(page).toMatchElement('input[type="submit"][disabled]'); - - await page.type('.usa-input--lg-password', '190809a8fqjekjlaj209cakjcoijes092'); - await expect(page).toMatch('Password strength: Great!'); - await expect(page).toMatchElement('.lg-password-strength--great'); -}); From 35e3ee14cd4c4e4b71b4dcf894857c53762394f5 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 3 Mar 2021 09:18:25 -0500 Subject: [PATCH 2/2] Remove zxcvbn dependency Unused after removal of password strength component --- package-lock.json | 5 ----- package.json | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 104c25a5..c8d91471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20433,11 +20433,6 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } - }, - "zxcvbn": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz", - "integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=" } } } diff --git a/package.json b/package.json index 8e5d3fbf..fae1f619 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,7 @@ }, "homepage": "https://github.com/18F/identity-style-guide#readme", "dependencies": { - "uswds": "^2.9.0", - "zxcvbn": "^4.4.2" + "uswds": "^2.9.0" }, "devDependencies": { "@babel/core": "^7.12.3",