mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Create password page (#13792)
This commit is contained in:
parent
2bc7aab402
commit
bea907e437
17
app/_locales/en/messages.json
generated
17
app/_locales/en/messages.json
generated
@ -1983,7 +1983,7 @@
|
||||
"message": "“$1” was successfully added!"
|
||||
},
|
||||
"newPassword": {
|
||||
"message": "New password (min 8 chars)"
|
||||
"message": "New password (8 characters min)"
|
||||
},
|
||||
"newToMetaMask": {
|
||||
"message": "New to MetaMask?"
|
||||
@ -2277,11 +2277,18 @@
|
||||
"passwordSetupDetails": {
|
||||
"message": "This password will unlock your MetaMask wallet only on this device. MetaMask can not recover this password."
|
||||
},
|
||||
"passwordStrength": {
|
||||
"message": "Password strength: $1",
|
||||
"description": "Return password strength to the user when user wants to create password."
|
||||
},
|
||||
"passwordStrengthDescription": {
|
||||
"message": "A strong password can improve the security of your wallet should your device be stolen or compromised."
|
||||
},
|
||||
"passwordTermsWarning": {
|
||||
"message": "I understand that MetaMask cannot recover this password for me. $1"
|
||||
},
|
||||
"passwordsDontMatch": {
|
||||
"message": "Passwords Don't Match"
|
||||
"message": "Passwords don't match"
|
||||
},
|
||||
"pastePrivateKey": {
|
||||
"message": "Enter your private key string here:",
|
||||
@ -2948,6 +2955,9 @@
|
||||
"storePhrase": {
|
||||
"message": "Store this phrase in a password manager like 1Password."
|
||||
},
|
||||
"strong": {
|
||||
"message": "Strong"
|
||||
},
|
||||
"stxAreHere": {
|
||||
"message": "Smart Transactions are here!"
|
||||
},
|
||||
@ -3772,6 +3782,9 @@
|
||||
"walletCreationSuccessTitle": {
|
||||
"message": "Wallet creation successful"
|
||||
},
|
||||
"weak": {
|
||||
"message": "Weak"
|
||||
},
|
||||
"web3ShimUsageNotification": {
|
||||
"message": "We noticed that the current website tried to use the removed window.web3 API. If the site appears to be broken, please click $1 for more information.",
|
||||
"description": "$1 is a clickable link."
|
||||
|
@ -1052,6 +1052,16 @@
|
||||
"buffer-equal": true
|
||||
}
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"builtin": {
|
||||
"events.EventEmitter": true,
|
||||
"util.inherits": true
|
||||
},
|
||||
"packages": {
|
||||
"delegates": true,
|
||||
"readable-stream": true
|
||||
}
|
||||
},
|
||||
"arr-diff": {
|
||||
"packages": {
|
||||
"arr-flatten": true,
|
||||
@ -1460,6 +1470,7 @@
|
||||
"anymatch": true,
|
||||
"async-each": true,
|
||||
"braces": true,
|
||||
"fsevents": true,
|
||||
"glob-parent": true,
|
||||
"inherits": true,
|
||||
"is-binary-path": true,
|
||||
@ -1726,6 +1737,16 @@
|
||||
"through2": true
|
||||
}
|
||||
},
|
||||
"detect-libc": {
|
||||
"builtin": {
|
||||
"child_process.spawnSync": true,
|
||||
"fs.readdirSync": true,
|
||||
"os.platform": true
|
||||
},
|
||||
"globals": {
|
||||
"process.env": true
|
||||
}
|
||||
},
|
||||
"detective": {
|
||||
"packages": {
|
||||
"acorn-node": true,
|
||||
@ -2429,6 +2450,45 @@
|
||||
"process.version": true
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"builtin": {
|
||||
"events.EventEmitter": true,
|
||||
"fs.stat": true,
|
||||
"path.join": true,
|
||||
"util.inherits": true
|
||||
},
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"process.nextTick": true,
|
||||
"process.platform": true,
|
||||
"setImmediate": true
|
||||
},
|
||||
"native": true,
|
||||
"packages": {
|
||||
"node-pre-gyp": true
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"builtin": {
|
||||
"util.format": true
|
||||
},
|
||||
"globals": {
|
||||
"clearInterval": true,
|
||||
"process": true,
|
||||
"setImmediate": true,
|
||||
"setInterval": true
|
||||
},
|
||||
"packages": {
|
||||
"aproba": true,
|
||||
"console-control-strings": true,
|
||||
"has-unicode": true,
|
||||
"object-assign": true,
|
||||
"signal-exit": true,
|
||||
"string-width": true,
|
||||
"strip-ansi": true,
|
||||
"wide-align": true
|
||||
}
|
||||
},
|
||||
"get-assigned-identifiers": {
|
||||
"builtin": {
|
||||
"assert.equal": true
|
||||
@ -2807,6 +2867,16 @@
|
||||
"process.argv": true
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"builtin": {
|
||||
"os.type": true
|
||||
},
|
||||
"globals": {
|
||||
"process.env.LANG": true,
|
||||
"process.env.LC_ALL": true,
|
||||
"process.env.LC_CTYPE": true
|
||||
}
|
||||
},
|
||||
"has-value": {
|
||||
"packages": {
|
||||
"get-value": true,
|
||||
@ -2978,6 +3048,11 @@
|
||||
"is-plain-object": true
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"packages": {
|
||||
"number-is-nan": true
|
||||
}
|
||||
},
|
||||
"is-glob": {
|
||||
"packages": {
|
||||
"is-extglob": true
|
||||
@ -3508,6 +3583,56 @@
|
||||
"setTimeout": true
|
||||
}
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"builtin": {
|
||||
"events.EventEmitter": true,
|
||||
"fs.existsSync": true,
|
||||
"fs.readFileSync": true,
|
||||
"fs.renameSync": true,
|
||||
"path.dirname": true,
|
||||
"path.existsSync": true,
|
||||
"path.join": true,
|
||||
"path.resolve": true,
|
||||
"url.parse": true,
|
||||
"url.resolve": true,
|
||||
"util.inherits": true
|
||||
},
|
||||
"globals": {
|
||||
"__dirname": true,
|
||||
"console.log": true,
|
||||
"process.arch": true,
|
||||
"process.cwd": true,
|
||||
"process.env": true,
|
||||
"process.platform": true,
|
||||
"process.version.substr": true,
|
||||
"process.versions": true
|
||||
},
|
||||
"packages": {
|
||||
"detect-libc": true,
|
||||
"nopt": true,
|
||||
"npmlog": true,
|
||||
"rimraf": true,
|
||||
"semver": true
|
||||
}
|
||||
},
|
||||
"nopt": {
|
||||
"builtin": {
|
||||
"path": true,
|
||||
"stream.Stream": true,
|
||||
"url": true
|
||||
},
|
||||
"globals": {
|
||||
"console": true,
|
||||
"process.argv": true,
|
||||
"process.env.DEBUG_NOPT": true,
|
||||
"process.env.NOPT_DEBUG": true,
|
||||
"process.platform": true
|
||||
},
|
||||
"packages": {
|
||||
"abbrev": true,
|
||||
"osenv": true
|
||||
}
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"builtin": {
|
||||
"url.parse": true,
|
||||
@ -3535,6 +3660,22 @@
|
||||
"once": true
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"builtin": {
|
||||
"events.EventEmitter": true,
|
||||
"util": true
|
||||
},
|
||||
"globals": {
|
||||
"process.nextTick": true,
|
||||
"process.stderr": true
|
||||
},
|
||||
"packages": {
|
||||
"are-we-there-yet": true,
|
||||
"console-control-strings": true,
|
||||
"gauge": true,
|
||||
"set-blocking": true
|
||||
}
|
||||
},
|
||||
"object-copy": {
|
||||
"packages": {
|
||||
"copy-descriptor": true,
|
||||
@ -3616,6 +3757,54 @@
|
||||
"readable-stream": true
|
||||
}
|
||||
},
|
||||
"os-homedir": {
|
||||
"builtin": {
|
||||
"os.homedir": true
|
||||
},
|
||||
"globals": {
|
||||
"process.env": true,
|
||||
"process.getuid": true,
|
||||
"process.platform": true
|
||||
}
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"globals": {
|
||||
"process.env.SystemRoot": true,
|
||||
"process.env.TEMP": true,
|
||||
"process.env.TMP": true,
|
||||
"process.env.TMPDIR": true,
|
||||
"process.env.windir": true,
|
||||
"process.platform": true
|
||||
}
|
||||
},
|
||||
"osenv": {
|
||||
"builtin": {
|
||||
"child_process.exec": true,
|
||||
"path": true
|
||||
},
|
||||
"globals": {
|
||||
"process.env.COMPUTERNAME": true,
|
||||
"process.env.ComSpec": true,
|
||||
"process.env.EDITOR": true,
|
||||
"process.env.HOSTNAME": true,
|
||||
"process.env.PATH": true,
|
||||
"process.env.PROMPT": true,
|
||||
"process.env.PS1": true,
|
||||
"process.env.Path": true,
|
||||
"process.env.SHELL": true,
|
||||
"process.env.USER": true,
|
||||
"process.env.USERDOMAIN": true,
|
||||
"process.env.USERNAME": true,
|
||||
"process.env.VISUAL": true,
|
||||
"process.env.path": true,
|
||||
"process.nextTick": true,
|
||||
"process.platform": true
|
||||
},
|
||||
"packages": {
|
||||
"os-homedir": true,
|
||||
"os-tmpdir": true
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"packages": {
|
||||
"p-try": true
|
||||
@ -4325,6 +4514,12 @@
|
||||
"lru-cache": true
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
"globals": {
|
||||
"process.stderr": true,
|
||||
"process.stdout": true
|
||||
}
|
||||
},
|
||||
"set-value": {
|
||||
"packages": {
|
||||
"extend-shallow": true,
|
||||
@ -4588,6 +4783,7 @@
|
||||
},
|
||||
"string-width": {
|
||||
"packages": {
|
||||
"code-point-at": true,
|
||||
"emoji-regex": true,
|
||||
"is-fullwidth-code-point": true,
|
||||
"strip-ansi": true
|
||||
@ -5240,6 +5436,11 @@
|
||||
"isexe": true
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"packages": {
|
||||
"string-width": true
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"builtin": {
|
||||
"fs.createWriteStream": true,
|
||||
|
@ -221,7 +221,8 @@
|
||||
"uuid": "^8.3.2",
|
||||
"valid-url": "^1.0.9",
|
||||
"web3": "^0.20.7",
|
||||
"web3-stream-provider": "^4.0.0"
|
||||
"web3-stream-provider": "^4.0.0",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/code-frame": "^7.12.13",
|
||||
|
@ -32,6 +32,8 @@ export default function FormField({
|
||||
disabled,
|
||||
placeholder,
|
||||
warning,
|
||||
passwordStrength,
|
||||
passwordStrengthText,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
@ -122,6 +124,24 @@ export default function FormField({
|
||||
{warning}
|
||||
</Typography>
|
||||
)}
|
||||
{passwordStrength && (
|
||||
<Typography
|
||||
color={COLORS.BLACK}
|
||||
variant={TYPOGRAPHY.H7}
|
||||
className="form-field__password-strength"
|
||||
>
|
||||
{passwordStrength}
|
||||
</Typography>
|
||||
)}
|
||||
{passwordStrengthText && (
|
||||
<Typography
|
||||
color={COLORS.UI4}
|
||||
variant={TYPOGRAPHY.H8}
|
||||
className="form-field__password-strength-text"
|
||||
>
|
||||
{passwordStrengthText}
|
||||
</Typography>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
@ -192,6 +212,14 @@ FormField.propTypes = {
|
||||
* Set the placeholder text for the input field
|
||||
*/
|
||||
placeholder: PropTypes.string,
|
||||
/**
|
||||
* Show password strength according to the score
|
||||
*/
|
||||
passwordStrength: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||
/**
|
||||
* Show password strength description
|
||||
*/
|
||||
passwordStrengthText: PropTypes.string,
|
||||
};
|
||||
|
||||
FormField.defaultProps = {
|
||||
|
@ -9,6 +9,8 @@ const ZENDESK_URLS = {
|
||||
'https://metamask.zendesk.com/hc/en-us/articles/4403988839451',
|
||||
SECRET_RECOVERY_PHRASE:
|
||||
'https://metamask.zendesk.com/hc/en-us/articles/360060826432-What-is-a-Secret-Recovery-Phrase-and-how-to-keep-your-crypto-wallet-secure',
|
||||
PASSWORD_ARTICLE:
|
||||
'https://metamask.zendesk.com/hc/en-us/articles/4404722782107',
|
||||
};
|
||||
|
||||
export default ZENDESK_URLS;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import zxcvbn from 'zxcvbn';
|
||||
import { useNewMetricEvent } from '../../../hooks/useMetricEvent';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import Button from '../../../components/ui/button';
|
||||
@ -25,6 +26,7 @@ import {
|
||||
TwoStepProgressBar,
|
||||
twoStepStages,
|
||||
} from '../../../components/app/step-progress-bar';
|
||||
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
|
||||
|
||||
export default function CreatePassword({
|
||||
createNewAccount,
|
||||
@ -35,6 +37,8 @@ export default function CreatePassword({
|
||||
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);
|
||||
@ -57,19 +61,51 @@ export default function CreatePassword({
|
||||
return !passwordError && !confirmPasswordError;
|
||||
}, [password, confirmPassword, passwordError, confirmPasswordError]);
|
||||
|
||||
const handlePasswordChange = (passwordInput) => {
|
||||
let error = '';
|
||||
let confirmError = '';
|
||||
if (passwordInput && passwordInput.length < 8) {
|
||||
error = t('passwordNotLongEnough');
|
||||
const getPasswordStrengthLabel = (score, translation) => {
|
||||
if (score >= 4) {
|
||||
return {
|
||||
className: 'create-password__strong',
|
||||
text: translation('strong'),
|
||||
description: '',
|
||||
};
|
||||
} else if (score === 3) {
|
||||
return {
|
||||
className: 'create-password__average',
|
||||
text: translation('average'),
|
||||
description: t('passwordStrengthDescription'),
|
||||
};
|
||||
}
|
||||
return {
|
||||
className: 'create-password__weak',
|
||||
text: translation('weak'),
|
||||
description: t('passwordStrengthDescription'),
|
||||
};
|
||||
};
|
||||
|
||||
const handlePasswordChange = (passwordInput) => {
|
||||
let confirmError = '';
|
||||
const passwordEvaluation = zxcvbn(passwordInput);
|
||||
const passwordStrengthLabel = getPasswordStrengthLabel(
|
||||
passwordEvaluation.score,
|
||||
t,
|
||||
);
|
||||
const passwordStrengthDescription = passwordStrengthLabel.description;
|
||||
const passwordStrengthInput = t('passwordStrength', [
|
||||
<span
|
||||
key={passwordEvaluation.score}
|
||||
className={passwordStrengthLabel.className}
|
||||
>
|
||||
{passwordStrengthLabel.text}
|
||||
</span>,
|
||||
]);
|
||||
|
||||
if (confirmPassword && passwordInput !== confirmPassword) {
|
||||
confirmError = t('passwordsDontMatch');
|
||||
}
|
||||
|
||||
setPassword(passwordInput);
|
||||
setPasswordError(error);
|
||||
setPasswordStrength(passwordStrengthInput);
|
||||
setPasswordStrengthText(passwordStrengthDescription);
|
||||
setConfirmPasswordError(confirmError);
|
||||
};
|
||||
|
||||
@ -133,7 +169,8 @@ export default function CreatePassword({
|
||||
<FormField
|
||||
dataTestId="create-password-new"
|
||||
autoFocus
|
||||
error={passwordError}
|
||||
passwordStrength={passwordStrength}
|
||||
passwordStrengthText={passwordStrengthText}
|
||||
onChange={handlePasswordChange}
|
||||
password={!showPassword}
|
||||
titleText={t('newPassword')}
|
||||
@ -181,12 +218,12 @@ export default function CreatePassword({
|
||||
<a
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
key="create-password__link-text"
|
||||
href="https://metamask.io/terms.html"
|
||||
href={ZENDESK_URLS.PASSWORD_ARTICLE}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="create-password__link-text">
|
||||
{t('learnMore')}
|
||||
{t('learnMoreUpperCase')}
|
||||
</span>
|
||||
</a>,
|
||||
])}
|
||||
|
@ -1,4 +1,16 @@
|
||||
.create-password {
|
||||
&__weak {
|
||||
color: var(--error-1);
|
||||
}
|
||||
|
||||
&__average {
|
||||
color: var(--secondary-3);;
|
||||
}
|
||||
|
||||
&__strong {
|
||||
color: var(--success-3);
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -28349,3 +28349,8 @@ zwitch@^1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
|
||||
integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==
|
||||
|
||||
zxcvbn@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30"
|
||||
integrity sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=
|
||||
|
Loading…
Reference in New Issue
Block a user