feature/default_network_editable
Dan Finlay 8 years ago
parent 383f8ea7dc
commit 0deed17752
  1. 2
      app/scripts/keyring-controller.js
  2. 14
      app/scripts/lib/encryptor.js
  3. 1
      test/integration/lib/encryptor-test.js
  4. 60
      test/unit/actions/restore_vault_test.js
  5. 8
      test/unit/actions/tx_test.js
  6. 106
      test/unit/keyring-controller-test.js
  7. 4
      ui/app/actions.js

@ -35,7 +35,7 @@ module.exports = class KeyringController extends EventEmitter {
}
createNewVault(password, entropy, cb) {
const salt = generateNewSalt()
const salt = generateSalt()
this.configManager.setSalt(salt)
this.loadKey(password)
.then((key) => {

@ -42,8 +42,9 @@ function encryptWithKey (key, dataObj) {
iv: vector,
}, key, dataBuffer).then(function(buf){
var buffer = new Uint8Array(buf)
var vectorStr = serializeBufferForStorage(vector)
return serializeBufferForStorage(buffer) + vectorStr
var vectorStr = encodeBufferToBase64(vector)
var vaultStr = encodeBufferToBase64(buffer)
return `${vaultStr}\\${vectorStr}`
})
}
@ -56,9 +57,9 @@ function decrypt (password, text) {
}
function decryptWithKey (key, text) {
const parts = text.split('0x')
const encryptedData = serializeBufferFromStorage(parts[1])
const vector = serializeBufferFromStorage(parts[2])
const parts = text.split('\\')
const encryptedData = decodeBase64ToBuffer(parts[0])
const vector = decodeBase64ToBuffer(parts[1])
return crypto.subtle.decrypt({name: 'AES-GCM', iv: vector}, key, encryptedData)
.then(function(result){
const decryptedData = new Uint8Array(result)
@ -128,8 +129,9 @@ function encodeBufferToBase64 (buf) {
}
function decodeBase64ToBuffer (base64) {
var u8_2 = new Uint8Array(atob(b64encoded).split("")
var buf = new Uint8Array(atob(base64).split('')
.map(function(c) {
return c.charCodeAt(0)
}))
return buf
}

@ -39,6 +39,7 @@ QUnit.test('encryptor:encrypt & decrypt', function(assert) {
})
.catch(function(reason) {
assert.ifError(reason, 'threw an error')
done(reason)
})
})

@ -1,60 +0,0 @@
var jsdom = require('mocha-jsdom')
var assert = require('assert')
var freeze = require('deep-freeze-strict')
var path = require('path')
var sinon = require('sinon')
var actions = require(path.join(__dirname, '..', '..', '..', 'ui', 'app', 'actions.js'))
var reducers = require(path.join(__dirname, '..', '..', '..', 'ui', 'app', 'reducers.js'))
describe('#recoverFromSeed(password, seed)', function() {
beforeEach(function() {
// sinon allows stubbing methods that are easily verified
this.sinon = sinon.sandbox.create()
})
afterEach(function() {
// sinon requires cleanup otherwise it will overwrite context
this.sinon.restore()
})
// stub out account manager
actions._setKeyringController({
recoverFromSeed(pw, seed, cb) {
cb(null, {
identities: {
foo: 'bar'
}
})
},
})
it('sets metamask.isUnlocked to true', function() {
var initialState = {
metamask: {
isUnlocked: false,
isInitialized: false,
}
}
freeze(initialState)
const restorePhrase = 'invite heavy among daring outdoor dice jelly coil stable note seat vicious'
const password = 'foo'
const dispatchFunc = actions.recoverFromSeed(password, restorePhrase)
var dispatchStub = this.sinon.stub()
dispatchStub.withArgs({ TYPE: actions.unlockMetamask() }).onCall(0)
dispatchStub.withArgs({ TYPE: actions.showAccountsPage() }).onCall(1)
var action
var resultingState = initialState
dispatchFunc((newAction) => {
action = newAction
resultingState = reducers(resultingState, action)
})
assert.equal(resultingState.metamask.isUnlocked, true, 'was unlocked')
assert.equal(resultingState.metamask.isInitialized, true, 'was initialized')
});
});

@ -46,7 +46,7 @@ describe('tx confirmation screen', function() {
describe('cancelTx', function() {
before(function(done) {
actions._setKeyringController({
actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb('An error!') },
cancelTransaction(txId) { /* noop */ },
clearSeedWordCache(cb) { cb() },
@ -75,7 +75,7 @@ describe('tx confirmation screen', function() {
before(function(done) {
alert = () => {/* noop */}
actions._setKeyringController({
actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb({message: 'An error!'}) },
})
@ -96,7 +96,7 @@ describe('tx confirmation screen', function() {
describe('when there is success', function() {
it('should complete tx and go home', function() {
actions._setKeyringController({
actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb() },
})
@ -135,7 +135,7 @@ describe('tx confirmation screen', function() {
}
freeze(initialState)
actions._setKeyringController({
actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb() },
})

@ -31,111 +31,5 @@ describe('KeyringController', function() {
done()
})
})
describe('#recoverFromSeed', function() {
let newAccounts = []
before(function() {
window.localStorage = {} // Hacking localStorage support into JSDom
keyringController = new KeyringController({
configManager: configManagerGen(),
ethStore: {
addAccount(acct) { newAccounts.push(ethUtil.addHexPrefix(acct)) },
},
})
})
it('should return the expected keystore', function (done) {
keyringController.recoverFromSeed(password, seedWords, (err) => {
assert.ifError(err)
let newKeystore = keyringController._idmgmt.keyStore
assert.equal(newAccounts[0], accounts[0])
done()
})
})
})
})
describe('#recoverFromSeed BIP44 compliance', function() {
const salt = 'lightwalletSalt'
let password = 'secret!'
let accounts = {}
let keyringController
var assertions = [
{
seed: 'picnic injury awful upper eagle junk alert toss flower renew silly vague',
account: '0x5d8de92c205279c10e5669f797b853ccef4f739a',
},
{
seed: 'radar blur cabbage chef fix engine embark joy scheme fiction master release',
account: '0xe15d894becb0354c501ae69429b05143679f39e0',
},
{
seed: 'phone coyote caught pattern found table wedding list tumble broccoli chief swing',
account: '0xb0e868f24bc7fec2bce2efc2b1c344d7569cd9d2',
},
{
seed: 'recycle tag bird palace blue village anxiety census cook soldier example music',
account: '0xab34a45920afe4af212b96ec51232aaa6a33f663',
},
{
seed: 'half glimpse tape cute harvest sweet bike voyage actual floor poet lazy',
account: '0x28e9044597b625ac4beda7250011670223de43b2',
},
{
seed: 'flavor tiger carpet motor angry hungry document inquiry large critic usage liar',
account: '0xb571be96558940c4e9292e1999461aa7499fb6cd',
},
]
before(function() {
window.localStorage = {} // Hacking localStorage support into JSDom
keyringController = new KeyringController({
configManager: configManagerGen(),
ethStore: {
addAccount(acct) { accounts[acct] = acct},
del(acct) { delete accounts[acct] },
},
})
})
it('should enforce seed compliance with TestRPC', function (done) {
this.timeout(10000)
const tests = assertions.map((assertion) => {
return function (cb) {
keyringController.recoverFromSeed(password, assertion.seed, (err) => {
assert.ifError(err)
var expected = assertion.account.toLowerCase()
var received = accounts[expected].toLowerCase()
assert.equal(received, expected)
keyringController.tryPassword(password, function (err) {
assert.ok(keyringController._isUnlocked(), 'should unlock the id store')
keyringController.submitPassword(password, function(err, account) {
assert.ifError(err)
assert.equal(account, expected)
assert.equal(Object.keys(keyringController._getAddresses()).length, 1, 'only one account on restore')
cb()
})
})
})
}
})
async.series(tests, function(err, results) {
assert.ifError(err)
done()
})
})
})
})

@ -1,4 +1,6 @@
var actions = {
_setBackgroundConnection: _setBackgroundConnection,
GO_HOME: 'GO_HOME',
goHome: goHome,
// menu state
@ -94,8 +96,6 @@ var actions = {
showConfigPage: showConfigPage,
setRpcTarget: setRpcTarget,
setProviderType: setProviderType,
// hacky - need a way to get a reference to account manager
_setBackgroundConnection: _setBackgroundConnection,
// loading overlay
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
HIDE_LOADING: 'HIDE_LOADING_INDICATION',

Loading…
Cancel
Save