aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Huang <tmashuang@users.noreply.github.com>2017-11-28 03:37:42 +0800
committerGitHub <noreply@github.com>2017-11-28 03:37:42 +0800
commite71115735c9b9d34fe85bc9e644f3b910bdaa014 (patch)
tree847d13545af412929a2e313af9dcf1e7b2e921a9
parent94fe294cafbe9bfef91f2b9c1aff4caddb35ebd3 (diff)
parentbd45022a2f04fd3d60f1e0da6963344d90aa91a1 (diff)
downloadtangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar.gz
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar.bz2
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar.lz
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar.xz
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.tar.zst
tangerine-wallet-browser-e71115735c9b9d34fe85bc9e644f3b910bdaa014.zip
Merge pull request #2605 from MetaMask/i2577-SeedPhraseBug
Fix a possible seed phrase bug
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/scripts/metamask-controller.js32
-rw-r--r--test/unit/metamask-controller-test.js33
-rw-r--r--ui/app/first-time/init-menu.js7
4 files changed, 68 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 968b8ab58..ab5043196 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
## Current Master
+- Fix bug where a user could be shown two different seed phrases.
- Detect when multiple web3 extensions are active, and provide useful error.
## 3.12.0 2017-10-25
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 968589f6e..a4c77e468 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -31,6 +31,7 @@ const ConfigManager = require('./lib/config-manager')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
const getBuyEthUrl = require('./lib/buy-eth-url')
+const Mutex = require('await-semaphore').Mutex
const version = require('../manifest.json').version
module.exports = class MetamaskController extends EventEmitter {
@@ -38,6 +39,7 @@ module.exports = class MetamaskController extends EventEmitter {
constructor (opts) {
super()
+
this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200)
this.opts = opts
@@ -49,6 +51,9 @@ module.exports = class MetamaskController extends EventEmitter {
// observable state store
this.store = new ObservableStore(initState)
+ // lock to ensure only one vault created at once
+ this.createVaultMutex = new Mutex()
+
// network store
this.networkController = new NetworkController(initState.NetworkController)
@@ -467,15 +472,34 @@ module.exports = class MetamaskController extends EventEmitter {
// Vault Management
//
- async createNewVaultAndKeychain (password, cb) {
- const vault = await this.keyringController.createNewVaultAndKeychain(password)
- this.selectFirstIdentity(vault)
+ async createNewVaultAndKeychain (password) {
+ const release = await this.createVaultMutex.acquire()
+ let vault
+
+ try {
+ const accounts = await this.keyringController.getAccounts()
+
+ if (accounts.length > 0) {
+ vault = await this.keyringController.fullUpdate()
+
+ } else {
+ let vault = await this.keyringController.createNewVaultAndKeychain(password)
+ this.selectFirstIdentity(vault)
+ }
+ release()
+ } catch (err) {
+ release()
+ throw err
+ }
+
return vault
}
- async createNewVaultAndRestore (password, seed, cb) {
+ async createNewVaultAndRestore (password, seed) {
+ const release = await this.createVaultMutex.acquire()
const vault = await this.keyringController.createNewVaultAndRestore(password, seed)
this.selectFirstIdentity(vault)
+ release()
return vault
}
diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js
index ef6cae758..fd420a70f 100644
--- a/test/unit/metamask-controller-test.js
+++ b/test/unit/metamask-controller-test.js
@@ -11,6 +11,15 @@ describe('MetaMaskController', function () {
unlockAccountMessage: noop,
showUnapprovedTx: noop,
platform: {},
+ encryptor: {
+ encrypt: function(password, object) {
+ this.object = object
+ return Promise.resolve()
+ },
+ decrypt: function () {
+ return Promise.resolve(this.object)
+ }
+ },
// initial state
initState: clone(firstTimeState),
})
@@ -27,6 +36,30 @@ describe('MetaMaskController', function () {
describe('Metamask Controller', function () {
assert(metamaskController)
+
+ beforeEach(function () {
+ sinon.spy(metamaskController.keyringController, 'createNewVaultAndKeychain')
+ })
+
+ afterEach(function () {
+ metamaskController.keyringController.createNewVaultAndKeychain.restore()
+ })
+
+ describe('#createNewVaultAndKeychain', function () {
+ it('can only create new vault on keyringController once', async function () {
+
+ const selectStub = sinon.stub(metamaskController, 'selectFirstIdentity')
+
+ const password = 'a-fake-password'
+
+ const first = await metamaskController.createNewVaultAndKeychain(password)
+ const second = await metamaskController.createNewVaultAndKeychain(password)
+
+ assert(metamaskController.keyringController.createNewVaultAndKeychain.calledOnce)
+
+ selectStub.reset()
+ })
+ })
})
})
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index cc7c51bd3..b4587f1ee 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -8,6 +8,8 @@ const actions = require('../actions')
const Tooltip = require('../components/tooltip')
const getCaretCoordinates = require('textarea-caret')
+let isSubmitting = false
+
module.exports = connect(mapStateToProps)(InitializeMenuScreen)
inherits(InitializeMenuScreen, Component)
@@ -164,7 +166,10 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
return
}
- this.props.dispatch(actions.createNewVaultAndKeychain(password))
+ if (!isSubmitting) {
+ isSubmitting = true
+ this.props.dispatch(actions.createNewVaultAndKeychain(password))
+ }
}
InitializeMenuScreen.prototype.inputChanged = function (event) {