mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-02 06:07:06 +01:00
7929a92c66
* Clear the clipboard after the seed phrase is pasted On the "Import" page of the import onboarding flow, we now clear the clipboard after the secret recovery phrase is pasted. This ensures that the SRP isn't accidentally pasted somewhere else by the user, which can be an easy and disastrous mistake to make. * Clear clipboard during new onboarding flow as well
121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { useHistory } from 'react-router-dom';
|
|
import { ethers } from 'ethers';
|
|
import classnames from 'classnames';
|
|
import PropTypes from 'prop-types';
|
|
import {
|
|
TwoStepProgressBar,
|
|
twoStepStages,
|
|
} from '../../../components/app/step-progress-bar';
|
|
import Box from '../../../components/ui/box';
|
|
import Button from '../../../components/ui/button';
|
|
import Typography from '../../../components/ui/typography';
|
|
import {
|
|
FONT_WEIGHT,
|
|
TEXT_ALIGN,
|
|
TYPOGRAPHY,
|
|
} from '../../../helpers/constants/design-system';
|
|
import { ONBOARDING_CREATE_PASSWORD_ROUTE } from '../../../helpers/constants/routes';
|
|
import { clearClipboard } from '../../../helpers/utils/util';
|
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
|
|
|
export default function ImportSRP({ submitSecretRecoveryPhrase }) {
|
|
const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState('');
|
|
const [revealSRP, setRevealSRP] = useState(true);
|
|
const [error, setError] = useState('');
|
|
const history = useHistory();
|
|
const t = useI18nContext();
|
|
const { isValidMnemonic } = ethers.utils;
|
|
|
|
const parseSeedPhrase = (seedPhrase) =>
|
|
(seedPhrase || '').trim().toLowerCase().match(/\w+/gu)?.join(' ') || '';
|
|
|
|
const handleSecretRecoveryPhraseChange = (recoveryPhrase) => {
|
|
setError('');
|
|
if (recoveryPhrase) {
|
|
const parsedSecretRecoveryPhrase = parseSeedPhrase(recoveryPhrase);
|
|
const wordCount = parsedSecretRecoveryPhrase.split(/\s/u).length;
|
|
if (wordCount % 3 !== 0 || wordCount > 24 || wordCount < 12) {
|
|
setError(t('seedPhraseReq'));
|
|
} else if (!isValidMnemonic(parsedSecretRecoveryPhrase)) {
|
|
setError(t('invalidSeedPhrase'));
|
|
}
|
|
}
|
|
setSecretRecoveryPhrase(recoveryPhrase);
|
|
};
|
|
|
|
return (
|
|
<div className="import-srp">
|
|
<TwoStepProgressBar stage={twoStepStages.RECOVERY_PHRASE_CONFIRM} />
|
|
<div className="import-srp__header">
|
|
<Typography variant={TYPOGRAPHY.H2} fontWeight={FONT_WEIGHT.BOLD}>
|
|
{t('importExistingWalletTitle')}
|
|
</Typography>
|
|
<Typography variant={TYPOGRAPHY.H4}>
|
|
{t('importExistingWalletDescription', [
|
|
<a
|
|
key="learnMore"
|
|
type="link"
|
|
href="https://metamask.zendesk.com/hc/en-us/articles/360036464651"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{t('learnMore')}
|
|
</a>,
|
|
])}
|
|
</Typography>
|
|
</div>
|
|
<div className="import-srp__actions">
|
|
<Box textAlign={TEXT_ALIGN.LEFT}>
|
|
<Typography variant={TYPOGRAPHY.H4}>
|
|
{t('secretRecoveryPhrase')}
|
|
</Typography>
|
|
|
|
<div className="srp-text-area">
|
|
<button onClick={() => setRevealSRP(!revealSRP)}>
|
|
<i
|
|
className={`far fa-eye${revealSRP ? '-slash' : ''}`}
|
|
color="grey"
|
|
/>
|
|
</button>
|
|
<textarea
|
|
data-testid="import-srp-text"
|
|
className={classnames('srp-text-area__textarea', {
|
|
'srp-text-area__textarea--blur': !revealSRP,
|
|
'srp-text-area__textarea--error': error,
|
|
})}
|
|
onChange={({ target: { value } }) =>
|
|
handleSecretRecoveryPhraseChange(value)
|
|
}
|
|
onPaste={clearClipboard}
|
|
autoComplete="off"
|
|
autoCorrect="off"
|
|
/>
|
|
{error && (
|
|
<span className="srp-text-area__textarea__error-message">
|
|
{error}
|
|
</span>
|
|
)}
|
|
</div>
|
|
<Button
|
|
type="primary"
|
|
data-testid="import-srp-confirm"
|
|
large
|
|
onClick={() => {
|
|
submitSecretRecoveryPhrase(secretRecoveryPhrase);
|
|
history.replace(ONBOARDING_CREATE_PASSWORD_ROUTE);
|
|
}}
|
|
disabled={error || secretRecoveryPhrase.length === 0}
|
|
>
|
|
{t('confirmRecoveryPhrase')}
|
|
</Button>
|
|
</Box>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
ImportSRP.propTypes = {
|
|
submitSecretRecoveryPhrase: PropTypes.func,
|
|
};
|