1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-30 16:18:07 +01:00
metamask-extension/ui/components/app/srp-input/srp-input.js
Mark Stacey f49e5076f3
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.
2022-02-23 17:00:26 -03:30

113 lines
3.4 KiB
JavaScript

import { ethers } from 'ethers';
import React, { useCallback, useState } from 'react';
import PropTypes from 'prop-types';
import { useI18nContext } from '../../../hooks/useI18nContext';
import TextField from '../../ui/text-field';
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;
export default function SrpInput({ onChange }) {
const [srpError, setSrpError] = useState('');
const [draftSrp, setDraftSrp] = useState('');
const [showSrp, setShowSrp] = useState(false);
const t = useI18nContext();
const onSrpChange = useCallback(
(event) => {
const rawSrp = event.target.value;
let newSrpError = '';
const parsedSeedPhrase = parseSecretRecoveryPhrase(rawSrp);
if (rawSrp) {
const wordCount = parsedSeedPhrase.split(/\s/u).length;
if (wordCount % 3 !== 0 || wordCount > 24 || wordCount < 12) {
newSrpError = t('seedPhraseReq');
} else if (!isValidMnemonic(parsedSeedPhrase)) {
newSrpError = t('invalidSeedPhrase');
}
}
setDraftSrp(rawSrp);
setSrpError(newSrpError);
onChange(newSrpError ? '' : parsedSeedPhrase);
},
[setDraftSrp, setSrpError, t, onChange],
);
const toggleShowSrp = useCallback(() => {
setShowSrp((currentShowSrp) => !currentShowSrp);
}, []);
return (
<>
<label htmlFor="import-srp__srp" className="import-srp__srp-label">
<Typography>{t('secretRecoveryPhrase')}</Typography>
</label>
{showSrp ? (
<textarea
id="import-srp__srp"
className="import-srp__srp-shown"
onChange={onSrpChange}
onPaste={clearClipboard}
value={draftSrp}
placeholder={t('seedPhrasePlaceholder')}
autoComplete="off"
/>
) : (
<TextField
id="import-srp__srp"
type="password"
onChange={onSrpChange}
value={draftSrp}
placeholder={t('seedPhrasePlaceholderPaste')}
autoComplete="off"
onPaste={clearClipboard}
/>
)}
{srpError ? (
<Typography
color={COLORS.ERROR1}
tag="span"
className="import-srp__srp-error"
>
{srpError}
</Typography>
) : null}
<div className="import-srp__show-srp">
<CheckBox
id="import-srp__show-srp-checkbox"
checked={showSrp}
onClick={toggleShowSrp}
title={t('showSeedPhrase')}
/>
<label
className="import-srp__show-srp-label"
htmlFor="import-srp__show-srp-checkbox"
>
<Typography tag="span">{t('showSeedPhrase')}</Typography>
</label>
</div>
</>
);
}
SrpInput.propTypes = {
/**
* Event handler for SRP changes.
*
* This is only called with a valid, well-formated (i.e. exactly one space
* between each word) SRP or with an empty string.
*
* This is called each time the draft SRP is updated. If the draft SRP is
* valid, this is called with a well-formatted version of that draft SRP.
* Otherwise, this is called with an empty string.
*/
onChange: PropTypes.func.isRequired,
};