Merge pull request #83 from poanetwork/change-password

(Feature) Changing of password
This commit is contained in:
Franco Victorio 2018-08-21 16:02:06 -03:00 committed by GitHub
commit 458fc9fc38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 223 additions and 15 deletions

View File

@ -3,6 +3,10 @@
## Current Master
- [#84](https://github.com/poanetwork/metamask-extension/pull/84): (Fix) Change green color
- [#83](https://github.com/poanetwork/metamask-extension/pull/83): (Feature) Changing of password
- [#81](https://github.com/poanetwork/metamask-extension/pull/81): (Feature) Deanonymize private network
- [#80](https://github.com/poanetwork/metamask-extension/pull/80): (Feature) Remove imported account
- [#78](https://github.com/poanetwork/metamask-extension/pull/78): (Fix) Link to POA explorer for POA networks
## 4.8.4 Thu Aug 09 2018

View File

@ -1,4 +1,4 @@
const KeyringController = require('eth-keyring-controller')
const KeyringController = require('eth-keychain-controller')
const log = require('loglevel')
const seedPhraseVerifier = {

View File

@ -19,7 +19,7 @@ const createOriginMiddleware = require('./lib/createOriginMiddleware')
const createLoggerMiddleware = require('./lib/createLoggerMiddleware')
const createProviderMiddleware = require('./lib/createProviderMiddleware')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
const KeyringController = require('eth-keyring-controller')
const KeyringController = require('eth-keychain-controller')
const NetworkController = require('./controllers/network')
const PreferencesController = require('./controllers/preferences')
const CurrencyController = require('./controllers/currency')
@ -370,6 +370,7 @@ module.exports = class MetamaskController extends EventEmitter {
verifySeedPhrase: nodeify(this.verifySeedPhrase, this),
clearSeedWordCache: this.clearSeedWordCache.bind(this),
resetAccount: nodeify(this.resetAccount, this),
changePassword: nodeify(this.changePassword, this),
removeAccount: nodeify(this.removeAccount, this),
importAccountWithStrategy: nodeify(this.importAccountWithStrategy, this),
@ -770,6 +771,10 @@ module.exports = class MetamaskController extends EventEmitter {
return selectedAddress
}
async changePassword (oldPassword, newPassword) {
await this.keyringController.changePassword(oldPassword, newPassword)
}
/**
* Removes an account from state / storage.
*

View File

@ -10,7 +10,7 @@ which we dont have access to at the time of this writing.
const ObservableStore = require('obs-store')
const ConfigManager = require('../../app/scripts/lib/config-manager')
const IdentityStoreMigrator = require('../../app/scripts/lib/idStore-migrator')
const KeyringController = require('eth-keyring-controller')
const KeyringController = require('eth-keychain-controller')
const password = 'obviously not correct'

View File

@ -37,6 +37,7 @@ const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
const DeleteRpc = require('./components/delete-rpc')
const DeleteImportedAccount = require('./components/delete-imported-account')
const ConfirmChangePassword = require('./components/confirm-change-password')
const ethNetProps = require('eth-net-props')
module.exports = connect(mapStateToProps)(App)
@ -656,6 +657,9 @@ App.prototype.renderPrimary = function () {
case 'delete-imported-account':
log.debug('rendering delete imported account confirmation screen')
return h(DeleteImportedAccount, {key: 'delete-imported-account'})
case 'confirm-change-password':
log.debug('rendering confirm password changing screen')
return h(ConfirmChangePassword, {key: 'confirm-change-password'})
default:
log.debug('rendering default, account detail screen')
return h(AccountDetailScreen, {key: 'account-detail'})

View File

@ -0,0 +1,147 @@
const inherits = require('util').inherits
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('../../../ui/app/actions')
module.exports = connect(mapStateToProps)(ConfirmChangePassword)
function mapStateToProps (state) {
return {
metamask: state.metamask,
warning: state.appState.warning,
}
}
inherits(ConfirmChangePassword, Component)
function ConfirmChangePassword () {
Component.call(this)
}
ConfirmChangePassword.prototype.render = function () {
const state = this.props
const passwordInputAdditionalStyle = {
width: '100%',
marginTop: 10,
marginBottom: 20,
}
return h('.flex-column.flex-grow', {
style: {
overflowX: 'auto',
overflowY: 'hidden',
},
}, [
// subtitle and nav
h('.section-title.flex-row.flex-center', [
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
onClick: () => {
this.props.dispatch(actions.showConfigPage())
},
style: {
position: 'absolute',
left: '30px',
},
}),
h('h2.page-subtitle', 'Change Password'),
]),
h('div', {
style: {
margin: '0 30px',
},
}, [
h('.error', {
style: {
display: state.warning ? 'block' : 'none',
},
}, state.warning),
h('span', 'Old password'),
h('input.large-input', {
type: 'password',
id: 'old-password-box',
ref: 'OldPasswordBox',
style: passwordInputAdditionalStyle,
}),
h('span', 'New password'),
h('input.large-input', {
type: 'password',
id: 'new-password-box',
ref: 'NewPasswordBox',
style: passwordInputAdditionalStyle,
}),
h('span', 'Confirm new password'),
h('input.large-input', {
type: 'password',
id: 'password-box-confirm',
ref: 'PasswordBoxConfirm',
style: passwordInputAdditionalStyle,
onKeyPress: this.createOnEnter.bind(this),
}),
]),
h('p.confirm-label', {
style: {
textAlign: 'center',
margin: '0px 30px 20px ',
},
},
`Are you sure you want to change the password for unlocking of your wallet?`),
h('.flex-row.flex-right', {
style: {
marginRight: '30px',
},
}, [
h('button.btn-violet',
{
style: {
marginRight: '10px',
},
onClick: () => {
this.props.dispatch(actions.showConfigPage())
},
},
'No'),
h('button',
{
onClick: () => {
this.ChangePassword()
},
},
'Yes'),
]),
])
}
ConfirmChangePassword.prototype.createOnEnter = function (event) {
if (event.key === 'Enter') {
this.ChangePassword()
}
}
ConfirmChangePassword.prototype.ChangePassword = function () {
const oldPasswordBox = this.refs.OldPasswordBox
const oldPassword = oldPasswordBox.value
const newPasswordBox = this.refs.NewPasswordBox
const newPassword = newPasswordBox.value
const newPasswordConfirmBox = this.refs.PasswordBoxConfirm
const newPasswordConfirm = newPasswordConfirmBox.value
if (newPassword.length < 8) {
this.warning = 'Password not long enough'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
if (newPassword !== newPasswordConfirm) {
this.warning = 'Passwords don\'t match'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
if (newPassword === oldPassword) {
this.warning = 'New password should differ from the current one'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
this.props.dispatch(actions.changePassword(oldPassword, newPassword))
.then(() => {
this.props.dispatch(actions.showConfigPage())
})
}

View File

@ -192,10 +192,6 @@ ConfigScreen.prototype.render = function () {
},
}, [
'Resetting is for developer use only. ',
h('a', {
href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account',
target: '_blank',
}, 'Read more.'),
]),
h('br'),
@ -208,8 +204,23 @@ ConfigScreen.prototype.render = function () {
state.dispatch(actions.resetAccount())
},
}, 'Reset Account'),
]),
h('hr.horizontal-line', {
style: {
marginTop: '20px',
},
}),
h('button', {
style: {
alignSelf: 'center',
},
onClick (event) {
event.preventDefault()
state.dispatch(actions.confirmChangePassword())
},
}, 'Change password'),
]),
]),
]),
])

8
package-lock.json generated
View File

@ -8574,10 +8574,10 @@
}
}
},
"eth-keyring-controller": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eth-keyring-controller/-/eth-keyring-controller-4.0.0.tgz",
"integrity": "sha512-D3Uj0b97vzEl/zXvrwYjFUYsz5gB4tnl/iMWqOm8jsvaREuHHbxRkm3iU/LG4fT8NGwS+fG8sLRPNBPu2/wRsA==",
"eth-keychain-controller": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/eth-keychain-controller/-/eth-keychain-controller-4.0.1.tgz",
"integrity": "sha512-4SR3+JxSrlCjyM6FfAlH73vr9zZ3n1nWuspAlF0B40fDDipjPouc+KqxKeqXHgQoAYm3Rub2OUVUfj9V0KqiBA==",
"dev": true,
"requires": {
"bip39": "^2.4.0",

View File

@ -245,7 +245,7 @@
"eslint-plugin-mocha": "^5.0.0",
"eslint-plugin-react": "^7.4.0",
"eth-json-rpc-middleware": "^1.6.0",
"eth-keyring-controller": "^4.0.0",
"eth-keychain-controller": "^4.0.1",
"file-loader": "^1.1.11",
"fs-promise": "^2.0.3",
"ganache-cli": "^6.1.0",

View File

@ -6,7 +6,7 @@ const {
KOVAN_CODE,
} = require('../../../../../app/scripts/controllers/network/enums')
const KeyringController = require('eth-keyring-controller')
const KeyringController = require('eth-keychain-controller')
describe('Recipient Blacklist Checker', function () {

View File

@ -1,6 +1,6 @@
const assert = require('assert')
const clone = require('clone')
const KeyringController = require('eth-keyring-controller')
const KeyringController = require('eth-keychain-controller')
const firstTimeState = require('../../../app/scripts/first-time-state')
const seedPhraseVerifier = require('../../../app/scripts/lib/seed-phrase-verifier')
const mockEncryptor = require('../../lib/mock-encryptor')

View File

@ -92,6 +92,7 @@ var actions = {
NEW_ACCOUNT_SCREEN: 'NEW_ACCOUNT_SCREEN',
navigateToNewAccountScreen,
resetAccount,
changePassword,
removeAccount,
showNewVaultSeed: showNewVaultSeed,
showInfoPage: showInfoPage,
@ -311,6 +312,8 @@ var actions = {
removeCustomRPC,
SHOW_DELETE_IMPORTED_ACCOUNT: 'SHOW_DELETE_IMPORTED_ACCOUNT',
showDeleteImportedAccount,
CONFIRM_CHANGE_PASSWORD: 'CONFIRM_CHANGE_PASSWORD',
confirmChangePassword,
}
module.exports = actions
@ -554,6 +557,26 @@ function resetAccount () {
}
}
function changePassword (oldPassword, newPassword) {
return dispatch => {
dispatch(actions.showLoadingIndication())
return new Promise((resolve, reject) => {
background.changePassword(oldPassword, newPassword, (err, account) => {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.displayWarning(err.message))
return reject(err)
}
log.info('Password is changed for ' + account)
dispatch(actions.showAccountsPage())
resolve(account)
})
})
}
}
function removeAccount (address) {
return dispatch => {
dispatch(actions.showLoadingIndication())
@ -2315,3 +2338,9 @@ function showDeleteImportedAccount (identity, keyring) {
keyring,
}
}
function confirmChangePassword () {
return {
type: actions.CONFIRM_CHANGE_PASSWORD,
}
}

View File

@ -729,6 +729,14 @@ function reduceApp (state, action) {
identity: action.identity,
})
case actions.CONFIRM_CHANGE_PASSWORD:
return extend(appState, {
currentView: {
name: 'confirm-change-password',
context: appState.currentView.context,
},
})
default:
return appState
}