From 931ae5f64a233b472c3dada8aa6af77e0bffad5e Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 20 Dec 2016 13:53:14 -0800 Subject: Make notices confirmation configurable - Confirm button will now dismiss the lost accounts array. --- app/scripts/metamask-controller.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 4b8fa432..edb25d30 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -52,7 +52,9 @@ module.exports = class MetamaskController { this.ethStore.getState(), this.configManager.getConfig(), this.keyringController.getState(), - this.noticeController.getState() + this.noticeController.getState(), { + lostAccounts: this.configManager.getLostAccounts(), + } ) } @@ -71,6 +73,7 @@ module.exports = class MetamaskController { setTOSHash: this.setTOSHash.bind(this), checkTOSChange: this.checkTOSChange.bind(this), setGasMultiplier: this.setGasMultiplier.bind(this), + markAccountsFound: this.markAccountsFound.bind(this), // forward directly to keyringController createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController), @@ -410,4 +413,16 @@ module.exports = class MetamaskController { getStateNetwork () { return this.state.network } + + markAccountsFound(cb) { + this.configManager.setLostAccounts([]) + this.keyringController.getAccounts() + .then((accounts) => { + return this.keyringController.setSelectedAccount(accounts[0]) + }) + .then(() => { + this.sendUpdate() + cb(null, this.getState()) + }) + } } -- cgit From 48f2ae2154b6e804ee60cfc1235025c128a6cfa8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 21 Dec 2016 11:01:04 -0800 Subject: Move old keystore migration code to metamask controller Allows keyring controller to be more generic, less opinionated, and who knows, maybe sooner publishable as its own thing. --- app/scripts/metamask-controller.js | 50 +++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index edb25d30..0c772536 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -10,6 +10,7 @@ const ConfigManager = require('./lib/config-manager') const extension = require('./lib/extension') const autoFaucet = require('./lib/auto-faucet') const nodeify = require('./lib/nodeify') +const IdStoreMigrator = require('./lib/idStore-migrator') module.exports = class MetamaskController { @@ -44,6 +45,11 @@ module.exports = class MetamaskController { this.checkTOSChange() this.scheduleConversionInterval() + + // TEMPORARY UNTIL FULL DEPRECATION: + this.idStoreMigrator = new IdStoreMigrator({ + configManager: this.configManager, + }) } getState () { @@ -61,6 +67,7 @@ module.exports = class MetamaskController { getApi () { const keyringController = this.keyringController const noticeController = this.noticeController + const submitPassword = keyringController.submitPassword.bind(keyringController) return { getState: (cb) => { cb(null, this.getState()) }, @@ -81,7 +88,12 @@ module.exports = class MetamaskController { placeSeedWords: nodeify(keyringController.placeSeedWords).bind(keyringController), clearSeedWordCache: nodeify(keyringController.clearSeedWordCache).bind(keyringController), setLocked: nodeify(keyringController.setLocked).bind(keyringController), - submitPassword: nodeify(keyringController.submitPassword).bind(keyringController), + submitPassword: (password, cb) => { + this.migrateOldVaultIfAny() + .then(submitPassword) + .then((newState) => { cb(null, newState) }) + .catch((reason) => { cb(reason) }) + }, addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController), addNewAccount: nodeify(keyringController.addNewAccount).bind(keyringController), setSelectedAccount: nodeify(keyringController.setSelectedAccount).bind(keyringController), @@ -425,4 +437,40 @@ module.exports = class MetamaskController { cb(null, this.getState()) }) } + + // Migrate Old Vault If Any + // @string password + // + // returns Promise() + // + // Temporary step used when logging in. + // Checks if old style (pre-3.0.0) Metamask Vault exists. + // If so, persists that vault in the new vault format + // with the provided password, so the other unlock steps + // may be completed without interruption. + migrateOldVaultIfAny (password) { + const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault() + if (!shouldMigrate) { + return Promise.resolve(password) + } + + return this.idStoreMigrator.migratedVaultForPassword(password) + .then((result) => { + if (result && shouldMigrate) { + const { serialized, lostAccounts } = result + this.configManager.setLostAccounts(lostAccounts) + return this.keyringController.restoreKeyring(serialized) + .then(keyring => keyring.getAccounts()) + .then((accounts) => { + this.configManager.setSelectedAccount(accounts[0]) + return this.keyringController.persistAllKeyrings() + .then(() => password) + }) + } else { + return Promise.resolve(password) + } + }) + } + + } -- cgit From ebeaf3b3d6cf79e2e0f251b9b2da765f0fe6d0e1 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 21 Dec 2016 17:21:10 -0800 Subject: Restructured migration Migrator now returns a lostAccount array that includes objects these objects include keys of address and privateKey, this allows the MetamaskController to restore the lost accounts even without customizing the idStore or the KeyringController. Also includes a patch that allows idStore to synchronously export private keys. --- app/scripts/metamask-controller.js | 62 ++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 19 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0c772536..493ee661 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -67,7 +67,6 @@ module.exports = class MetamaskController { getApi () { const keyringController = this.keyringController const noticeController = this.noticeController - const submitPassword = keyringController.submitPassword.bind(keyringController) return { getState: (cb) => { cb(null, this.getState()) }, @@ -89,10 +88,10 @@ module.exports = class MetamaskController { clearSeedWordCache: nodeify(keyringController.clearSeedWordCache).bind(keyringController), setLocked: nodeify(keyringController.setLocked).bind(keyringController), submitPassword: (password, cb) => { - this.migrateOldVaultIfAny() - .then(submitPassword) - .then((newState) => { cb(null, newState) }) - .catch((reason) => { cb(reason) }) + this.migrateOldVaultIfAny(password) + .then(keyringController.submitPassword.bind(keyringController)) + .then((newState) => { console.log('succeeded submitting!'); cb(null, newState) }) + .catch((reason) => { console.error(reason); cb(reason) }) }, addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController), addNewAccount: nodeify(keyringController.addNewAccount).bind(keyringController), @@ -456,21 +455,46 @@ module.exports = class MetamaskController { return this.idStoreMigrator.migratedVaultForPassword(password) .then((result) => { - if (result && shouldMigrate) { - const { serialized, lostAccounts } = result - this.configManager.setLostAccounts(lostAccounts) - return this.keyringController.restoreKeyring(serialized) - .then(keyring => keyring.getAccounts()) - .then((accounts) => { - this.configManager.setSelectedAccount(accounts[0]) - return this.keyringController.persistAllKeyrings() - .then(() => password) - }) - } else { - return Promise.resolve(password) + + this.keyringController.password = password + const { serialized, lostAccounts } = result + + // Restore the correct accounts first: + return this.keyringController.restoreKeyring(serialized) + .then(keyring => keyring.getAccounts()) + .then((accounts) => { + this.configManager.setSelectedAccount(accounts[0]) + return result + }) + + }).then((result) => { + + // Now we restore any lost accounts: + const { serialized, lostAccounts } = result + if (result && lostAccounts) { + this.configManager.setLostAccounts(lostAccounts.map((acct) => acct.address)) + return this.importLostAccounts(result) } - }) - } + return Promise.resolve(result) + }).then(() => { + + // Persist all these newly restored items to disk: + return this.keyringController.persistAllKeyrings() + // Ultimately pass the password back for normal unlocking: + }).then((result) => password) + } + // IMPORT LOST ACCOUNTS + // @Object with key lostAccounts: @Array accounts <{ address, privateKey }> + // Uses the array's private keys to create a new Simple Key Pair keychain + // and add it to the keyring controller. + importLostAccounts (result) { + const { serialized, lostAccounts } = result + const privKeys = lostAccounts.map(acct => acct.privateKey) + return this.keyringController.restoreKeyring({ + type: 'Simple Key Pair', + data: privKeys, + }) + } } -- cgit From 0df656850de606b82b4299fffdc812f45a252b69 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 21 Dec 2016 17:30:10 -0800 Subject: Linted --- app/scripts/metamask-controller.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 493ee661..2dac61a0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -457,7 +457,7 @@ module.exports = class MetamaskController { .then((result) => { this.keyringController.password = password - const { serialized, lostAccounts } = result + const { serialized } = result // Restore the correct accounts first: return this.keyringController.restoreKeyring(serialized) @@ -470,7 +470,7 @@ module.exports = class MetamaskController { }).then((result) => { // Now we restore any lost accounts: - const { serialized, lostAccounts } = result + const { lostAccounts } = result if (result && lostAccounts) { this.configManager.setLostAccounts(lostAccounts.map((acct) => acct.address)) return this.importLostAccounts(result) @@ -489,8 +489,7 @@ module.exports = class MetamaskController { // @Object with key lostAccounts: @Array accounts <{ address, privateKey }> // Uses the array's private keys to create a new Simple Key Pair keychain // and add it to the keyring controller. - importLostAccounts (result) { - const { serialized, lostAccounts } = result + importLostAccounts ({ lostAccounts }) { const privKeys = lostAccounts.map(acct => acct.privateKey) return this.keyringController.restoreKeyring({ type: 'Simple Key Pair', -- cgit From cf3951c9dfcc42387b165ae76e0a2abaece06b6c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 22 Dec 2016 13:40:12 -0800 Subject: Remove logs --- app/scripts/metamask-controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 2dac61a0..8b7713df 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -90,8 +90,8 @@ module.exports = class MetamaskController { submitPassword: (password, cb) => { this.migrateOldVaultIfAny(password) .then(keyringController.submitPassword.bind(keyringController)) - .then((newState) => { console.log('succeeded submitting!'); cb(null, newState) }) - .catch((reason) => { console.error(reason); cb(reason) }) + .then((newState) => { cb(null, newState) }) + .catch((reason) => { cb(reason) }) }, addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController), addNewAccount: nodeify(keyringController.addNewAccount).bind(keyringController), -- cgit From 291403c13f0c8f61f29585cc9a80ed618718f60f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 22 Dec 2016 13:41:31 -0800 Subject: Don't bother changing selected accounts since accounts are recovered --- app/scripts/metamask-controller.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 8b7713df..ab4cb8ed 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -427,14 +427,8 @@ module.exports = class MetamaskController { markAccountsFound(cb) { this.configManager.setLostAccounts([]) - this.keyringController.getAccounts() - .then((accounts) => { - return this.keyringController.setSelectedAccount(accounts[0]) - }) - .then(() => { - this.sendUpdate() - cb(null, this.getState()) - }) + this.sendUpdate() + cb(null, this.getState()) } // Migrate Old Vault If Any @@ -461,11 +455,7 @@ module.exports = class MetamaskController { // Restore the correct accounts first: return this.keyringController.restoreKeyring(serialized) - .then(keyring => keyring.getAccounts()) - .then((accounts) => { - this.configManager.setSelectedAccount(accounts[0]) - return result - }) + .then(() => result) }).then((result) => { -- cgit From 9e54e3baa0799e5083a9f9152f128077a2ee0527 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 22 Dec 2016 13:56:45 -0800 Subject: Break up migration function --- app/scripts/metamask-controller.js | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index ab4cb8ed..983a590d 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -442,37 +442,37 @@ module.exports = class MetamaskController { // with the provided password, so the other unlock steps // may be completed without interruption. migrateOldVaultIfAny (password) { - const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault() - if (!shouldMigrate) { + + if (!this.checkIfShouldMigrate()) { return Promise.resolve(password) } - return this.idStoreMigrator.migratedVaultForPassword(password) - .then((result) => { - - this.keyringController.password = password - const { serialized } = result - - // Restore the correct accounts first: - return this.keyringController.restoreKeyring(serialized) - .then(() => result) + const keyringController = this.keyringController - }).then((result) => { + return this.idStoreMigrator.migratedVaultForPassword(password) + .then(this.restoreOldVaultAccounts.bind(this)) + .then(this.restoreOldLostAccounts.bind(this)) + .then(keyringController.persistAllKeyrings.bind(keyringController)) + .then(() => password) + } - // Now we restore any lost accounts: - const { lostAccounts } = result - if (result && lostAccounts) { - this.configManager.setLostAccounts(lostAccounts.map((acct) => acct.address)) - return this.importLostAccounts(result) - } - return Promise.resolve(result) - }).then(() => { + checkIfShouldMigrate() { + return !!this.configManager.getWallet() && !this.configManager.getVault() + } - // Persist all these newly restored items to disk: - return this.keyringController.persistAllKeyrings() + restoreOldVaultAccounts(migratorOutput) { + const { serialized } = migratorOutput + return this.keyringController.restoreKeyring(serialized) + .then(() => migratorOutput) + } - // Ultimately pass the password back for normal unlocking: - }).then((result) => password) + restoreOldLostAccounts(migratorOutput) { + const { lostAccounts } = migratorOutput + if (lostAccounts) { + this.configManager.setLostAccounts(lostAccounts.map(acct => acct.address)) + return this.importLostAccounts(migratorOutput) + } + return Promise.resolve(migratorOutput) } // IMPORT LOST ACCOUNTS -- cgit