1
0
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:
Alexander Tseung 2018-03-06 09:14:57 -08:00 committed by GitHub
parent 9734969e5d
commit 5f8a632fec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 133 additions and 95 deletions

View File

@ -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())

View File

@ -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;

View File

@ -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', [

View File

@ -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;