From d9ea2df6c2a2cabedead09f90c3c9bb7b4c37dd1 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 4 Dec 2017 14:29:52 -0500 Subject: Add route for Mascara confirm seed --- mascara/src/app/first-time/backup-phrase-screen.js | 269 --------------------- mascara/src/app/first-time/confirm-seed-screen.js | 133 ++++++++++ mascara/src/app/first-time/seed-screen.js | 158 ++++++++++++ 3 files changed, 291 insertions(+), 269 deletions(-) delete mode 100644 mascara/src/app/first-time/backup-phrase-screen.js create mode 100644 mascara/src/app/first-time/confirm-seed-screen.js create mode 100644 mascara/src/app/first-time/seed-screen.js (limited to 'mascara/src/app/first-time') diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/backup-phrase-screen.js deleted file mode 100644 index 266a82cdb..000000000 --- a/mascara/src/app/first-time/backup-phrase-screen.js +++ /dev/null @@ -1,269 +0,0 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import {connect} from 'react-redux' -import classnames from 'classnames' -import shuffle from 'lodash.shuffle' -import {compose, onlyUpdateForPropTypes} from 'recompose' -import Identicon from '../../../../ui/app/components/identicon' -import {confirmSeedWords} from '../../../../ui/app/actions' -import Breadcrumbs from './breadcrumbs' -import LoadingScreen from './loading-screen' -import { DEFAULT_ROUTE } from '../../../../ui/app/routes' - -const LockIcon = props => ( - - - - - -) - -class BackupPhraseScreen extends Component { - static propTypes = { - isLoading: PropTypes.bool.isRequired, - address: PropTypes.string.isRequired, - seedWords: PropTypes.string, - confirmSeedWords: PropTypes.func.isRequired, - history: PropTypes.object, - }; - - static defaultProps = { - seedWords: '', - } - - static PAGE = { - SECRET: 'secret', - CONFIRM: 'confirm', - } - - constructor (props) { - const {seedWords} = props - super(props) - this.state = { - isShowingSecret: false, - page: BackupPhraseScreen.PAGE.SECRET, - selectedSeeds: [], - shuffledSeeds: seedWords && shuffle(seedWords.split(' ')), - } - } - - componentWillMount () { - const { seedWords, history } = this.props - if (!seedWords) { - history.push(DEFAULT_ROUTE) - } - } - - renderSecretWordsContainer () { - const { isShowingSecret } = this.state - - return ( -
-
- {this.props.seedWords} -
- {!isShowingSecret && ( -
- - -
- )} -
- ) - } - - renderSecretScreen () { - const { isShowingSecret } = this.state - - return ( -
-
-
Secret Backup Phrase
-
- Your secret backup phrase makes it easy to back up and restore your account. -
-
- WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever. -
- {this.renderSecretWordsContainer()} - - -
-
-
Tips:
-
- Store this phrase in a password manager like 1password. -
-
- Write this phrase on a piece of paper and store in a secure location. If you want even more security, write it down on multiple pieces of paper and store each in 2 - 3 different locations. -
-
- Memorize this phrase. -
-
-
- ) - } - - renderConfirmationScreen () { - const { seedWords, confirmSeedWords, history } = this.props - const { selectedSeeds, shuffledSeeds } = this.state - const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ') - - return ( -
-
-
Confirm your Secret Backup Phrase
-
- Please select each phrase in order to make sure it is correct. -
-
- {selectedSeeds.map(([_, word], i) => ( - - ))} -
-
- {shuffledSeeds.map((word, i) => { - const isSelected = selectedSeeds - .filter(([index, seed]) => seed === word && index === i) - .length - - return ( - - ) - })} -
- -
-
- ) - } - - renderBack () { - return this.state.page === BackupPhraseScreen.PAGE.CONFIRM - ? ( - { - e.preventDefault() - this.setState({ - page: BackupPhraseScreen.PAGE.SECRET, - }) - }} - href="#" - > - {`< Back`} - - ) - : null - } - - renderContent () { - switch (this.state.page) { - case BackupPhraseScreen.PAGE.CONFIRM: - return this.renderConfirmationScreen() - case BackupPhraseScreen.PAGE.SECRET: - default: - return this.renderSecretScreen() - } - } - - render () { - return ( -
- { - this.props.isLoading - ? - : ( -
- {this.renderBack()} - - {this.renderContent()} -
- ) - } -
- ) - } -} - -export default compose( - onlyUpdateForPropTypes, - connect( - ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({ - seedWords, - isLoading, - address: selectedAddress, - }), - dispatch => ({ - confirmSeedWords: () => dispatch(confirmSeedWords()), - }) - ) -)(BackupPhraseScreen) diff --git a/mascara/src/app/first-time/confirm-seed-screen.js b/mascara/src/app/first-time/confirm-seed-screen.js new file mode 100644 index 000000000..6b730a2f8 --- /dev/null +++ b/mascara/src/app/first-time/confirm-seed-screen.js @@ -0,0 +1,133 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' +import classnames from 'classnames' +import shuffle from 'lodash.shuffle' +import { compose, onlyUpdateForPropTypes } from 'recompose' +import Identicon from '../../../../ui/app/components/identicon' +import { confirmSeedWords } from '../../../../ui/app/actions' +import Breadcrumbs from './breadcrumbs' +import LoadingScreen from './loading-screen' +import { DEFAULT_ROUTE } from '../../../../ui/app/routes' + +class ConfirmSeedScreen extends Component { + static propTypes = { + isLoading: PropTypes.bool.isRequired, + address: PropTypes.string.isRequired, + seedWords: PropTypes.string, + confirmSeedWords: PropTypes.func.isRequired, + history: PropTypes.object, + }; + + static defaultProps = { + seedWords: '', + } + + constructor (props) { + super(props) + const { seedWords } = props + this.state = { + selectedSeeds: [], + shuffledSeeds: seedWords && shuffle(seedWords.split(' ')), + } + } + + componentWillMount () { + const { seedWords, history } = this.props + if (!seedWords) { + history.push(DEFAULT_ROUTE) + } + } + + render () { + const { seedWords, confirmSeedWords, history } = this.props + const { selectedSeeds, shuffledSeeds } = this.state + const isValid = seedWords === selectedSeeds.map(([_, seed]) => seed).join(' ') + + return ( +
+ { + this.props.isLoading + ? + : ( +
+ +
+
+
+ Confirm your Secret Backup Phrase +
+
+ Please select each phrase in order to make sure it is correct. +
+
+ {selectedSeeds.map(([_, word], i) => ( + + ))} +
+
+ {shuffledSeeds.map((word, i) => { + const isSelected = selectedSeeds + .filter(([index, seed]) => seed === word && index === i) + .length + + return ( + + ) + })} +
+ +
+
+ +
+ ) + } +
+ ) + } +} + +export default compose( + onlyUpdateForPropTypes, + connect( + ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({ + seedWords, + isLoading, + address: selectedAddress, + }), + dispatch => ({ + confirmSeedWords: () => dispatch(confirmSeedWords()), + }) + ) +)(ConfirmSeedScreen) diff --git a/mascara/src/app/first-time/seed-screen.js b/mascara/src/app/first-time/seed-screen.js new file mode 100644 index 000000000..dc1da851c --- /dev/null +++ b/mascara/src/app/first-time/seed-screen.js @@ -0,0 +1,158 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' +import classnames from 'classnames' +import { compose, onlyUpdateForPropTypes } from 'recompose' +import Identicon from '../../../../ui/app/components/identicon' +import Breadcrumbs from './breadcrumbs' +import LoadingScreen from './loading-screen' +import { DEFAULT_ROUTE, CONFIRM_SEED_ROUTE } from '../../../../ui/app/routes' + +const LockIcon = props => ( + + + + + +) + +class BackupPhraseScreen extends Component { + static propTypes = { + isLoading: PropTypes.bool.isRequired, + address: PropTypes.string.isRequired, + seedWords: PropTypes.string, + history: PropTypes.object, + }; + + static defaultProps = { + seedWords: '', + } + + constructor (props) { + super(props) + this.state = { + isShowingSecret: false, + } + } + + componentWillMount () { + const { seedWords, history } = this.props + if (!seedWords) { + history.push(DEFAULT_ROUTE) + } + } + + renderSecretWordsContainer () { + const { isShowingSecret } = this.state + + return ( +
+
+ {this.props.seedWords} +
+ {!isShowingSecret && ( +
+ + +
+ )} +
+ ) + } + + renderSecretScreen () { + const { isShowingSecret } = this.state + const { history } = this.props + + return ( +
+
+
Secret Backup Phrase
+
+ Your secret backup phrase makes it easy to back up and restore your account. +
+
+ WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever. +
+ {this.renderSecretWordsContainer()} + + +
+
+
Tips:
+
+ Store this phrase in a password manager like 1password. +
+
+ Write this phrase on a piece of paper and store in a secure location. If you want even more security, write it down on multiple pieces of paper and store each in 2 - 3 different locations. +
+
+ Memorize this phrase. +
+
+
+ ) + } + + render () { + return ( +
+ { + this.props.isLoading + ? + : ( +
+ + {this.renderSecretScreen()} +
+ ) + } +
+ ) + } +} + +export default compose( + onlyUpdateForPropTypes, + connect( + ({ metamask: { selectedAddress, seedWords }, appState: { isLoading } }) => ({ + seedWords, + isLoading, + address: selectedAddress, + }) + ) +)(BackupPhraseScreen) -- cgit