From 26b60f1b5a5c34754d0f8b920ef5211b94480e80 Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 7 Dec 2016 14:42:38 -0800 Subject: inpage - correctly listen for incomming messages --- app/scripts/inpage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 85dd70b4d..ef199946c 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -43,7 +43,7 @@ reloadStream.once('data', triggerReload) var pingChannel = inpageProvider.multiStream.createStream('pingpong') var pingStream = new PingStream({ objectMode: true }) // wait for first successful reponse -metamaskStream.once('_data', function(){ +metamaskStream.once('data', function(){ pingStream.pipe(pingChannel).pipe(pingStream) }) endOfStream(pingStream, triggerReload) -- cgit v1.2.3 From ab9e15b782620002c0a2477829db3e56a25a7d5c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 8 Dec 2016 14:22:02 -0800 Subject: Mostly added bad account detection Currently riddled with logs, because the migrator is inexplicably returning before generating the new style accounts for comparison. --- app/scripts/keyring-controller.js | 8 +++++- app/scripts/keyrings/hd.js | 8 ++++-- app/scripts/lib/config-manager.js | 12 ++++++++ app/scripts/lib/idStore-migrator.js | 55 +++++++++++++++++++++++++++++++++---- 4 files changed, 74 insertions(+), 9 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index 40c9695dd..d0ce16cbb 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -113,6 +113,7 @@ module.exports = class KeyringController extends EventEmitter { conversionDate: this.configManager.getConversionDate(), keyringTypes: this.keyringTypes.map(krt => krt.type), identities: this.identities, + lostAccounts: this.configManager.getLostAccounts(), } } @@ -623,7 +624,12 @@ module.exports = class KeyringController extends EventEmitter { migrateOldVaultIfAny (password) { const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault() return this.idStoreMigrator.migratedVaultForPassword(password) - .then((serialized) => { + .then((result) => { + console.log('migrator called back with') + console.dir(result) + const { serialized, lostAccounts } = result + console.dir({ serialized, lostAccounts }) + this.configManager.setLostAccounts(lostAccounts) this.password = password if (serialized && shouldMigrate) { diff --git a/app/scripts/keyrings/hd.js b/app/scripts/keyrings/hd.js index cfec56561..55c008601 100644 --- a/app/scripts/keyrings/hd.js +++ b/app/scripts/keyrings/hd.js @@ -38,16 +38,18 @@ class HdKeyring extends EventEmitter { } if ('numberOfAccounts' in opts) { - this.addAccounts(opts.numberOfAccounts) + console.log('number of accounts detected, adding accounts.') + return this.addAccounts(opts.numberOfAccounts) } - return Promise.resolve() + return Promise.resolve([]) } addAccounts (numberOfAccounts = 1) { if (!this.root) { this._initFromMnemonic(bip39.generateMnemonic()) } + console.log('attempting to add %s accounts', numberOfAccounts) const oldLen = this.wallets.length const newWallets = [] @@ -57,7 +59,9 @@ class HdKeyring extends EventEmitter { newWallets.push(wallet) this.wallets.push(wallet) } + console.log('hd has %s wallets', this.wallets.length) const hexWallets = newWallets.map(w => w.getAddress().toString('hex')) + console.log('hd calling back w promise of hex wallets ' + hexWallets) return Promise.resolve(hexWallets) } diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index 59cc2b63c..efc0b4628 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -432,3 +432,15 @@ ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) { data.gasMultiplier = gasMultiplier this.setData(data) } + +ConfigManager.prototype.setLostAccounts = function (lostAccounts) { + var data = this.getData() + data.lostAccounts = lostAccounts + this.setData(data) +} + +ConfigManager.prototype.getLostAccounts = function () { + var data = this.getData() + return ('lostAccounts' in data) && data.lostAccounts || [] +} + diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index 40b08efee..c13015b96 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -1,5 +1,7 @@ const IdentityStore = require('./idStore') - +const HdKeyring = require('../keyrings/hd') +const sigUtil = require('./sig-util') +const normalize = sigUtil.normalize module.exports = class IdentityStoreMigrator { @@ -12,25 +14,34 @@ module.exports = class IdentityStoreMigrator { } migratedVaultForPassword (password) { + console.log('migrating vault for password') const hasOldVault = this.hasOldVault() const configManager = this.configManager if (!this.idStore) { + console.log('initializing id store') this.idStore = new IdentityStore({ configManager }) + console.log('initialized') } if (!hasOldVault) { + console.log('no old vault recognized') return Promise.resolve(null) } + console.log('returning new promise') return new Promise((resolve, reject) => { + console.log('submitting password to idStore') this.idStore.submitPassword(password, (err) => { + console.log('returned ' + err) if (err) return reject(err) - try { - resolve(this.serializeVault()) - } catch (e) { - reject(e) - } + console.log('serializing vault') + const serialized = this.serializeVault() + console.log('migrated and serialized into') + console.dir(serialized) + this.checkForErrors(serialized) + .then(resolve) + .catch(reject) }) }) } @@ -45,6 +56,38 @@ module.exports = class IdentityStoreMigrator { } } + checkForErrors (serialized) { + console.log('checking for errors, first making hd wallet') + const hd = new HdKeyring() + return hd.deserialize(serialized) + .then(() => { + console.log('deserialized, now getting accounts') + console.dir(arguments) + return hd.getAccounts() + }) + .then((hexAccounts) => { + console.log('hd returned accounts', hexAccounts) + const newAccounts = hexAccounts.map(normalize) + const oldAccounts = this.idStore._getAddresses().map(normalize) + const lostAccounts = oldAccounts.reduce((result, account) => { + if (newAccounts.includes(account)) { + return result + } else { + result.push(account) + return result + } + }, []) + + console.log('migrator has') + console.dir({ newAccounts, oldAccounts, lostAccounts, hexAccounts }) + + return { + serialized, + lostAccounts, + } + }) + } + hasOldVault () { const wallet = this.configManager.getWallet() return wallet -- cgit v1.2.3 From 7b9749e30c4f8228fe62c1ad81515117cf7504bc Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 9 Dec 2016 12:24:25 -0800 Subject: Got bad account detection working and added to state --- app/scripts/keyring-controller.js | 13 +++++++------ app/scripts/keyrings/hd.js | 4 ---- app/scripts/lib/idStore-migrator.js | 22 +--------------------- 3 files changed, 8 insertions(+), 31 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index d0ce16cbb..6a087c918 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -623,16 +623,17 @@ module.exports = class KeyringController extends EventEmitter { // may be completed without interruption. migrateOldVaultIfAny (password) { const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault() + if (!shouldMigrate) { + return Promise.resolve() + } + return this.idStoreMigrator.migratedVaultForPassword(password) .then((result) => { - console.log('migrator called back with') - console.dir(result) - const { serialized, lostAccounts } = result - console.dir({ serialized, lostAccounts }) - this.configManager.setLostAccounts(lostAccounts) this.password = password - if (serialized && shouldMigrate) { + if (result && shouldMigrate) { + const { serialized, lostAccounts } = result + this.configManager.setLostAccounts(lostAccounts) return this.restoreKeyring(serialized) .then(keyring => keyring.getAccounts()) .then((accounts) => { diff --git a/app/scripts/keyrings/hd.js b/app/scripts/keyrings/hd.js index 55c008601..097d995a7 100644 --- a/app/scripts/keyrings/hd.js +++ b/app/scripts/keyrings/hd.js @@ -38,7 +38,6 @@ class HdKeyring extends EventEmitter { } if ('numberOfAccounts' in opts) { - console.log('number of accounts detected, adding accounts.') return this.addAccounts(opts.numberOfAccounts) } @@ -49,7 +48,6 @@ class HdKeyring extends EventEmitter { if (!this.root) { this._initFromMnemonic(bip39.generateMnemonic()) } - console.log('attempting to add %s accounts', numberOfAccounts) const oldLen = this.wallets.length const newWallets = [] @@ -59,9 +57,7 @@ class HdKeyring extends EventEmitter { newWallets.push(wallet) this.wallets.push(wallet) } - console.log('hd has %s wallets', this.wallets.length) const hexWallets = newWallets.map(w => w.getAddress().toString('hex')) - console.log('hd calling back w promise of hex wallets ' + hexWallets) return Promise.resolve(hexWallets) } diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index c13015b96..14bd0d8b8 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -14,31 +14,21 @@ module.exports = class IdentityStoreMigrator { } migratedVaultForPassword (password) { - console.log('migrating vault for password') const hasOldVault = this.hasOldVault() const configManager = this.configManager if (!this.idStore) { - console.log('initializing id store') this.idStore = new IdentityStore({ configManager }) - console.log('initialized') } if (!hasOldVault) { - console.log('no old vault recognized') return Promise.resolve(null) } - console.log('returning new promise') return new Promise((resolve, reject) => { - console.log('submitting password to idStore') this.idStore.submitPassword(password, (err) => { - console.log('returned ' + err) if (err) return reject(err) - console.log('serializing vault') const serialized = this.serializeVault() - console.log('migrated and serialized into') - console.dir(serialized) this.checkForErrors(serialized) .then(resolve) .catch(reject) @@ -57,16 +47,9 @@ module.exports = class IdentityStoreMigrator { } checkForErrors (serialized) { - console.log('checking for errors, first making hd wallet') const hd = new HdKeyring() - return hd.deserialize(serialized) - .then(() => { - console.log('deserialized, now getting accounts') - console.dir(arguments) - return hd.getAccounts() - }) + return hd.deserialize(serialized.data) .then((hexAccounts) => { - console.log('hd returned accounts', hexAccounts) const newAccounts = hexAccounts.map(normalize) const oldAccounts = this.idStore._getAddresses().map(normalize) const lostAccounts = oldAccounts.reduce((result, account) => { @@ -78,9 +61,6 @@ module.exports = class IdentityStoreMigrator { } }, []) - console.log('migrator has') - console.dir({ newAccounts, oldAccounts, lostAccounts, hexAccounts }) - return { serialized, lostAccounts, -- cgit v1.2.3 From 83880a5c92df6024e3420ecf19d55585f5d2b185 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 15 Dec 2016 16:09:39 -0800 Subject: Remove morden testnet provider Instances configured to point at Morden will now point at Ropsten. --- app/scripts/config.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/config.js b/app/scripts/config.js index 9a0f2a50b..e09206c5f 100644 --- a/app/scripts/config.js +++ b/app/scripts/config.js @@ -1,6 +1,5 @@ const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask' const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask' -const MORDEN_RPC_URL = 'https://morden.infura.io/metamask' const DEFAULT_RPC_URL = TESTNET_RPC_URL global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' @@ -11,6 +10,6 @@ module.exports = { default: DEFAULT_RPC_URL, mainnet: MAINET_RPC_URL, testnet: TESTNET_RPC_URL, - morden: MORDEN_RPC_URL, + morden: TESTNET_RPC_URL, }, } -- cgit v1.2.3 From 8819475a2ed2ee7c34e983ebb5ab12661be1a961 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 7 Dec 2016 14:34:15 -0800 Subject: Add ability to show notices to user & get confirmation. Implement generation of markdown for notice files. Create npm command. Enhance notice generation. Add test files to test multiple notices. Add basic markdown support to notices. Interval checks for updates. Add extensionizer and linker Add terms and conditions state file Add link support to disclaimer. Changelog addition. --- app/scripts/lib/config-manager.js | 64 ++++++++++++++++++++++++++++++++++++++ app/scripts/metamask-controller.js | 42 +++++++++++++++++++++++-- app/scripts/notice-controller.js | 18 +++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 app/scripts/notice-controller.js (limited to 'app/scripts') diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index b8ffb6991..b5e4995ad 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -2,6 +2,7 @@ const Migrator = require('pojo-migrator') const MetamaskConfig = require('../config.js') const migrations = require('./migrations') const rp = require('request-promise') +const notices = require('../../../development/notices.json') const TESTNET_RPC = MetamaskConfig.network.testnet const MAINNET_RPC = MetamaskConfig.network.mainnet @@ -161,6 +162,69 @@ ConfigManager.prototype.setData = function (data) { this.migrator.saveData(data) } +// +// Notices +// + +ConfigManager.prototype.getNoticesList = function () { + var data = this.getData() + if ('noticesList' in data) { + return data.noticesList + } else { + return [] + } +} + +ConfigManager.prototype.setNoticesList = function (list) { + var data = this.getData() + data.noticesList = list + this.setData(data) + return Promise.resolve(true) +} + +ConfigManager.prototype.markNoticeRead = function (notice) { + var notices = this.getNoticesList() + var id = notice.id + notices[id].read = true + this.setNoticesList(notices) +} + +ConfigManager.prototype.updateNoticesList = function () { + return this._retrieveNoticeData().then((newNotices) => { + var oldNotices = this.getNoticesList() + var combinedNotices = this._mergeNotices(oldNotices, newNotices) + return Promise.resolve(this.setNoticesList(combinedNotices)) + }) +} + +ConfigManager.prototype.getLatestUnreadNotice = function () { + var notices = this.getNoticesList() + var filteredNotices = notices.filter((notice) => { + return notice.read === false + }) + return filteredNotices[filteredNotices.length - 1] +} + +ConfigManager.prototype._mergeNotices = function (oldNotices, newNotices) { + var noticeMap = this._mapNoticeIds(oldNotices) + newNotices.forEach((notice) => { + if (noticeMap.indexOf(notice.id) === -1) { + oldNotices.push(notice) + } + }) + return oldNotices +} + +ConfigManager.prototype._mapNoticeIds = function (notices) { + return notices.map((notice) => notice.id) +} + +ConfigManager.prototype._retrieveNoticeData = function () { + // Placeholder for the API. + return Promise.resolve(notices) +} + + // // Tx // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 631411bed..65619af82 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -2,6 +2,7 @@ const extend = require('xtend') const EthStore = require('eth-store') const MetaMaskProvider = require('web3-provider-engine/zero.js') const IdentityStore = require('./lib/idStore') +const NoticeController = require('./notice-controller') const messageManager = require('./lib/message-manager') const HostStore = require('./lib/remote-store.js').HostStore const Web3 = require('web3') @@ -17,6 +18,9 @@ module.exports = class MetamaskController { this.idStore = new IdentityStore({ configManager: this.configManager, }) + this.noticeController = new NoticeController({ + configManager: this.configManager, + }) this.provider = this.initializeProvider(opts) this.ethStore = new EthStore(this.provider) this.idStore.setStore(this.ethStore) @@ -27,17 +31,19 @@ module.exports = class MetamaskController { this.configManager.setCurrentFiat(currentFiat) this.configManager.updateConversionRate() + this.checkNotices() this.checkTOSChange() this.scheduleConversionInterval() - + this.scheduleNoticeCheck() } getState () { return extend( this.ethStore.getState(), this.idStore.getState(), - this.configManager.getConfig() + this.configManager.getConfig(), + this.noticeController.getState() ) } @@ -55,6 +61,7 @@ module.exports = class MetamaskController { agreeToEthWarning: this.agreeToEthWarning.bind(this), setTOSHash: this.setTOSHash.bind(this), checkTOSChange: this.checkTOSChange.bind(this), + checkNotices: this.checkNotices.bind(this), setGasMultiplier: this.setGasMultiplier.bind(this), // forward directly to idStore @@ -77,6 +84,8 @@ module.exports = class MetamaskController { buyEth: this.buyEth.bind(this), // shapeshift createShapeShiftTx: this.createShapeShiftTx.bind(this), + // notices + markNoticeRead: this.markNoticeRead.bind(this), } } @@ -289,6 +298,25 @@ module.exports = class MetamaskController { } + checkNotices () { + try { + this.configManager.updateNoticesList() + } catch (e) { + console.error('Error in checking notices.') + } + } + + // notice + + markNoticeRead (notice, cb) { + try { + this.configManager.markNoticeRead(notice) + cb(null, this.configManager.getLatestUnreadNotice()) + } catch (e) { + cb(e) + } + } + agreeToDisclaimer (cb) { try { this.configManager.setConfirmed(true) @@ -331,6 +359,7 @@ module.exports = class MetamaskController { }, 300000) } +<<<<<<< HEAD agreeToEthWarning (cb) { try { this.configManager.setShouldntShowWarning() @@ -338,6 +367,15 @@ module.exports = class MetamaskController { } catch (e) { cb(e) } +======= + scheduleNoticeCheck () { + if (this.noticeCheck) { + clearInterval(this.noticeCheck) + } + this.noticeCheck = setInterval(() => { + this.configManager.updateNoticesList() + }, 300000) +>>>>>>> 25acad7... Add ability to show notices to user & get confirmation. } // called from popup diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js new file mode 100644 index 000000000..f1785d705 --- /dev/null +++ b/app/scripts/notice-controller.js @@ -0,0 +1,18 @@ +const EventEmitter = require('events').EventEmitter + +module.exports = class NoticeController extends EventEmitter { + + constructor (opts) { + super() + this.configManager = opts.configManager + } + + getState() { + var lastUnreadNotice = this.configManager.getLatestUnreadNotice() + + return { + lastUnreadNotice: lastUnreadNotice, + noActiveNotices: !lastUnreadNotice, + } + } +} -- cgit v1.2.3 From 851ba66cdd50aae8e2f9cb70fbed016990df2a2a Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 7 Dec 2016 14:34:15 -0800 Subject: Add ability to show notices to user & get confirmation. Implement generation of markdown for notice files. Create npm command. Enhance notice generation. Add test files to test multiple notices. Add basic markdown support to notices. Interval checks for updates. Add extensionizer and linker Add terms and conditions state file Add link support to disclaimer. Changelog addition. --- app/scripts/metamask-controller.js | 40 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 65619af82..65eda7342 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -21,6 +21,9 @@ module.exports = class MetamaskController { this.noticeController = new NoticeController({ configManager: this.configManager, }) + this.noticeController = new NoticeController({ + configManager: this.configManager, + }) this.provider = this.initializeProvider(opts) this.ethStore = new EthStore(this.provider) this.idStore.setStore(this.ethStore) @@ -298,14 +301,6 @@ module.exports = class MetamaskController { } - checkNotices () { - try { - this.configManager.updateNoticesList() - } catch (e) { - console.error('Error in checking notices.') - } - } - // notice markNoticeRead (notice, cb) { @@ -317,6 +312,25 @@ module.exports = class MetamaskController { } } + checkNotices () { + try { + this.configManager.updateNoticesList() + } catch (e) { + console.error('Error in checking notices.') + } + } + + scheduleNoticeCheck () { + if (this.noticeCheck) { + clearInterval(this.noticeCheck) + } + this.noticeCheck = setInterval(() => { + this.configManager.updateNoticesList() + }, 300000) + } + + // disclaimer + agreeToDisclaimer (cb) { try { this.configManager.setConfirmed(true) @@ -359,7 +373,6 @@ module.exports = class MetamaskController { }, 300000) } -<<<<<<< HEAD agreeToEthWarning (cb) { try { this.configManager.setShouldntShowWarning() @@ -367,15 +380,6 @@ module.exports = class MetamaskController { } catch (e) { cb(e) } -======= - scheduleNoticeCheck () { - if (this.noticeCheck) { - clearInterval(this.noticeCheck) - } - this.noticeCheck = setInterval(() => { - this.configManager.updateNoticesList() - }, 300000) ->>>>>>> 25acad7... Add ability to show notices to user & get confirmation. } // called from popup -- cgit v1.2.3 From 2b1d821da3d7205254b9cccf34215e0bfb0fded8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 16 Dec 2016 11:26:39 -0800 Subject: Cleanup --- app/scripts/metamask-controller.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 65eda7342..b22d53d11 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -21,9 +21,6 @@ module.exports = class MetamaskController { this.noticeController = new NoticeController({ configManager: this.configManager, }) - this.noticeController = new NoticeController({ - configManager: this.configManager, - }) this.provider = this.initializeProvider(opts) this.ethStore = new EthStore(this.provider) this.idStore.setStore(this.ethStore) -- cgit v1.2.3 From 1458b8c68ec1ae5e043d9ea08a862a38966b22c1 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Fri, 16 Dec 2016 11:39:41 -0800 Subject: Deactivate polling for now. --- app/scripts/metamask-controller.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b22d53d11..b7e37b3a5 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -35,7 +35,9 @@ module.exports = class MetamaskController { this.checkTOSChange() this.scheduleConversionInterval() - this.scheduleNoticeCheck() + + // to be uncommented when retrieving notices from a remote server. + // this.scheduleNoticeCheck() } getState () { -- cgit v1.2.3 From 73998feeb2b6ba4ebb9a16c6ed54cce195c09013 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 16 Dec 2016 12:44:47 -0800 Subject: move notice code from metamask-controller + config-manager, in to notice-controller --- app/scripts/lib/config-manager.js | 64 ------------------------------ app/scripts/metamask-controller.js | 65 +++++++++---------------------- app/scripts/notice-controller.js | 80 +++++++++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 111 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index b5e4995ad..b8ffb6991 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -2,7 +2,6 @@ const Migrator = require('pojo-migrator') const MetamaskConfig = require('../config.js') const migrations = require('./migrations') const rp = require('request-promise') -const notices = require('../../../development/notices.json') const TESTNET_RPC = MetamaskConfig.network.testnet const MAINNET_RPC = MetamaskConfig.network.mainnet @@ -162,69 +161,6 @@ ConfigManager.prototype.setData = function (data) { this.migrator.saveData(data) } -// -// Notices -// - -ConfigManager.prototype.getNoticesList = function () { - var data = this.getData() - if ('noticesList' in data) { - return data.noticesList - } else { - return [] - } -} - -ConfigManager.prototype.setNoticesList = function (list) { - var data = this.getData() - data.noticesList = list - this.setData(data) - return Promise.resolve(true) -} - -ConfigManager.prototype.markNoticeRead = function (notice) { - var notices = this.getNoticesList() - var id = notice.id - notices[id].read = true - this.setNoticesList(notices) -} - -ConfigManager.prototype.updateNoticesList = function () { - return this._retrieveNoticeData().then((newNotices) => { - var oldNotices = this.getNoticesList() - var combinedNotices = this._mergeNotices(oldNotices, newNotices) - return Promise.resolve(this.setNoticesList(combinedNotices)) - }) -} - -ConfigManager.prototype.getLatestUnreadNotice = function () { - var notices = this.getNoticesList() - var filteredNotices = notices.filter((notice) => { - return notice.read === false - }) - return filteredNotices[filteredNotices.length - 1] -} - -ConfigManager.prototype._mergeNotices = function (oldNotices, newNotices) { - var noticeMap = this._mapNoticeIds(oldNotices) - newNotices.forEach((notice) => { - if (noticeMap.indexOf(notice.id) === -1) { - oldNotices.push(notice) - } - }) - return oldNotices -} - -ConfigManager.prototype._mapNoticeIds = function (notices) { - return notices.map((notice) => notice.id) -} - -ConfigManager.prototype._retrieveNoticeData = function () { - // Placeholder for the API. - return Promise.resolve(notices) -} - - // // Tx // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b7e37b3a5..1477ce9e7 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -18,9 +18,13 @@ module.exports = class MetamaskController { this.idStore = new IdentityStore({ configManager: this.configManager, }) + // notices this.noticeController = new NoticeController({ configManager: this.configManager, }) + this.noticeController.updateNoticesList() + // to be uncommented when retrieving notices from a remote server. + // this.noticeController.startPolling() this.provider = this.initializeProvider(opts) this.ethStore = new EthStore(this.provider) this.idStore.setStore(this.ethStore) @@ -31,13 +35,9 @@ module.exports = class MetamaskController { this.configManager.setCurrentFiat(currentFiat) this.configManager.updateConversionRate() - this.checkNotices() this.checkTOSChange() this.scheduleConversionInterval() - - // to be uncommented when retrieving notices from a remote server. - // this.scheduleNoticeCheck() } getState () { @@ -51,6 +51,7 @@ module.exports = class MetamaskController { getApi () { const idStore = this.idStore + const noticeController = this.noticeController return { getState: (cb) => { cb(null, this.getState()) }, @@ -63,7 +64,6 @@ module.exports = class MetamaskController { agreeToEthWarning: this.agreeToEthWarning.bind(this), setTOSHash: this.setTOSHash.bind(this), checkTOSChange: this.checkTOSChange.bind(this), - checkNotices: this.checkNotices.bind(this), setGasMultiplier: this.setGasMultiplier.bind(this), // forward directly to idStore @@ -87,7 +87,8 @@ module.exports = class MetamaskController { // shapeshift createShapeShiftTx: this.createShapeShiftTx.bind(this), // notices - markNoticeRead: this.markNoticeRead.bind(this), + checkNotices: noticeController.updateNoticesList.bind(noticeController), + markNoticeRead: noticeController.markNoticeRead.bind(noticeController), } } @@ -282,7 +283,7 @@ module.exports = class MetamaskController { setTOSHash (hash) { try { this.configManager.setTOSHash(hash) - } catch (e) { + } catch (err) { console.error('Error in setting terms of service hash.') } } @@ -294,56 +295,28 @@ module.exports = class MetamaskController { this.resetDisclaimer() this.setTOSHash(global.TOS_HASH) } - } catch (e) { + } catch (err) { console.error('Error in checking TOS change.') } } - // notice - - markNoticeRead (notice, cb) { - try { - this.configManager.markNoticeRead(notice) - cb(null, this.configManager.getLatestUnreadNotice()) - } catch (e) { - cb(e) - } - } - - checkNotices () { - try { - this.configManager.updateNoticesList() - } catch (e) { - console.error('Error in checking notices.') - } - } - - scheduleNoticeCheck () { - if (this.noticeCheck) { - clearInterval(this.noticeCheck) - } - this.noticeCheck = setInterval(() => { - this.configManager.updateNoticesList() - }, 300000) - } - // disclaimer agreeToDisclaimer (cb) { try { this.configManager.setConfirmed(true) cb() - } catch (e) { - cb(e) + } catch (err) { + cb(err) } } resetDisclaimer () { try { this.configManager.setConfirmed(false) - } catch (e) { - console.error(e) + } catch (err) { + console.error(err) } } @@ -358,8 +331,8 @@ module.exports = class MetamaskController { conversionDate: this.configManager.getConversionDate(), } cb(data) - } catch (e) { - cb(null, e) + } catch (err) { + cb(null, err) } } @@ -376,8 +349,8 @@ module.exports = class MetamaskController { try { this.configManager.setShouldntShowWarning() cb() - } catch (e) { - cb(e) + } catch (err) { + cb(err) } } @@ -422,8 +395,8 @@ module.exports = class MetamaskController { try { this.configManager.setGasMultiplier(gasMultiplier) cb() - } catch (e) { - cb(e) + } catch (err) { + cb(err) } } } diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js index f1785d705..438f5c27e 100644 --- a/app/scripts/notice-controller.js +++ b/app/scripts/notice-controller.js @@ -1,18 +1,96 @@ const EventEmitter = require('events').EventEmitter +const hardCodedNotices = require('../../development/notices.json') module.exports = class NoticeController extends EventEmitter { constructor (opts) { super() this.configManager = opts.configManager + this.noticePoller = null } getState() { - var lastUnreadNotice = this.configManager.getLatestUnreadNotice() + var lastUnreadNotice = this.getLatestUnreadNotice() return { lastUnreadNotice: lastUnreadNotice, noActiveNotices: !lastUnreadNotice, } } + + getNoticesList() { + var data = this.configManager.getData() + if ('noticesList' in data) { + return data.noticesList + } else { + return [] + } + } + + setNoticesList(list) { + var data = this.configManager.getData() + data.noticesList = list + this.configManager.setData(data) + return Promise.resolve(true) + } + + markNoticeRead(notice, cb) { + cb = cb || function(err){ if (err) throw err } + try { + var notices = this.getNoticesList() + var id = notice.id + notices[id].read = true + this.setNoticesList(notices) + let latestNotice = this.getLatestUnreadNotice() + cb(null, latestNotice) + } catch (err) { + cb(err) + } + } + + updateNoticesList() { + return this._retrieveNoticeData().then((newNotices) => { + var oldNotices = this.getNoticesList() + var combinedNotices = this._mergeNotices(oldNotices, newNotices) + return Promise.resolve(this.setNoticesList(combinedNotices)) + }) + } + + getLatestUnreadNotice() { + var notices = this.getNoticesList() + var filteredNotices = notices.filter((notice) => { + return notice.read === false + }) + return filteredNotices[filteredNotices.length - 1] + } + + startPolling () { + if (this.noticePoller) { + clearInterval(this.noticePoller) + } + this.noticePoller = setInterval(() => { + this.noticeController.updateNoticesList() + }, 300000) + } + + _mergeNotices(oldNotices, newNotices) { + var noticeMap = this._mapNoticeIds(oldNotices) + newNotices.forEach((notice) => { + if (noticeMap.indexOf(notice.id) === -1) { + oldNotices.push(notice) + } + }) + return oldNotices + } + + _mapNoticeIds(notices) { + return notices.map((notice) => notice.id) + } + + _retrieveNoticeData() { + // Placeholder for the API. + return Promise.resolve(hardCodedNotices) + } + + } -- cgit v1.2.3 From b4a298e1a3d5ad5ede0c1e5bd094c8f867cd6895 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 19 Dec 2016 12:25:35 -0800 Subject: inpage - temporarily disable ping stream --- app/scripts/inpage.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index ef199946c..7d43bd20e 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -2,8 +2,8 @@ cleanContextForImports() require('web3/dist/web3.min.js') const LocalMessageDuplexStream = require('post-message-stream') -const PingStream = require('ping-pong-stream/ping') -const endOfStream = require('end-of-stream') +// const PingStream = require('ping-pong-stream/ping') +// const endOfStream = require('end-of-stream') const setupDappAutoReload = require('./lib/auto-reload.js') const MetamaskInpageProvider = require('./lib/inpage-provider.js') restoreContextAfterImports() @@ -40,13 +40,14 @@ reloadStream.once('data', triggerReload) // setup ping timeout autoreload // LocalMessageDuplexStream does not self-close, so reload if pingStream fails -var pingChannel = inpageProvider.multiStream.createStream('pingpong') -var pingStream = new PingStream({ objectMode: true }) +// var pingChannel = inpageProvider.multiStream.createStream('pingpong') +// var pingStream = new PingStream({ objectMode: true }) // wait for first successful reponse -metamaskStream.once('data', function(){ - pingStream.pipe(pingChannel).pipe(pingStream) -}) -endOfStream(pingStream, triggerReload) +// disable pingStream until https://github.com/MetaMask/metamask-plugin/issues/746 is resolved more gracefully +// metamaskStream.once('data', function(){ +// pingStream.pipe(pingChannel).pipe(pingStream) +// }) +// endOfStream(pingStream, triggerReload) // set web3 defaultAcount inpageProvider.publicConfigStore.subscribe(function (state) { -- cgit v1.2.3 From e9bea92ac3243e58321cd8cf3f44f0df0c66aa70 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Mon, 19 Dec 2016 14:55:52 -0800 Subject: Lint. --- app/scripts/keyring-controller.js | 3 +-- app/scripts/lib/idStore.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index 40c9695dd..ca4c306be 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -73,7 +73,7 @@ module.exports = class KeyringController extends EventEmitter { // or accept a state-resolving promise to consume their results. // // Not all methods end with this, that might be a nice refactor. - fullUpdate() { + fullUpdate () { this.emit('update') return Promise.resolve(this.getState()) } @@ -586,7 +586,6 @@ module.exports = class KeyringController extends EventEmitter { // Attempts to sign the provided @object msgParams. signMessage (msgParams, cb) { try { - const msgId = msgParams.metamaskId delete msgParams.metamaskId const approvalCb = this._unconfMsgCbs[msgId] || noop diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js index d36504f13..cf4353e48 100644 --- a/app/scripts/lib/idStore.js +++ b/app/scripts/lib/idStore.js @@ -258,7 +258,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone function estimateGas (cb) { var estimationParams = extend(txParams) - query.getBlockByNumber('latest', true, function(err, block){ + query.getBlockByNumber('latest', true, function (err, block) { if (err) return cb(err) // check if gasLimit is already specified const gasLimitSpecified = Boolean(txParams.gas) @@ -267,7 +267,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone estimationParams.gas = block.gasLimit } // run tx, see if it will OOG - query.estimateGas(estimationParams, function(err, estimatedGasHex){ + query.estimateGas(estimationParams, function (err, estimatedGasHex) { if (err) return cb(err.message || err) // all gas used - must be an error if (estimatedGasHex === estimationParams.gas) { -- cgit v1.2.3 From 20d2204ce6a9e8dcd3269c588b2f4ce6ff93408b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 19 Dec 2016 16:29:44 -0800 Subject: Made changes according to feedback. --- app/scripts/keyrings/hd.js | 4 ++-- app/scripts/lib/config-manager.js | 3 +-- app/scripts/lib/idStore-migrator.js | 18 +++++++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/keyrings/hd.js b/app/scripts/keyrings/hd.js index 097d995a7..80b713b58 100644 --- a/app/scripts/keyrings/hd.js +++ b/app/scripts/keyrings/hd.js @@ -33,11 +33,11 @@ class HdKeyring extends EventEmitter { this.mnemonic = null this.root = null - if ('mnemonic' in opts) { + if (opts.mnemonic) { this._initFromMnemonic(opts.mnemonic) } - if ('numberOfAccounts' in opts) { + if (opts.numberOfAccounts) { return this.addAccounts(opts.numberOfAccounts) } diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index efc0b4628..d36ccf0db 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -441,6 +441,5 @@ ConfigManager.prototype.setLostAccounts = function (lostAccounts) { ConfigManager.prototype.getLostAccounts = function () { var data = this.getData() - return ('lostAccounts' in data) && data.lostAccounts || [] + return data.lostAccounts || [] } - diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js index 14bd0d8b8..2e9418376 100644 --- a/app/scripts/lib/idStore-migrator.js +++ b/app/scripts/lib/idStore-migrator.js @@ -2,6 +2,7 @@ const IdentityStore = require('./idStore') const HdKeyring = require('../keyrings/hd') const sigUtil = require('./sig-util') const normalize = sigUtil.normalize +const denodeify = require('denodeify') module.exports = class IdentityStoreMigrator { @@ -25,14 +26,13 @@ module.exports = class IdentityStoreMigrator { return Promise.resolve(null) } - return new Promise((resolve, reject) => { - this.idStore.submitPassword(password, (err) => { - if (err) return reject(err) - const serialized = this.serializeVault() - this.checkForErrors(serialized) - .then(resolve) - .catch(reject) - }) + const idStore = this.idStore + const submitPassword = denodeify(idStore.submitPassword.bind(idStore)) + + return submitPassword(password) + .then(() => { + const serialized = this.serializeVault() + return this.checkForLostAccounts(serialized) }) } @@ -46,7 +46,7 @@ module.exports = class IdentityStoreMigrator { } } - checkForErrors (serialized) { + checkForLostAccounts (serialized) { const hd = new HdKeyring() return hd.deserialize(serialized.data) .then((hexAccounts) => { -- cgit v1.2.3 From 26f1e6cbd2af9d6bb0c58871635466c459cc87d8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 19 Dec 2016 21:55:02 -0800 Subject: Remove encryptor in favor of external browser-passworder I broke out the encryptor lib into its own module on npm called browser-passworder. --- app/scripts/keyring-controller.js | 3 +- app/scripts/lib/encryptor.js | 156 -------------------------------------- 2 files changed, 2 insertions(+), 157 deletions(-) delete mode 100644 app/scripts/lib/encryptor.js (limited to 'app/scripts') diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index ca4c306be..58366c26f 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -5,8 +5,9 @@ const bip39 = require('bip39') const Transaction = require('ethereumjs-tx') const EventEmitter = require('events').EventEmitter const filter = require('promise-filter') +const encryptor = require('browser-passworder') + const normalize = require('./lib/sig-util').normalize -const encryptor = require('./lib/encryptor') const messageManager = require('./lib/message-manager') const IdStoreMigrator = require('./lib/idStore-migrator') const BN = ethUtil.BN diff --git a/app/scripts/lib/encryptor.js b/app/scripts/lib/encryptor.js deleted file mode 100644 index 4770d2f54..000000000 --- a/app/scripts/lib/encryptor.js +++ /dev/null @@ -1,156 +0,0 @@ -module.exports = { - - // Simple encryption methods: - encrypt, - decrypt, - - // More advanced encryption methods: - keyFromPassword, - encryptWithKey, - decryptWithKey, - - // Buffer <-> String methods - convertArrayBufferViewtoString, - convertStringToArrayBufferView, - - // Buffer <-> Hex string methods - serializeBufferForStorage, - serializeBufferFromStorage, - - // Buffer <-> base64 string methods - encodeBufferToBase64, - decodeBase64ToBuffer, - - generateSalt, -} - -// Takes a Pojo, returns cypher text. -function encrypt (password, dataObj) { - const salt = this.generateSalt() - - return keyFromPassword(password + salt) - .then(function (passwordDerivedKey) { - return encryptWithKey(passwordDerivedKey, dataObj) - }) - .then(function (payload) { - payload.salt = salt - return JSON.stringify(payload) - }) -} - -function encryptWithKey (key, dataObj) { - var data = JSON.stringify(dataObj) - var dataBuffer = convertStringToArrayBufferView(data) - var vector = global.crypto.getRandomValues(new Uint8Array(16)) - return global.crypto.subtle.encrypt({ - name: 'AES-GCM', - iv: vector, - }, key, dataBuffer).then(function (buf) { - var buffer = new Uint8Array(buf) - var vectorStr = encodeBufferToBase64(vector) - var vaultStr = encodeBufferToBase64(buffer) - return { - data: vaultStr, - iv: vectorStr, - } - }) -} - -// Takes encrypted text, returns the restored Pojo. -function decrypt (password, text) { - const payload = JSON.parse(text) - const salt = payload.salt - return keyFromPassword(password + salt) - .then(function (key) { - return decryptWithKey(key, payload) - }) -} - -function decryptWithKey (key, payload) { - const encryptedData = decodeBase64ToBuffer(payload.data) - const vector = decodeBase64ToBuffer(payload.iv) - return crypto.subtle.decrypt({name: 'AES-GCM', iv: vector}, key, encryptedData) - .then(function (result) { - const decryptedData = new Uint8Array(result) - const decryptedStr = convertArrayBufferViewtoString(decryptedData) - const decryptedObj = JSON.parse(decryptedStr) - return decryptedObj - }) - .catch(function (reason) { - throw new Error('Incorrect password') - }) -} - -function convertStringToArrayBufferView (str) { - var bytes = new Uint8Array(str.length) - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i) - } - - return bytes -} - -function convertArrayBufferViewtoString (buffer) { - var str = '' - for (var i = 0; i < buffer.byteLength; i++) { - str += String.fromCharCode(buffer[i]) - } - - return str -} - -function keyFromPassword (password) { - var passBuffer = convertStringToArrayBufferView(password) - return global.crypto.subtle.digest('SHA-256', passBuffer) - .then(function (passHash) { - return global.crypto.subtle.importKey('raw', passHash, {name: 'AES-GCM'}, false, ['encrypt', 'decrypt']) - }) -} - -function serializeBufferFromStorage (str) { - var stripStr = (str.slice(0, 2) === '0x') ? str.slice(2) : str - var buf = new Uint8Array(stripStr.length / 2) - for (var i = 0; i < stripStr.length; i += 2) { - var seg = stripStr.substr(i, 2) - buf[i / 2] = parseInt(seg, 16) - } - return buf -} - -// Should return a string, ready for storage, in hex format. -function serializeBufferForStorage (buffer) { - var result = '0x' - var len = buffer.length || buffer.byteLength - for (var i = 0; i < len; i++) { - result += unprefixedHex(buffer[i]) - } - return result -} - -function unprefixedHex (num) { - var hex = num.toString(16) - while (hex.length < 2) { - hex = '0' + hex - } - return hex -} - -function encodeBufferToBase64 (buf) { - var b64encoded = btoa(String.fromCharCode.apply(null, buf)) - return b64encoded -} - -function decodeBase64ToBuffer (base64) { - var buf = new Uint8Array(atob(base64).split('') - .map(function (c) { - return c.charCodeAt(0) - })) - return buf -} - -function generateSalt (byteCount = 32) { - var view = new Uint8Array(byteCount) - global.crypto.getRandomValues(view) - var b64encoded = btoa(String.fromCharCode.apply(null, view)) - return b64encoded -} -- cgit v1.2.3 From aea263a80d373841f89cd1ef895b80781d2f78f7 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Tue, 20 Dec 2016 16:45:22 -0800 Subject: Lint. --- app/scripts/notice-controller.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js index 438f5c27e..00c87c670 100644 --- a/app/scripts/notice-controller.js +++ b/app/scripts/notice-controller.js @@ -9,7 +9,7 @@ module.exports = class NoticeController extends EventEmitter { this.noticePoller = null } - getState() { + getState () { var lastUnreadNotice = this.getLatestUnreadNotice() return { @@ -18,7 +18,7 @@ module.exports = class NoticeController extends EventEmitter { } } - getNoticesList() { + getNoticesList () { var data = this.configManager.getData() if ('noticesList' in data) { return data.noticesList @@ -27,28 +27,28 @@ module.exports = class NoticeController extends EventEmitter { } } - setNoticesList(list) { + setNoticesList (list) { var data = this.configManager.getData() data.noticesList = list this.configManager.setData(data) return Promise.resolve(true) } - markNoticeRead(notice, cb) { - cb = cb || function(err){ if (err) throw err } + markNoticeRead (notice, cb) { + cb = cb || function (err) { if (err) throw err } try { var notices = this.getNoticesList() var id = notice.id notices[id].read = true this.setNoticesList(notices) - let latestNotice = this.getLatestUnreadNotice() + const latestNotice = this.getLatestUnreadNotice() cb(null, latestNotice) } catch (err) { cb(err) } } - updateNoticesList() { + updateNoticesList () { return this._retrieveNoticeData().then((newNotices) => { var oldNotices = this.getNoticesList() var combinedNotices = this._mergeNotices(oldNotices, newNotices) @@ -56,7 +56,7 @@ module.exports = class NoticeController extends EventEmitter { }) } - getLatestUnreadNotice() { + getLatestUnreadNotice () { var notices = this.getNoticesList() var filteredNotices = notices.filter((notice) => { return notice.read === false @@ -73,7 +73,7 @@ module.exports = class NoticeController extends EventEmitter { }, 300000) } - _mergeNotices(oldNotices, newNotices) { + _mergeNotices (oldNotices, newNotices) { var noticeMap = this._mapNoticeIds(oldNotices) newNotices.forEach((notice) => { if (noticeMap.indexOf(notice.id) === -1) { @@ -83,11 +83,11 @@ module.exports = class NoticeController extends EventEmitter { return oldNotices } - _mapNoticeIds(notices) { + _mapNoticeIds (notices) { return notices.map((notice) => notice.id) } - _retrieveNoticeData() { + _retrieveNoticeData () { // Placeholder for the API. return Promise.resolve(hardCodedNotices) } -- cgit v1.2.3