From 96643c222a74552d98218fe1f9fc81e493a1960f Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 31 Oct 2016 11:35:09 -0700 Subject: Implement seed word confirmation page. Remove logs. Move HD render files to ui/app. --- ui/app/keychains/hd/create-vault-complete.js | 73 +++++++++++ ui/app/keychains/hd/recover-seed/confirmation.js | 148 +++++++++++++++++++++++ ui/app/keychains/hd/restore-vault.js | 148 +++++++++++++++++++++++ 3 files changed, 369 insertions(+) create mode 100644 ui/app/keychains/hd/create-vault-complete.js create mode 100644 ui/app/keychains/hd/recover-seed/confirmation.js create mode 100644 ui/app/keychains/hd/restore-vault.js (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js new file mode 100644 index 000000000..7272ebdbd --- /dev/null +++ b/ui/app/keychains/hd/create-vault-complete.js @@ -0,0 +1,73 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const actions = require('../../actions') + +module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen) + +inherits(CreateVaultCompleteScreen, Component) +function CreateVaultCompleteScreen () { + Component.call(this) +} + +function mapStateToProps (state) { + return { + seed: state.appState.currentView.seedWords, + cachedSeed: state.metamask.seedWords, + } +} + +CreateVaultCompleteScreen.prototype.render = function () { + var state = this.props + var seed = state.seed || state.cachedSeed + + return ( + + h('.initialize-screen.flex-column.flex-center.flex-grow', [ + + // // subtitle and nav + // h('.section-title.flex-row.flex-center', [ + // h('h2.page-subtitle', 'Vault Created'), + // ]), + + h('h3.flex-center.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + marginTop: 36, + marginBottom: 8, + width: '100%', + fontSize: '20px', + padding: 6, + }, + }, [ + 'Vault Created', + ]), + + h('span.error', { // Error for the right red + style: { + padding: '12px 20px 0px 20px', + textAlign: 'center', + }, + }, 'These 12 words can restore all of your MetaMask accounts for this vault.\nSave them somewhere safe and secret.'), + + h('textarea.twelve-word-phrase', { + readOnly: true, + value: seed, + }), + + h('button.primary', { + onClick: () => this.confirmSeedWords(), + style: { + margin: '24px', + fontSize: '0.9em', + }, + }, 'I\'ve copied it somewhere safe'), + ]) + ) +} + +CreateVaultCompleteScreen.prototype.confirmSeedWords = function () { + this.props.dispatch(actions.confirmSeedWords()) +} diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js new file mode 100644 index 000000000..55b18025f --- /dev/null +++ b/ui/app/keychains/hd/recover-seed/confirmation.js @@ -0,0 +1,148 @@ +const inherits = require('util').inherits + +const Component = require('react').Component +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const actions = require('../actions') + +module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin) + +inherits(RevealSeedConfirmatoin, Component) +function RevealSeedConfirmatoin () { + Component.call(this) +} + +function mapStateToProps (state) { + return { + warning: state.appState.warning, + } +} + +RevealSeedConfirmatoin.prototype.confirmationPhrase = 'I understand' + +RevealSeedConfirmatoin.prototype.render = function () { + const props = this.props + const state = this.state + + return ( + + h('.initialize-screen.flex-column.flex-center.flex-grow', [ + + h('h3.flex-center.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + marginBottom: 24, + width: '100%', + fontSize: '20px', + padding: 6, + }, + }, [ + 'Reveal Seed Words', + ]), + + h('.div', { + style: { + display: 'flex', + flexDirection: 'column', + padding: '20px', + justifyContent: 'center', + }, + }, [ + + h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'), + + // confirmation + h('input.large-input.letter-spacey', { + type: 'password', + id: 'password-box', + placeholder: 'Enter your password to confirm', + onKeyPress: this.checkConfirmation.bind(this), + style: { + width: 260, + marginTop: '12px', + }, + }), + + h(`h4${state && state.confirmationWrong ? '.error' : ''}`, { + style: { + marginTop: '12px', + }, + }, 'Enter the phrase "I understand" to proceed.'), + + // confirm confirmation + h('input.large-input.letter-spacey', { + type: 'text', + id: 'confirm-box', + placeholder: this.confirmationPhrase, + onKeyPress: this.checkConfirmation.bind(this), + style: { + width: 260, + marginTop: 16, + }, + }), + + h('.flex-row.flex-space-between', { + style: { + marginTop: 30, + width: '50%', + }, + }, [ +// cancel + h('button.primary', { + onClick: this.goHome.bind(this), + }, 'CANCEL'), + + // submit + h('button.primary', { + onClick: this.revealSeedWords.bind(this), + }, 'OK'), + + ]), + + (props.warning) && ( + h('span.error', { + style: { + margin: '20px', + }, + }, props.warning.split('-')) + ), + + props.inProgress && ( + h('span.in-progress-notification', 'Generating Seed...') + ), + ]), + ]) + ) +} + +RevealSeedConfirmatoin.prototype.componentDidMount = function () { + document.getElementById('password-box').focus() +} + +RevealSeedConfirmatoin.prototype.goHome = function () { + this.props.dispatch(actions.showConfigPage(false)) +} + +// create vault + +RevealSeedConfirmatoin.prototype.checkConfirmation = function (event) { + if (event.key === 'Enter') { + event.preventDefault() + this.revealSeedWords() + } +} + +RevealSeedConfirmatoin.prototype.revealSeedWords = function () { + this.setState({ confirmationWrong: false }) + + const confirmBox = document.getElementById('confirm-box') + const confirmation = confirmBox.value + if (confirmation !== this.confirmationPhrase) { + confirmBox.value = '' + return this.setState({ confirmationWrong: true }) + } + + var password = document.getElementById('password-box').value + this.props.dispatch(actions.requestRevealSeed(password)) +} diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js new file mode 100644 index 000000000..4c1f21008 --- /dev/null +++ b/ui/app/keychains/hd/restore-vault.js @@ -0,0 +1,148 @@ +const inherits = require('util').inherits +const PersistentForm = require('../../lib/persistent-form') +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const actions = require('../actions') + +module.exports = connect(mapStateToProps)(RestoreVaultScreen) + +inherits(RestoreVaultScreen, PersistentForm) +function RestoreVaultScreen () { + PersistentForm.call(this) +} + +function mapStateToProps (state) { + return { + warning: state.appState.warning, + } +} + +RestoreVaultScreen.prototype.render = function () { + var state = this.props + this.persistentFormParentId = 'restore-vault-form' + + return ( + + h('.initialize-screen.flex-column.flex-center.flex-grow', [ + + h('h3.flex-center.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + marginBottom: 24, + width: '100%', + fontSize: '20px', + padding: 6, + }, + }, [ + 'Restore Vault', + ]), + + // wallet seed entry + h('h3', 'Wallet Seed'), + h('textarea.twelve-word-phrase.letter-spacey', { + dataset: { + persistentFormId: 'wallet-seed', + }, + placeholder: 'Enter your secret twelve word phrase here to restore your vault.', + }), + + // password + h('input.large-input.letter-spacey', { + type: 'password', + id: 'password-box', + placeholder: 'New Password (min 8 chars)', + dataset: { + persistentFormId: 'password', + }, + style: { + width: 260, + marginTop: 12, + }, + }), + + // confirm password + h('input.large-input.letter-spacey', { + type: 'password', + id: 'password-box-confirm', + placeholder: 'Confirm Password', + onKeyPress: this.onMaybeCreate.bind(this), + dataset: { + persistentFormId: 'password-confirmation', + }, + style: { + width: 260, + marginTop: 16, + }, + }), + + (state.warning) && ( + h('span.error.in-progress-notification', state.warning) + ), + + // submit + + h('.flex-row.flex-space-between', { + style: { + marginTop: 30, + width: '50%', + }, + }, [ + + // cancel + h('button.primary', { + onClick: this.showInitializeMenu.bind(this), + }, 'CANCEL'), + + // submit + h('button.primary', { + onClick: this.restoreVault.bind(this), + }, 'OK'), + + ]), + + ]) + + ) +} + +RestoreVaultScreen.prototype.showInitializeMenu = function () { + this.props.dispatch(actions.showInitializeMenu()) +} + +RestoreVaultScreen.prototype.onMaybeCreate = function (event) { + if (event.key === 'Enter') { + this.restoreVault() + } +} + +RestoreVaultScreen.prototype.restoreVault = function () { + // check password + var passwordBox = document.getElementById('password-box') + var password = passwordBox.value + var passwordConfirmBox = document.getElementById('password-box-confirm') + var passwordConfirm = passwordConfirmBox.value + if (password.length < 8) { + this.warning = 'Password not long enough' + + this.props.dispatch(actions.displayWarning(this.warning)) + return + } + if (password !== passwordConfirm) { + this.warning = 'Passwords don\'t match' + this.props.dispatch(actions.displayWarning(this.warning)) + return + } + // check seed + var seedBox = document.querySelector('textarea.twelve-word-phrase') + var seed = seedBox.value.trim() + if (seed.split(' ').length !== 12) { + this.warning = 'seed phrases are 12 words long' + this.props.dispatch(actions.displayWarning(this.warning)) + return + } + // submit + this.warning = null + this.props.dispatch(actions.displayWarning(this.warning)) + this.props.dispatch(actions.recoverFromSeed(password, seed)) +} -- cgit v1.2.3 From db356a181a3fde4ad528c699f6da517053171866 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 1 Nov 2016 11:25:38 -0700 Subject: Made progress on parity for MultiVault - Deleted some unused items - Renamed files and paths to match with new locations. - Modified keyring controller logic to separate concerns. - Fix account naming issues. - Enable creation of new vault with default HD keyring. - Formatting issues. --- ui/app/keychains/hd/recover-seed/confirmation.js | 4 ++-- ui/app/keychains/hd/restore-vault.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js index 55b18025f..83dbc270f 100644 --- a/ui/app/keychains/hd/recover-seed/confirmation.js +++ b/ui/app/keychains/hd/recover-seed/confirmation.js @@ -3,7 +3,7 @@ const inherits = require('util').inherits const Component = require('react').Component const connect = require('react-redux').connect const h = require('react-hyperscript') -const actions = require('../actions') +const actions = require('../../../actions') module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin) @@ -68,7 +68,7 @@ RevealSeedConfirmatoin.prototype.render = function () { style: { marginTop: '12px', }, - }, 'Enter the phrase "I understand" to proceed.'), + }, `Enter the phrase "${this.confirmationPhrase}" to proceed.`), // confirm confirmation h('input.large-input.letter-spacey', { diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 4c1f21008..15690a159 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -1,8 +1,8 @@ const inherits = require('util').inherits -const PersistentForm = require('../../lib/persistent-form') +const PersistentForm = require('../../../lib/persistent-form') const connect = require('react-redux').connect const h = require('react-hyperscript') -const actions = require('../actions') +const actions = require('../../actions') module.exports = connect(mapStateToProps)(RestoreVaultScreen) @@ -96,7 +96,7 @@ RestoreVaultScreen.prototype.render = function () { // submit h('button.primary', { - onClick: this.restoreVault.bind(this), + onClick: this.createNewVaultAndRestore.bind(this), }, 'OK'), ]), @@ -116,7 +116,7 @@ RestoreVaultScreen.prototype.onMaybeCreate = function (event) { } } -RestoreVaultScreen.prototype.restoreVault = function () { +RestoreVaultScreen.prototype.createNewVaultAndRestore = function () { // check password var passwordBox = document.getElementById('password-box') var password = passwordBox.value @@ -144,5 +144,5 @@ RestoreVaultScreen.prototype.restoreVault = function () { // submit this.warning = null this.props.dispatch(actions.displayWarning(this.warning)) - this.props.dispatch(actions.recoverFromSeed(password, seed)) + this.props.dispatch(actions.createNewVaultAndRestore(password, seed)) } -- cgit v1.2.3 From 498b30bddcfa16f587a9f62b74a5d9fceb04cb07 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 1 Nov 2016 11:51:51 -0700 Subject: Fix seed phrase restore --- ui/app/keychains/hd/restore-vault.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 15690a159..3fa25a2eb 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -66,7 +66,7 @@ RestoreVaultScreen.prototype.render = function () { type: 'password', id: 'password-box-confirm', placeholder: 'Confirm Password', - onKeyPress: this.onMaybeCreate.bind(this), + onKeyPress: this.createOnEnter.bind(this), dataset: { persistentFormId: 'password-confirmation', }, @@ -110,9 +110,9 @@ RestoreVaultScreen.prototype.showInitializeMenu = function () { this.props.dispatch(actions.showInitializeMenu()) } -RestoreVaultScreen.prototype.onMaybeCreate = function (event) { +RestoreVaultScreen.prototype.createOnEnter = function (event) { if (event.key === 'Enter') { - this.restoreVault() + this.createNewVaultAndRestore() } } -- cgit v1.2.3 From 3828edf6a4458a59161c445587f581c14baf50fe Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Fri, 11 Nov 2016 10:54:15 -0800 Subject: Typo fix. --- ui/app/keychains/hd/recover-seed/confirmation.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js index 83dbc270f..56ac461ea 100644 --- a/ui/app/keychains/hd/recover-seed/confirmation.js +++ b/ui/app/keychains/hd/recover-seed/confirmation.js @@ -5,10 +5,10 @@ const connect = require('react-redux').connect const h = require('react-hyperscript') const actions = require('../../../actions') -module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin) +module.exports = connect(mapStateToProps)(RevealSeedConfirmation) -inherits(RevealSeedConfirmatoin, Component) -function RevealSeedConfirmatoin () { +inherits(RevealSeedConfirmation, Component) +function RevealSeedConfirmation () { Component.call(this) } @@ -18,9 +18,9 @@ function mapStateToProps (state) { } } -RevealSeedConfirmatoin.prototype.confirmationPhrase = 'I understand' +RevealSeedConfirmation.prototype.confirmationPhrase = 'I understand' -RevealSeedConfirmatoin.prototype.render = function () { +RevealSeedConfirmation.prototype.render = function () { const props = this.props const state = this.state @@ -116,24 +116,24 @@ RevealSeedConfirmatoin.prototype.render = function () { ) } -RevealSeedConfirmatoin.prototype.componentDidMount = function () { +RevealSeedConfirmation.prototype.componentDidMount = function () { document.getElementById('password-box').focus() } -RevealSeedConfirmatoin.prototype.goHome = function () { +RevealSeedConfirmation.prototype.goHome = function () { this.props.dispatch(actions.showConfigPage(false)) } // create vault -RevealSeedConfirmatoin.prototype.checkConfirmation = function (event) { +RevealSeedConfirmation.prototype.checkConfirmation = function (event) { if (event.key === 'Enter') { event.preventDefault() this.revealSeedWords() } } -RevealSeedConfirmatoin.prototype.revealSeedWords = function () { +RevealSeedConfirmation.prototype.revealSeedWords = function () { this.setState({ confirmationWrong: false }) const confirmBox = document.getElementById('confirm-box') -- cgit v1.2.3 From b8ee336f0dd1c0a7d5990ddef22e2d17e09bb1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Iv=C3=A1n=20Cuende?= Date: Tue, 13 Dec 2016 23:46:50 -0800 Subject: Better buttons --- ui/app/keychains/hd/create-vault-complete.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js index 7272ebdbd..ae745430c 100644 --- a/ui/app/keychains/hd/create-vault-complete.js +++ b/ui/app/keychains/hd/create-vault-complete.js @@ -35,7 +35,7 @@ CreateVaultCompleteScreen.prototype.render = function () { style: { background: '#EBEBEB', color: '#AEAEAE', - marginTop: 36, + marginTop: 0, marginBottom: 8, width: '100%', fontSize: '20px', @@ -60,8 +60,10 @@ CreateVaultCompleteScreen.prototype.render = function () { h('button.primary', { onClick: () => this.confirmSeedWords(), style: { - margin: '24px', - fontSize: '0.9em', + position: 'absolute', + left: 0, + bottom: 0, + width: '100%', }, }, 'I\'ve copied it somewhere safe'), ]) -- cgit v1.2.3 From 6d13ef691f4162caad6b8742a21d0b75f8baccca Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 16 Dec 2016 10:04:57 -0800 Subject: Revert "Interface enhancements" --- ui/app/keychains/hd/create-vault-complete.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js index ae745430c..7272ebdbd 100644 --- a/ui/app/keychains/hd/create-vault-complete.js +++ b/ui/app/keychains/hd/create-vault-complete.js @@ -35,7 +35,7 @@ CreateVaultCompleteScreen.prototype.render = function () { style: { background: '#EBEBEB', color: '#AEAEAE', - marginTop: 0, + marginTop: 36, marginBottom: 8, width: '100%', fontSize: '20px', @@ -60,10 +60,8 @@ CreateVaultCompleteScreen.prototype.render = function () { h('button.primary', { onClick: () => this.confirmSeedWords(), style: { - position: 'absolute', - left: 0, - bottom: 0, - width: '100%', + margin: '24px', + fontSize: '0.9em', }, }, 'I\'ve copied it somewhere safe'), ]) -- cgit v1.2.3 From 20c043a4c280891b3b1322a06887e6515a8d94fa Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 19 Dec 2016 14:54:24 -0800 Subject: Redirect to seed word screen for forgotten passwords. --- ui/app/keychains/hd/restore-vault.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ui/app/keychains') diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js index 3fa25a2eb..06e51d9b3 100644 --- a/ui/app/keychains/hd/restore-vault.js +++ b/ui/app/keychains/hd/restore-vault.js @@ -14,6 +14,7 @@ function RestoreVaultScreen () { function mapStateToProps (state) { return { warning: state.appState.warning, + forgottenPassword: state.appState.forgottenPassword, } } @@ -100,14 +101,17 @@ RestoreVaultScreen.prototype.render = function () { }, 'OK'), ]), - ]) ) } RestoreVaultScreen.prototype.showInitializeMenu = function () { - this.props.dispatch(actions.showInitializeMenu()) + if (this.props.forgottenPassword) { + this.props.dispatch(actions.backToUnlockView()) + } else { + this.props.dispatch(actions.showInitializeMenu()) + } } RestoreVaultScreen.prototype.createOnEnter = function (event) { -- cgit v1.2.3