From 716931a492c37e5b9136fbc679e43cd39b95c05f Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Mon, 21 Mar 2022 20:52:04 +0000 Subject: [PATCH 01/13] Version v10.11.3 --- CHANGELOG.md | 5 ++++- package.json | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a58844f6..2b244595c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.11.3] + ## [10.11.2] ### Fixed - Fix bug that users who are connected to another extension would hit when viewing connected sites ([#13974](https://github.com/MetaMask/metamask-extension/pull/13974)) @@ -2779,7 +2781,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.11.2...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.11.3...HEAD +[10.11.3]: https://github.com/MetaMask/metamask-extension/compare/v10.11.2...v10.11.3 [10.11.2]: https://github.com/MetaMask/metamask-extension/compare/v10.11.1...v10.11.2 [10.11.1]: https://github.com/MetaMask/metamask-extension/compare/v10.11.0...v10.11.1 [10.11.0]: https://github.com/MetaMask/metamask-extension/compare/v10.10.2...v10.11.0 diff --git a/package.json b/package.json index 04949d247..e24bd0d35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.11.2", + "version": "10.11.3", "private": true, "repository": { "type": "git", From 22f9de9a2cb4db220d3236b6df97e511e60f2633 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 23 Feb 2022 17:00:26 -0330 Subject: [PATCH 02/13] Refactor: Extract SRP input from create vault component (#13720) This is a pure refactor that extracts the SRP input from the `CreateNewVault` component. This is intended to make future changes to the SRP input easier, and to reduce duplication between the old and new onboarding flows. Extensive unit tests have been added for the new SRP input component. A new test library was added (`@testing-library/user-event`) for simulating user events with components rendered using the `@testing-library` library. A new helper method has been added (`renderWithLocalization`) for rendering components using `@testing-library` with just our localization contexts added as a wrapper. The localization contexts were already added by the `renderWithProviders` helper function, but there is no need for a Redux provider in these unit tests. --- package.json | 1 + test/helpers/setup-helper.js | 8 + test/lib/render-helpers.js | 14 + ui/components/app/app-components.scss | 1 + .../app/create-new-vault/create-new-vault.js | 89 +-- .../create-new-vault/create-new-vault.scss | 23 - ui/components/app/srp-input/index.js | 1 + .../parse-secret-recovery-phrase'.test.js | 0 .../parse-secret-recovery-phrase.js | 0 ui/components/app/srp-input/srp-input.js | 112 ++++ ui/components/app/srp-input/srp-input.scss | 24 + .../app/srp-input/srp-input.stories.js | 23 + ui/components/app/srp-input/srp-input.test.js | 571 ++++++++++++++++++ yarn.lock | 7 + 14 files changed, 766 insertions(+), 108 deletions(-) create mode 100644 ui/components/app/srp-input/index.js rename ui/components/app/{create-new-vault => srp-input}/parse-secret-recovery-phrase'.test.js (100%) rename ui/components/app/{create-new-vault => srp-input}/parse-secret-recovery-phrase.js (100%) create mode 100644 ui/components/app/srp-input/srp-input.js create mode 100644 ui/components/app/srp-input/srp-input.scss create mode 100644 ui/components/app/srp-input/srp-input.stories.js create mode 100644 ui/components/app/srp-input/srp-input.test.js diff --git a/package.json b/package.json index e24bd0d35..7a1201ae5 100644 --- a/package.json +++ b/package.json @@ -261,6 +261,7 @@ "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^3.2.1", + "@testing-library/user-event": "^13.5.0", "@types/react": "^16.9.53", "addons-linter": "1.14.0", "babelify": "^10.0.0", diff --git a/test/helpers/setup-helper.js b/test/helpers/setup-helper.js index f9d2112aa..9d4b7d892 100644 --- a/test/helpers/setup-helper.js +++ b/test/helpers/setup-helper.js @@ -79,3 +79,11 @@ if (!window.crypto.getRandomValues) { // eslint-disable-next-line node/global-require window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues'); } + +// Used to test `clearClipboard` function +if (!window.navigator.clipboard) { + window.navigator.clipboard = {}; +} +if (!window.navigator.clipboard.writeText) { + window.navigator.clipboard.writeText = () => undefined; +} diff --git a/test/lib/render-helpers.js b/test/lib/render-helpers.js index 37c5d6370..9fc7aad16 100644 --- a/test/lib/render-helpers.js +++ b/test/lib/render-helpers.js @@ -95,3 +95,17 @@ export function renderWithProvider(component, store) { return render(component, { wrapper: Wrapper }); } + +export function renderWithLocalization(component) { + const Wrapper = ({ children }) => ( + + {children} + + ); + + Wrapper.propTypes = { + children: PropTypes.node, + }; + + return render(component, { wrapper: Wrapper }); +} diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index c11ff6027..a135c0766 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -54,6 +54,7 @@ @import 'selected-account/index'; @import 'signature-request/index'; @import 'signature-request-original/index'; +@import 'srp-input/srp-input'; @import 'tab-bar/index'; @import 'token-cell/token-cell'; @import 'token-list-display/token-list-display'; diff --git a/ui/components/app/create-new-vault/create-new-vault.js b/ui/components/app/create-new-vault/create-new-vault.js index 3c2b5007b..05ca7a716 100644 --- a/ui/components/app/create-new-vault/create-new-vault.js +++ b/ui/components/app/create-new-vault/create-new-vault.js @@ -1,17 +1,12 @@ -import { ethers } from 'ethers'; import React, { useCallback, useContext, useState } from 'react'; import PropTypes from 'prop-types'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import TextField from '../../ui/text-field'; import Button from '../../ui/button'; -import { clearClipboard } from '../../../helpers/utils/util'; import CheckBox from '../../ui/check-box'; import Typography from '../../ui/typography'; -import { COLORS } from '../../../helpers/constants/design-system'; -import { parseSecretRecoveryPhrase } from './parse-secret-recovery-phrase'; - -const { isValidMnemonic } = ethers.utils; +import SrpInput from '../srp-input'; export default function CreateNewVault({ disabled = false, @@ -24,33 +19,11 @@ export default function CreateNewVault({ const [password, setPassword] = useState(''); const [passwordError, setPasswordError] = useState(''); const [seedPhrase, setSeedPhrase] = useState(''); - const [seedPhraseError, setSeedPhraseError] = useState(''); - const [showSeedPhrase, setShowSeedPhrase] = useState(false); const [termsChecked, setTermsChecked] = useState(false); const t = useI18nContext(); const metricsEvent = useContext(MetaMetricsContext); - const onSeedPhraseChange = useCallback( - (rawSeedPhrase) => { - let newSeedPhraseError = ''; - - if (rawSeedPhrase) { - const parsedSeedPhrase = parseSecretRecoveryPhrase(rawSeedPhrase); - const wordCount = parsedSeedPhrase.split(/\s/u).length; - if (wordCount % 3 !== 0 || wordCount > 24 || wordCount < 12) { - newSeedPhraseError = t('seedPhraseReq'); - } else if (!isValidMnemonic(parsedSeedPhrase)) { - newSeedPhraseError = t('invalidSeedPhrase'); - } - } - - setSeedPhrase(rawSeedPhrase); - setSeedPhraseError(newSeedPhraseError); - }, - [setSeedPhrase, setSeedPhraseError, t], - ); - const onPasswordChange = useCallback( (newPassword) => { let newConfirmPasswordError = ''; @@ -93,8 +66,7 @@ export default function CreateNewVault({ seedPhrase && (!includeTerms || termsChecked) && !passwordError && - !confirmPasswordError && - !seedPhraseError; + !confirmPasswordError; const onImport = useCallback( async (event) => { @@ -104,7 +76,7 @@ export default function CreateNewVault({ return; } - await onSubmit(password, parseSecretRecoveryPhrase(seedPhrase)); + await onSubmit(password, seedPhrase); }, [isValid, onSubmit, password, seedPhrase], ); @@ -121,10 +93,6 @@ export default function CreateNewVault({ setTermsChecked((currentTermsChecked) => !currentTermsChecked); }, [metricsEvent]); - const toggleShowSeedPhrase = useCallback(() => { - setShowSeedPhrase((currentShowSeedPhrase) => !currentShowSeedPhrase); - }, []); - const termsOfUse = t('acceptTermsOfUse', [
- - {showSeedPhrase ? ( -