From 0888424a2c3b8ea97207171f2105e5fa61777026 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 08:27:57 -0600 Subject: [PATCH 01/10] replace crockford encoding dependencies --- .../packs/personal-key-input-encoder.js | 16 ++++++++++ .../packs/personal-key-page-controller.js | 17 ++-------- package.json | 3 +- .../packs/personal-key-input-encoder-spec.js | 13 ++++++++ yarn.lock | 31 +++++-------------- 5 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 app/javascript/packs/personal-key-input-encoder.js create mode 100644 spec/javascripts/packs/personal-key-input-encoder-spec.js diff --git a/app/javascript/packs/personal-key-input-encoder.js b/app/javascript/packs/personal-key-input-encoder.js new file mode 100644 index 00000000000..f01367ee4dc --- /dev/null +++ b/app/javascript/packs/personal-key-input-encoder.js @@ -0,0 +1,16 @@ +import base32Decode from 'base32-decode'; +import base32Encode from 'base32-encode'; + +export function encodeInput(value) { + // Coerce mistaken user input from 'problem' letters: + // https://en.wikipedia.org/wiki/Base32#Crockford.27s_Base32 + value = value.replace(/-/g, ''); + value = base32Decode(value, 'Crockford'); + value = base32Encode(value, 'Crockford'); + + // Add back the dashes + value = value.toString().match(/.{4}/g).join('-'); + + // And uppercase + return value.toUpperCase(); +} diff --git a/app/javascript/packs/personal-key-page-controller.js b/app/javascript/packs/personal-key-page-controller.js index 1aa2ba32bb6..5e0ee17fd77 100644 --- a/app/javascript/packs/personal-key-page-controller.js +++ b/app/javascript/packs/personal-key-page-controller.js @@ -1,4 +1,4 @@ -import base32Crockford from 'base32-crockford-browser'; +import { encodeInput } from './personal-key-input-encoder'; const modalSelector = '#personal-key-confirm'; const modal = new window.LoginGov.Modal({ el: modalSelector }); @@ -47,19 +47,6 @@ function resetForm() { unsetInvalidHTML(); } -function formatInput(value) { - // Coerce mistaken user input from 'problem' letters: - // https://en.wikipedia.org/wiki/Base32#Crockford.27s_Base32 - value = base32Crockford.decode(value); - value = base32Crockford.encode(value); - - // Add back the dashes - value = value.toString().match(/.{4}/g).join('-'); - - // And uppercase - return value.toUpperCase(); -} - function handleSubmit(event) { event.preventDefault(); @@ -69,7 +56,7 @@ function handleSubmit(event) { return; } - const value = formatInput(input.value); + const value = encodeInput(input.value); if (value === personalKey) { unsetInvalidHTML(); diff --git a/package.json b/package.json index bb89f6de802..29a6961735a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "build": "true" }, "dependencies": { - "base32-crockford-browser": "^1.0.0", + "base32-decode": "^1.0.0", + "base32-encode": "^1.1.1", "basscss-sass": "^3.0.0", "classlist-polyfill": "^1.2.0", "cleave.js": "^1.5.3", diff --git a/spec/javascripts/packs/personal-key-input-encoder-spec.js b/spec/javascripts/packs/personal-key-input-encoder-spec.js new file mode 100644 index 00000000000..b0e749ac245 --- /dev/null +++ b/spec/javascripts/packs/personal-key-input-encoder-spec.js @@ -0,0 +1,13 @@ +import { encodeInput } from '../../../app/javascript/packs/personal-key-input-encoder'; + +describe('personal-key-input-encoder', () => { + it('removes Crockford-encoded characters', () => { + expect(encodeInput('LlIi-1111-1111-1111')).to.equal('1111-1111-1111-1111'); + + expect(encodeInput('LLII-0000-0000-llii')).to.equal('1111-0000-0000-1111'); + + expect(encodeInput('1234-1234-1234-1234')).to.equal('1234-1234-1234-1234'); + + expect(encodeInput('7P41-1JFN-W7JA-DVR2')).to.equal('7P41-1JFN-W7JA-DVR2'); + }); +}); diff --git a/yarn.lock b/yarn.lock index 64244413fa6..969dfc87dc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1838,12 +1838,15 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base32-crockford-browser@^1.0.0: +base32-decode@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/base32-crockford-browser/-/base32-crockford-browser-1.0.0.tgz#3684970a5826ba1430f01e719cf923b00d773dd8" - integrity sha1-NoSXClgmuhQw8B5xnPkjsA13Pdg= - dependencies: - optimist ">=0.1.0" + resolved "https://registry.yarnpkg.com/base32-decode/-/base32-decode-1.0.0.tgz#2a821d6a664890c872f20aa9aca95a4b4b80e2a7" + integrity sha512-KNWUX/R7wKenwE/G/qFMzGScOgVntOmbE27vvc6GrniDGYb6a5+qWcuoXl8WIOQL7q0TpK7nZDm1Y04Yi3Yn5g== + +base32-encode@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/base32-encode/-/base32-encode-1.1.1.tgz#d022d86aca0002a751bbe1bf20eb4a9b1cef4e95" + integrity sha512-eqa0BeGghj3guezlasdHJhr3+J5ZbbQvxeprkcDMbRQrjlqOT832IUDT4Al4ofAwekFYMqkkM9KMUHs9Cu0HKA== base64-js@^1.0.2: version "1.3.1" @@ -5951,11 +5954,6 @@ minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -6469,14 +6467,6 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" -optimist@>=0.1.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - optimize-css-assets-webpack-plugin@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" @@ -9742,11 +9732,6 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" From 6c22d875e9e49fb87b505f3a5463f1fa27cc7c14 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 09:40:09 -0600 Subject: [PATCH 02/10] move encoding to package --- .../personal-key-input/index.js} | 10 ++++++++-- .../packages/personal-key-input/index.spec.js | 15 +++++++++++++++ .../packages/personal-key-input/package.json | 12 ++++++++++++ .../packs/personal-key-page-controller.js | 2 +- package.json | 3 +-- .../packs/personal-key-input-encoder-spec.js | 13 ------------- yarn.lock | 6 ++++++ 7 files changed, 43 insertions(+), 18 deletions(-) rename app/javascript/{packs/personal-key-input-encoder.js => packages/personal-key-input/index.js} (63%) create mode 100644 app/javascript/packages/personal-key-input/index.spec.js create mode 100644 app/javascript/packages/personal-key-input/package.json delete mode 100644 spec/javascripts/packs/personal-key-input-encoder-spec.js diff --git a/app/javascript/packs/personal-key-input-encoder.js b/app/javascript/packages/personal-key-input/index.js similarity index 63% rename from app/javascript/packs/personal-key-input-encoder.js rename to app/javascript/packages/personal-key-input/index.js index f01367ee4dc..c9a7fc75292 100644 --- a/app/javascript/packs/personal-key-input-encoder.js +++ b/app/javascript/packages/personal-key-input/index.js @@ -1,9 +1,15 @@ import base32Decode from 'base32-decode'; import base32Encode from 'base32-encode'; +/** + * Coerce mistaken user input from 'problem' letters: + * https://en.wikipedia.org/wiki/Base32#Crockford.27s_Base32 + * + * @param {string} value User-provided text input + * + * @return {string} Encoded input + */ export function encodeInput(value) { - // Coerce mistaken user input from 'problem' letters: - // https://en.wikipedia.org/wiki/Base32#Crockford.27s_Base32 value = value.replace(/-/g, ''); value = base32Decode(value, 'Crockford'); value = base32Encode(value, 'Crockford'); diff --git a/app/javascript/packages/personal-key-input/index.spec.js b/app/javascript/packages/personal-key-input/index.spec.js new file mode 100644 index 00000000000..9ba09ae2268 --- /dev/null +++ b/app/javascript/packages/personal-key-input/index.spec.js @@ -0,0 +1,15 @@ +import { encodeInput } from './index.js'; + +describe('personal-key-input', () => { + describe('encodeInput', () => { + it('removes Crockford-encoded characters', () => { + expect(encodeInput('LlIi-1111-1111-1111')).to.equal('1111-1111-1111-1111'); + + expect(encodeInput('LlII-0000-0000-0000')).to.equal('1111-0000-0000-0000'); + + expect(encodeInput('1234-1234-1234-1234')).to.equal('1234-1234-1234-1234'); + + expect(encodeInput('7P41-1JFN-W7JA-DVR2')).to.equal('7P41-1JFN-W7JA-DVR2'); + }); + }); +}); diff --git a/app/javascript/packages/personal-key-input/package.json b/app/javascript/packages/personal-key-input/package.json new file mode 100644 index 00000000000..0b8e5a6d78f --- /dev/null +++ b/app/javascript/packages/personal-key-input/package.json @@ -0,0 +1,12 @@ +{ + "name": "@18f/identity-personal-key-input", + "private": true, + "version": "1.0.0", + "type": "module", + "bin": { + }, + "dependencies": { + "base32-decode": "^1.0.0", + "base32-encode": "^1.1.1" + } +} diff --git a/app/javascript/packs/personal-key-page-controller.js b/app/javascript/packs/personal-key-page-controller.js index 5e0ee17fd77..3320eed0f37 100644 --- a/app/javascript/packs/personal-key-page-controller.js +++ b/app/javascript/packs/personal-key-page-controller.js @@ -1,4 +1,4 @@ -import { encodeInput } from './personal-key-input-encoder'; +import { encodeInput } from '@18f/identity-personal-key-input'; const modalSelector = '#personal-key-confirm'; const modal = new window.LoginGov.Modal({ el: modalSelector }); diff --git a/package.json b/package.json index 29a6961735a..9afc7cfa2cd 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,7 @@ "build": "true" }, "dependencies": { - "base32-decode": "^1.0.0", - "base32-encode": "^1.1.1", + "@18f/identity-personal-key-input": "file:./app/javascript/packages/personal-key-input", "basscss-sass": "^3.0.0", "classlist-polyfill": "^1.2.0", "cleave.js": "^1.5.3", diff --git a/spec/javascripts/packs/personal-key-input-encoder-spec.js b/spec/javascripts/packs/personal-key-input-encoder-spec.js deleted file mode 100644 index b0e749ac245..00000000000 --- a/spec/javascripts/packs/personal-key-input-encoder-spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import { encodeInput } from '../../../app/javascript/packs/personal-key-input-encoder'; - -describe('personal-key-input-encoder', () => { - it('removes Crockford-encoded characters', () => { - expect(encodeInput('LlIi-1111-1111-1111')).to.equal('1111-1111-1111-1111'); - - expect(encodeInput('LLII-0000-0000-llii')).to.equal('1111-0000-0000-1111'); - - expect(encodeInput('1234-1234-1234-1234')).to.equal('1234-1234-1234-1234'); - - expect(encodeInput('7P41-1JFN-W7JA-DVR2')).to.equal('7P41-1JFN-W7JA-DVR2'); - }); -}); diff --git a/yarn.lock b/yarn.lock index 969dfc87dc6..12e0be7b287 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,12 @@ # yarn lockfile v1 +"@18f/identity-personal-key-input@file:./app/javascript/packages/personal-key-input": + version "1.0.0" + dependencies: + base32-decode "^1.0.0" + base32-encode "^1.1.1" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" From 9dbcf29a6c910c704015915325e796f2e2b64470 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:14:54 -0600 Subject: [PATCH 03/10] Update app/javascript/packages/personal-key-input/index.js Co-authored-by: Andrew Duthie --- app/javascript/packages/personal-key-input/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/packages/personal-key-input/index.js b/app/javascript/packages/personal-key-input/index.js index c9a7fc75292..860b4a9f070 100644 --- a/app/javascript/packages/personal-key-input/index.js +++ b/app/javascript/packages/personal-key-input/index.js @@ -15,7 +15,7 @@ export function encodeInput(value) { value = base32Encode(value, 'Crockford'); // Add back the dashes - value = value.toString().match(/.{4}/g).join('-'); + value = (value.match(/.{4}/g) || [value]).join('-'); // And uppercase return value.toUpperCase(); From fa26b3fb1a0d834d3ba90332cbc18fb0620c8055 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:15:02 -0600 Subject: [PATCH 04/10] Update app/javascript/packages/personal-key-input/index.js Co-authored-by: Andrew Duthie --- app/javascript/packages/personal-key-input/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/javascript/packages/personal-key-input/index.js b/app/javascript/packages/personal-key-input/index.js index 860b4a9f070..6c36cc9bd7d 100644 --- a/app/javascript/packages/personal-key-input/index.js +++ b/app/javascript/packages/personal-key-input/index.js @@ -11,8 +11,7 @@ import base32Encode from 'base32-encode'; */ export function encodeInput(value) { value = value.replace(/-/g, ''); - value = base32Decode(value, 'Crockford'); - value = base32Encode(value, 'Crockford'); + value = base32Encode(base32Decode(value, 'Crockford'), 'Crockford'); // Add back the dashes value = (value.match(/.{4}/g) || [value]).join('-'); From 003d94c8da1c131908ddb3f2234e45b8b029d3e7 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:37:15 -0600 Subject: [PATCH 05/10] Update app/javascript/packages/personal-key-input/package.json Co-authored-by: Andrew Duthie --- app/javascript/packages/personal-key-input/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/javascript/packages/personal-key-input/package.json b/app/javascript/packages/personal-key-input/package.json index 0b8e5a6d78f..a98c03debac 100644 --- a/app/javascript/packages/personal-key-input/package.json +++ b/app/javascript/packages/personal-key-input/package.json @@ -3,8 +3,6 @@ "private": true, "version": "1.0.0", "type": "module", - "bin": { - }, "dependencies": { "base32-decode": "^1.0.0", "base32-encode": "^1.1.1" From 0e95daf4d631c3861f1ab4c1fc4154ea6852fc2a Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:37:24 -0600 Subject: [PATCH 06/10] Update package.json Co-authored-by: Andrew Duthie --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 9afc7cfa2cd..eb7bd5b7932 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "build": "true" }, "dependencies": { - "@18f/identity-personal-key-input": "file:./app/javascript/packages/personal-key-input", "basscss-sass": "^3.0.0", "classlist-polyfill": "^1.2.0", "cleave.js": "^1.5.3", From 468ef4232a94e158370fdc56fb17c255f24b0001 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:39:18 -0600 Subject: [PATCH 07/10] yarn update --- yarn.lock | 6 ------ 1 file changed, 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 12e0be7b287..969dfc87dc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,12 +2,6 @@ # yarn lockfile v1 -"@18f/identity-personal-key-input@file:./app/javascript/packages/personal-key-input": - version "1.0.0" - dependencies: - base32-decode "^1.0.0" - base32-encode "^1.1.1" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" From 553f23e760a418abc7113729be50f0eb2ca92d05 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:40:23 -0600 Subject: [PATCH 08/10] remove broken class --- app/assets/stylesheets/components/_util.scss | 2 -- app/javascript/packs/personal-key-page-controller.js | 2 -- spec/features/users/regenerate_personal_key_spec.rb | 3 --- 3 files changed, 7 deletions(-) diff --git a/app/assets/stylesheets/components/_util.scss b/app/assets/stylesheets/components/_util.scss index b215d5fb4ff..ee4462107ea 100644 --- a/app/assets/stylesheets/components/_util.scss +++ b/app/assets/stylesheets/components/_util.scss @@ -4,8 +4,6 @@ .no-hover-decoration:hover { text-decoration: none; } -.invisible { visibility: hidden; } - .hidden { display: none; } .truncate-inline { diff --git a/app/javascript/packs/personal-key-page-controller.js b/app/javascript/packs/personal-key-page-controller.js index 3320eed0f37..7fad6387240 100644 --- a/app/javascript/packs/personal-key-page-controller.js +++ b/app/javascript/packs/personal-key-page-controller.js @@ -75,7 +75,6 @@ function show(event) { modal.on('show', function () { input.focus(); - personalKeyContainer.classList.add('invisible'); }); modal.show(); @@ -84,7 +83,6 @@ function show(event) { function hide() { modal.on('hide', function () { resetForm(); - personalKeyContainer.classList.remove('invisible'); }); modal.hide(); diff --git a/spec/features/users/regenerate_personal_key_spec.rb b/spec/features/users/regenerate_personal_key_spec.rb index 9cfd7f4eaf4..44dcea2cb2d 100644 --- a/spec/features/users/regenerate_personal_key_spec.rb +++ b/spec/features/users/regenerate_personal_key_spec.rb @@ -72,8 +72,6 @@ end context 'with javascript enabled', js: true do - let(:invisible_selector) { generate_class_selector('invisible') } - it 'prompts the user to enter their personal key to confirm they have it' do sign_in_and_2fa_user(user) visit account_two_factor_authentication_path @@ -140,7 +138,6 @@ def sign_up_and_view_personal_key def expect_confirmation_modal_to_appear_with_first_code_field_in_focus expect(page).not_to have_xpath("//div[@id='personal-key-confirm'][@class='display-none']") - expect(page).not_to have_xpath("//#{invisible_selector}[@id='personal-key']") expect(page.evaluate_script('document.activeElement.name')).to eq 'personal_key' end From 5f22d840686e4a564b432265241922d1b59a84b0 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 10:43:23 -0600 Subject: [PATCH 09/10] remove unused variable --- app/javascript/packs/personal-key-page-controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/javascript/packs/personal-key-page-controller.js b/app/javascript/packs/personal-key-page-controller.js index 7fad6387240..2200cbf7eab 100644 --- a/app/javascript/packs/personal-key-page-controller.js +++ b/app/javascript/packs/personal-key-page-controller.js @@ -3,7 +3,6 @@ import { encodeInput } from '@18f/identity-personal-key-input'; const modalSelector = '#personal-key-confirm'; const modal = new window.LoginGov.Modal({ el: modalSelector }); -const personalKeyContainer = document.getElementById('personal-key'); const personalKeyWords = [].slice.call(document.querySelectorAll('[data-personal-key]')); const formEl = document.getElementById('confirm-key'); const input = formEl.querySelector('input[type="text"]'); From 471e349bbd99d0545d7ed5da1ce466bc8df0eb48 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Tue, 3 Nov 2020 11:03:09 -0600 Subject: [PATCH 10/10] add couple more examples to spec --- app/javascript/packages/personal-key-input/index.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/javascript/packages/personal-key-input/index.spec.js b/app/javascript/packages/personal-key-input/index.spec.js index 9ba09ae2268..552cd52e419 100644 --- a/app/javascript/packages/personal-key-input/index.spec.js +++ b/app/javascript/packages/personal-key-input/index.spec.js @@ -10,6 +10,10 @@ describe('personal-key-input', () => { expect(encodeInput('1234-1234-1234-1234')).to.equal('1234-1234-1234-1234'); expect(encodeInput('7P41-1JFN-W7JA-DVR2')).to.equal('7P41-1JFN-W7JA-DVR2'); + + expect(encodeInput('')).to.be.a('string'); + + expect(encodeInput('abc')).to.be.a('string'); }); }); });