import React, { useState, useMemo, useContext, useEffect } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; import zxcvbn from 'zxcvbn'; import { useSelector } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import Button from '../../../components/ui/button'; import Typography from '../../../components/ui/typography'; import { TEXT_ALIGN, TypographyVariant, JustifyContent, FONT_WEIGHT, AlignItems, } from '../../../helpers/constants/design-system'; import { ONBOARDING_COMPLETION_ROUTE, ONBOARDING_SECURE_YOUR_WALLET_ROUTE, } from '../../../helpers/constants/routes'; import FormField from '../../../components/ui/form-field'; import Box from '../../../components/ui/box'; import CheckBox from '../../../components/ui/check-box'; import { ThreeStepProgressBar, threeStepStages, TwoStepProgressBar, twoStepStages, } from '../../../components/app/step-progress-bar'; import { PASSWORD_MIN_LENGTH } from '../../../helpers/constants/common'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import { getFirstTimeFlowType, getCurrentKeyring } from '../../../selectors'; import { FIRST_TIME_FLOW_TYPES } from '../../../helpers/constants/onboarding'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { Icon, IconName } from '../../../components/component-library'; export default function CreatePassword({ createNewAccount, importWithRecoveryPhrase, secretRecoveryPhrase, }) { const t = useI18nContext(); const [confirmPassword, setConfirmPassword] = useState(''); const [password, setPassword] = useState(''); const [passwordError, setPasswordError] = useState(''); const [passwordStrength, setPasswordStrength] = useState(''); const [passwordStrengthText, setPasswordStrengthText] = useState(''); const [confirmPasswordError, setConfirmPasswordError] = useState(''); const [termsChecked, setTermsChecked] = useState(false); const [showPassword, setShowPassword] = useState(false); const history = useHistory(); const firstTimeFlowType = useSelector(getFirstTimeFlowType); const trackEvent = useContext(MetaMetricsContext); const currentKeyring = useSelector(getCurrentKeyring); useEffect(() => { if (currentKeyring) { if (firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT) { history.replace(ONBOARDING_COMPLETION_ROUTE); } else { history.replace(ONBOARDING_SECURE_YOUR_WALLET_ROUTE); } } }, [currentKeyring, history, firstTimeFlowType]); const isValid = useMemo(() => { if (!password || !confirmPassword || password !== confirmPassword) { return false; } if (password.length < PASSWORD_MIN_LENGTH) { return false; } return !passwordError && !confirmPasswordError; }, [password, confirmPassword, passwordError, confirmPasswordError]); const getPasswordStrengthLabel = (isTooShort, score) => { if (isTooShort) { return { className: 'create-password__weak', dataTestId: 'short-password-error', text: t('passwordNotLongEnough'), description: '', }; } if (score >= 4) { return { className: 'create-password__strong', dataTestId: 'strong-password', text: t('strong'), description: '', }; } if (score === 3) { return { className: 'create-password__average', dataTestId: 'average-password', text: t('average'), description: t('passwordStrengthDescription'), }; } return { className: 'create-password__weak', dataTestId: 'weak-password', text: t('weak'), description: t('passwordStrengthDescription'), }; }; const handlePasswordChange = (passwordInput) => { const isTooShort = passwordInput.length && passwordInput.length < PASSWORD_MIN_LENGTH; const { score } = zxcvbn(passwordInput); const passwordStrengthLabel = getPasswordStrengthLabel(isTooShort, score); const passwordStrengthComponent = t('passwordStrength', [ {passwordStrengthLabel.text} , ]); const confirmError = !confirmPassword || passwordInput === confirmPassword ? '' : t('passwordsDontMatch'); setPassword(passwordInput); setPasswordStrength(passwordStrengthComponent); setPasswordStrengthText(passwordStrengthLabel.description); setConfirmPasswordError(confirmError); }; const handleConfirmPasswordChange = (confirmPasswordInput) => { const error = password === confirmPasswordInput ? '' : t('passwordsDontMatch'); setConfirmPassword(confirmPasswordInput); setConfirmPasswordError(error); }; const handleCreate = async (event) => { event?.preventDefault(); if (!isValid) { return; } trackEvent({ category: MetaMetricsEventCategory.Onboarding, event: MetaMetricsEventName.OnboardingWalletCreationAttempted, }); // If secretRecoveryPhrase is defined we are in import wallet flow if ( secretRecoveryPhrase && firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT ) { await importWithRecoveryPhrase(password, secretRecoveryPhrase); history.push(ONBOARDING_COMPLETION_ROUTE); } else { // Otherwise we are in create new wallet flow try { if (createNewAccount) { await createNewAccount(password); } history.push(ONBOARDING_SECURE_YOUR_WALLET_ROUTE); } catch (error) { setPasswordError(error.message); } } }; return (
{secretRecoveryPhrase && firstTimeFlowType === FIRST_TIME_FLOW_TYPES.IMPORT ? ( ) : ( )} {t('createPassword')} {t('passwordSetupDetails')}
{ e.preventDefault(); setShowPassword(!showPassword); }} > {showPassword ? t('hide') : t('show')} } />
) } /> ); } CreatePassword.propTypes = { createNewAccount: PropTypes.func, importWithRecoveryPhrase: PropTypes.func, secretRecoveryPhrase: PropTypes.string, };