mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Fix seed phrase validation clearing form (#3417)
* Fix seed phrase validation clearing form * Make new ui import seed error feedback live, and allow newlines with and without carriage returns.
This commit is contained in:
parent
9734969e5d
commit
5f8a632fec
@ -1,13 +1,12 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import {connect} from 'react-redux'
|
import {connect} from 'react-redux'
|
||||||
import LoadingScreen from './loading-screen'
|
import classnames from 'classnames'
|
||||||
import {
|
import {
|
||||||
createNewVaultAndRestore,
|
createNewVaultAndRestore,
|
||||||
hideWarning,
|
hideWarning,
|
||||||
displayWarning,
|
displayWarning,
|
||||||
unMarkPasswordForgotten,
|
unMarkPasswordForgotten,
|
||||||
clearNotices,
|
|
||||||
} from '../../../../ui/app/actions'
|
} from '../../../../ui/app/actions'
|
||||||
|
|
||||||
class ImportSeedPhraseScreen extends Component {
|
class ImportSeedPhraseScreen extends Component {
|
||||||
@ -17,8 +16,8 @@ class ImportSeedPhraseScreen extends Component {
|
|||||||
next: PropTypes.func.isRequired,
|
next: PropTypes.func.isRequired,
|
||||||
createNewVaultAndRestore: PropTypes.func.isRequired,
|
createNewVaultAndRestore: PropTypes.func.isRequired,
|
||||||
hideWarning: PropTypes.func.isRequired,
|
hideWarning: PropTypes.func.isRequired,
|
||||||
isLoading: PropTypes.bool.isRequired,
|
|
||||||
displayWarning: PropTypes.func,
|
displayWarning: PropTypes.func,
|
||||||
|
leaveImportSeedScreenState: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -27,37 +26,59 @@ class ImportSeedPhraseScreen extends Component {
|
|||||||
confirmPassword: '',
|
confirmPassword: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseSeedPhrase = (seedPhrase) => {
|
||||||
|
return seedPhrase
|
||||||
|
.match(/\w+/g)
|
||||||
|
.join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = ({ seedPhrase, password, confirmPassword }) => {
|
||||||
|
const {
|
||||||
|
password: prevPassword,
|
||||||
|
confirmPassword: prevConfirmPassword,
|
||||||
|
} = this.state
|
||||||
|
const { displayWarning, hideWarning } = this.props
|
||||||
|
|
||||||
|
let warning = null
|
||||||
|
|
||||||
|
if (seedPhrase && this.parseSeedPhrase(seedPhrase).split(' ').length !== 12) {
|
||||||
|
warning = 'Seed Phrases are 12 words long'
|
||||||
|
} else if (password && password.length < 8) {
|
||||||
|
warning = 'Passwords require a mimimum length of 8'
|
||||||
|
} else if ((password || prevPassword) !== (confirmPassword || prevConfirmPassword)) {
|
||||||
|
warning = 'Confirmed password does not match'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warning) {
|
||||||
|
displayWarning(warning)
|
||||||
|
} else {
|
||||||
|
hideWarning()
|
||||||
|
}
|
||||||
|
|
||||||
|
seedPhrase && this.setState({ seedPhrase })
|
||||||
|
password && this.setState({ password })
|
||||||
|
confirmPassword && this.setState({ confirmPassword })
|
||||||
|
}
|
||||||
|
|
||||||
onClick = () => {
|
onClick = () => {
|
||||||
const { password, seedPhrase, confirmPassword } = this.state
|
const { password, seedPhrase } = this.state
|
||||||
const { createNewVaultAndRestore, next, displayWarning, leaveImportSeedScreenState } = this.props
|
const {
|
||||||
|
createNewVaultAndRestore,
|
||||||
|
next,
|
||||||
|
displayWarning,
|
||||||
|
leaveImportSeedScreenState,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
if (seedPhrase.split(' ').length !== 12) {
|
|
||||||
this.warning = 'Seed Phrases are 12 words long'
|
|
||||||
displayWarning(this.warning)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.length < 8) {
|
|
||||||
this.warning = 'Passwords require a mimimum length of 8'
|
|
||||||
displayWarning(this.warning)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
this.warning = 'Confirmed password does not match'
|
|
||||||
displayWarning(this.warning)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.warning = null
|
|
||||||
leaveImportSeedScreenState()
|
leaveImportSeedScreenState()
|
||||||
createNewVaultAndRestore(password, seedPhrase)
|
createNewVaultAndRestore(password, this.parseSeedPhrase(seedPhrase))
|
||||||
.then(next)
|
.then(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return this.props.isLoading
|
const { seedPhrase, password, confirmPassword } = this.state
|
||||||
? <LoadingScreen loadingMessage="Creating your new account" />
|
const { warning } = this.props
|
||||||
: (
|
const importDisabled = warning || !seedPhrase || !password || !confirmPassword
|
||||||
|
return (
|
||||||
<div className="import-account">
|
<div className="import-account">
|
||||||
<a
|
<a
|
||||||
className="import-account__back-button"
|
className="import-account__back-button"
|
||||||
@ -79,7 +100,8 @@ class ImportSeedPhraseScreen extends Component {
|
|||||||
<label className="import-account__input-label">Wallet Seed</label>
|
<label className="import-account__input-label">Wallet Seed</label>
|
||||||
<textarea
|
<textarea
|
||||||
className="import-account__secret-phrase"
|
className="import-account__secret-phrase"
|
||||||
onChange={e => this.setState({seedPhrase: e.target.value})}
|
onChange={e => this.onChange({seedPhrase: e.target.value})}
|
||||||
|
value={this.state.seedPhrase}
|
||||||
placeholder="Separate each word with a single space"
|
placeholder="Separate each word with a single space"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -94,21 +116,30 @@ class ImportSeedPhraseScreen extends Component {
|
|||||||
className="first-time-flow__input"
|
className="first-time-flow__input"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="New Password (min 8 characters)"
|
placeholder="New Password (min 8 characters)"
|
||||||
onChange={e => this.setState({password: e.target.value})}
|
onChange={e => this.onChange({password: e.target.value})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="import-account__input-wrapper">
|
<div className="import-account__input-wrapper">
|
||||||
<label className="import-account__input-label">Confirm Password</label>
|
<label
|
||||||
|
className="import-account__input-label"
|
||||||
|
className={classnames('import-account__input-label', {
|
||||||
|
'import-account__input-label__disabled': password.length < 8,
|
||||||
|
})}
|
||||||
|
>Confirm Password</label>
|
||||||
<input
|
<input
|
||||||
className="first-time-flow__input"
|
className={classnames('first-time-flow__input', {
|
||||||
|
'first-time-flow__input__disabled': password.length < 8,
|
||||||
|
})}
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Confirm Password"
|
placeholder="Confirm Password"
|
||||||
onChange={e => this.setState({confirmPassword: e.target.value})}
|
onChange={e => this.onChange({confirmPassword: e.target.value})}
|
||||||
|
disabled={password.length < 8}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="first-time-flow__button"
|
className="first-time-flow__button"
|
||||||
onClick={this.onClick}
|
onClick={() => !importDisabled && this.onClick()}
|
||||||
|
disabled={importDisabled}
|
||||||
>
|
>
|
||||||
Import
|
Import
|
||||||
</button>
|
</button>
|
||||||
@ -118,7 +149,7 @@ class ImportSeedPhraseScreen extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
({ appState: { isLoading, warning } }) => ({ isLoading, warning }),
|
({ appState: { warning } }) => ({ warning }),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
leaveImportSeedScreenState: () => {
|
leaveImportSeedScreenState: () => {
|
||||||
dispatch(unMarkPasswordForgotten())
|
dispatch(unMarkPasswordForgotten())
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
.first-time-flow {
|
.first-time-flow {
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
background-color: #FFF;
|
background-color: #fff;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
flex: 1 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alpha-warning {
|
.alpha-warning {
|
||||||
@ -45,12 +45,12 @@
|
|||||||
.buy-ether {
|
.buy-ether {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
margin: 67px 0 50px 146px;
|
margin: 67px 0 50px;
|
||||||
max-width: 35rem;
|
max-width: 35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-password {
|
.create-password {
|
||||||
margin: 67px 0 50px 0px;
|
margin: 67px 0 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.import-account {
|
.import-account {
|
||||||
@ -418,6 +418,10 @@ button.backup-phrase__confirm-seed-option:hover {
|
|||||||
line-height: 23px;
|
line-height: 23px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.import-account__input-label__disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.import-account__input {
|
.import-account__input {
|
||||||
width: 325px !important;
|
width: 325px !important;
|
||||||
}
|
}
|
||||||
@ -564,6 +568,10 @@ button.backup-phrase__confirm-seed-option:hover {
|
|||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.first-time-flow__input__disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.first-time-flow__input::placeholder {
|
.first-time-flow__input::placeholder {
|
||||||
color: #9B9B9B;
|
color: #9B9B9B;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
|
@ -288,10 +288,10 @@ App.prototype.renderAppBar = function () {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
// metamask name
|
// metamask name
|
||||||
|
h('.flex-row', [
|
||||||
h('h1', 'MetaMask'),
|
h('h1', 'MetaMask'),
|
||||||
|
|
||||||
h('div.beta-label', 'BETA'),
|
h('div.beta-label', 'BETA'),
|
||||||
|
]),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
h('div.header__right-actions', [
|
h('div.header__right-actions', [
|
||||||
|
@ -80,11 +80,10 @@
|
|||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 0.8rem;
|
font-size: .8rem;
|
||||||
padding-left: 9px;
|
|
||||||
color: $buttercup;
|
color: $buttercup;
|
||||||
align-self: flex-start;
|
margin-left: 5px;
|
||||||
margin-top: 10px;
|
line-height: initial;
|
||||||
|
|
||||||
@media screen and (max-width: 575px) {
|
@media screen and (max-width: 575px) {
|
||||||
display: none;
|
display: none;
|
||||||
|
Loading…
Reference in New Issue
Block a user