From 567cb8c713338c6191a3d599d9472a7f8c81b936 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Fri, 24 Oct 2014 09:36:28 -0300 Subject: [PATCH] remove storage from Wallet --- Gruntfile.js | 1 + config.js | 2 +- js/models/Identity.js | 56 +++++++++++---- js/models/Passphrase.js | 2 - js/models/Profile.js | 7 +- js/models/Wallet.js | 134 ++++++++++++----------------------- js/services/notifications.js | 2 +- js/util/crypto.js | 4 +- 8 files changed, 92 insertions(+), 116 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 41b8a3c8b..2955fd54e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -55,6 +55,7 @@ module.exports = function(grunt) { scripts: { files: [ 'js/models/*.js', + 'js/util/*.js', 'plugins/*.js', 'js/*.js', '!js/copayBundle.js', diff --git a/config.js b/config.js index 06525ab1e..edde35bd6 100644 --- a/config.js +++ b/config.js @@ -56,7 +56,7 @@ var defaultConfig = { plugins: { LocalStorage: true, //GoogleDrive: true, - InsightStorage: true + //InsightStorage: true }, InsightStorage: { diff --git a/js/models/Identity.js b/js/models/Identity.js index c33196134..6bc46b626 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -64,10 +64,6 @@ Identity._walletFromObj = function(o, readOpts) { return Wallet.fromObj(o, readOpts); }; -Identity._walletRead = function(id, r, cb) { - return Wallet.read(id, r, cb); -}; - Identity._walletDelete = function(id, s, cb) { return Wallet.delete(id, s, cb); }; @@ -105,7 +101,11 @@ Identity._getStorage = function(opts, password) { */ Identity.anyProfile = function(opts, cb) { var storage = Identity._getStorage(opts); - Profile.any(storage, cb); + storage.getFirst(Profile.key(''), { + onlyKey: true + }, function(err, v, k) { + return cb(k ? true : false); + }); }; /** @@ -116,7 +116,11 @@ Identity.anyProfile = function(opts, cb) { */ Identity.anyWallet = function(opts, cb) { var storage = Identity._getStorage(opts); - Wallet.any(storage, cb); + storage.getFirst(Wallet.getStorageKey(''), { + onlyKey: true + }, function(err, v, k) { + return cb(k ? true : false); + }); }; /** @@ -249,12 +253,41 @@ Identity.isAvailable = function(email, opts, cb) { return cb(); }; +Identity.prototype.readWallet = function(walletId, readOpts, cb) { + preconditions.checkArgument(cb); + var self = this, + err; + var obj = {}; + + this.storage.getFirst(Wallet.getStorageKey(walletId), {}, function(err, obj) { + if (err) return cb(err); + + if (!obj) + return cb(new Error('WNOTFOUND: Wallet not found')); + + var w, err; + obj.id = walletId; + + try { + log.debug('## OPENING Wallet: ' + walletId); + w = Wallet.fromUntrustedObj(obj, readOpts); + } catch (e) { + log.debug("ERROR: ", e.message); + if (e && e.message && e.message.indexOf('MISSOPTS')) { + err = new Error('WERROR: Could not read: ' + walletId + ': ' + e.message); + } else { + err = e; + } + w = null; + } + return cb(err, w); + }); +}; Identity.prototype.storeWallet = function(w, cb) { preconditions.checkArgument(w && _.isObject(w)); var id = w.getId(); - var val = w.toObj(); var key = Wallet.getStorageKey(id + '_' + w.getName()); @@ -264,7 +297,6 @@ Identity.prototype.storeWallet = function(w, cb) { if (cb) cb(err); }); - }; @@ -343,7 +375,6 @@ Identity.prototype.importWallet = function(base64, password, skipFields, cb) { var obj = this.storage.decrypt(base64, password); var readOpts = { - storage: this.storage, networkOpts: this.networkOpts, blockchainOpts: this.blockchainOpts, skipFields: skipFields @@ -509,7 +540,6 @@ Identity.prototype.createWallet = function(opts, cb) { log.debug('\t### TxProposals Initialized'); - opts.storage = this.storage; opts.networkOpts = this.networkOpts; opts.blockchainOpts = this.blockchainOpts; @@ -519,9 +549,6 @@ Identity.prototype.createWallet = function(opts, cb) { opts.totalCopayers = totalCopayers; opts.version = opts.version || this.version; - if (opts.password && !this.storage.hasPassphrase()) - this.storage.setPassword(opts.password); - var self = this; var w = Identity._newWallet(opts); this.addWallet(w, function(err) { @@ -592,8 +619,7 @@ Identity.prototype.openWallet = function(walletId, cb) { // self.migrateWallet(walletId, password, function() { // - Identity._walletRead(walletId, { - storage: self.storage, + self.readWallet(walletId, { networkOpts: this.networkOpts, blockchainOpts: this.blockchainOpts }, function(err, w) { diff --git a/js/models/Passphrase.js b/js/models/Passphrase.js index d3cd0853b..c57ee6662 100644 --- a/js/models/Passphrase.js +++ b/js/models/Passphrase.js @@ -6,8 +6,6 @@ // this line throws a warning on Chrome Desktop var sjcl = require('../../lib/sjcl'); - -console.log('[Passphrase.js.8]'); //TODO var preconditions = require('preconditions').instance(); var _ = require('underscore'); diff --git a/js/models/Profile.js b/js/models/Profile.js index babab434c..aeb2d6d79 100644 --- a/js/models/Profile.js +++ b/js/models/Profile.js @@ -46,17 +46,12 @@ Profile.create = function(email, password, storage, cb) { }; -Profile.any = function(storage, cb) { - storage.getFirst(Profile.key(''), { onlyKey: true}, function(err, v, k) { - return cb(k ? true : false); - }); -}; - Profile.open = function(email, password, storage, cb) { preconditions.checkArgument(cb); preconditions.checkState(storage.hasPassphrase()); var key = Profile.key(Profile.hash(email, password)); +console.log('[Profile.js.59:key:]',key); //TODO storage.get(key, function(err, val) { if (err || !val) return cb(new Error('PNOTFOUND: Profile not found')); diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 83b815600..8ffcb34e7 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -37,7 +37,6 @@ var copayConfig = require('../../config'); * @TODO: Split this leviathan. * * @param {Object} opts - * @param {Storage} opts.storage - an object that can persist the wallet * @param {Network} opts.network - used to send and retrieve messages from * copayers * @param {Blockchain} opts.blockchain - source of truth for what happens in @@ -70,7 +69,7 @@ function Wallet(opts) { opts.blockchain = opts.blockchain || Wallet._newInsight(opts.blockchainOpts[networkName]);; //required params - ['storage', 'network', 'blockchain', + ['network', 'blockchain', 'requiredCopayers', 'totalCopayers', 'spendUnconfirmed', 'publicKeyRing', 'txProposals', 'privateKey', 'version', 'reconnectDelay' @@ -82,7 +81,8 @@ function Wallet(opts) { this.id = opts.id || Wallet.getRandomId(); this.secretNumber = opts.secretNumber || Wallet.getRandomSecretNumber(); - this.lock = new WalletLock(this.storage, this.id, opts.lockTimeOutMin); + // TODO + // this.lock = new WalletLock(this.storage, this.id, opts.lockTimeOutMin); this.settings = opts.settings || copayConfig.wallet.settings; this.name = opts.name; @@ -121,9 +121,9 @@ function Wallet(opts) { inherits(Wallet, events.EventEmitter); Wallet.prototype.emitAndKeepAlive = function(args) { - log.debug('Wallet Emitting:',arguments); + log.debug('Wallet Emitting:', arguments); this.keepAlive(); - this.emit.apply(this,arguments); + this.emit.apply(this, arguments); }; /** @@ -179,13 +179,6 @@ Wallet.getStorageKey = function(str) { return 'wallet::' + str; }; - -Wallet.any = function(storage, cb) { - storage.getFirst(Wallet.getStorageKey(''), { onlyKey: true}, function(err, v, k) { - return cb(k ? true : false); - }); -}; - /* for stubbing */ Wallet._newInsight = function(opts) { return new Insight(opts); @@ -234,65 +227,17 @@ Wallet.getMaxRequiredCopayers = function(totalCopayers) { * @param cb * @return {undefined} */ -Wallet.delete = function(walletId, storage, cb) { - preconditions.checkArgument(cb); - storage.deletePrefix(Wallet.getStorageKey(walletId), function(err) { - if (err && err.message != 'not found') return cb(err); - storage.deletePrefix(walletId + '::', function(err) { - if (err && err.message != 'not found') return cb(err); - return cb(); - }); - }); -}; - -/** - * @desc Retrieve a wallet from storage - * - * @param {string} walletId - the wallet id - * @param readOpts (see fromObj) - * @param {function} callback - {err, Wallet} - * @return {undefined} - */ -Wallet.read = function(walletId, readOpts, cb) { - preconditions.checkArgument(readOpts); - preconditions.checkArgument(readOpts.storage); - preconditions.checkArgument(readOpts.storage.setPassword); - preconditions.checkArgument(cb); - - var storage = readOpts.storage; - - var self = this, - err; - var obj = {}; - - storage.getFirst(Wallet.getStorageKey(walletId), {}, function(err, ret) { - if (err) return cb(err); - - if (!ret) - return cb(new Error('WNOTFOUND: Wallet not found')); - - _.each(Wallet.PERSISTED_PROPERTIES, function(p) { - obj[p] = ret[p]; - }); - - var w, err; - obj.id = walletId; - try { - log.debug('## OPENING Wallet: ' + walletId); - w = self.fromObj(obj, readOpts); - } catch (e) { - log.debug("ERROR: ", e.message); - if (e && e.message && e.message.indexOf('MISSOPTS')) { - err = new Error('WERROR: Could not read: ' + walletId + ': ' + e.message); - } else { - err = e; - } - w = null; - } - return cb(err, w); - }); -}; - +// Wallet.delete = function(walletId, storage, cb) { +// preconditions.checkArgument(cb); +// storage.deletePrefix(Wallet.getStorageKey(walletId), function(err) { +// if (err && err.message != 'not found') return cb(err); +// storage.deletePrefix(walletId + '::', function(err) { +// if (err && err.message != 'not found') return cb(err); +// return cb(); +// }); +// }); +// }; +// /** @@ -1024,12 +969,13 @@ Wallet.prototype.getRegisteredPeerIds = function() { Wallet.prototype.keepAlive = function() { var self = this; - this.lock.keepAlive(function(err) { - if (err) { - log.debug(err); - self.emitAndKeepAlive('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); - } - }); + + // this.lock.keepAlive(function(err) { + // if (err) { + // log.debug(err); + // self.emitAndKeepAlive('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); + // } + // }); }; @@ -1061,6 +1007,19 @@ Wallet.prototype.toObj = function() { return walletObj; }; + +Wallet.fromUntrustedObj = function(obj, readOpts) { + obj = _.clone(obj); + var o = {}; + _.each(Wallet.PERSISTED_PROPERTIES, function(p) { + o[p] = obj[p]; + }); + + return Wallet.fromObj(o,readOpts); +}; + + + /** * @desc Retrieve the wallet state from a trusted object * @@ -1073,7 +1032,6 @@ Wallet.prototype.toObj = function() { * @param {Object} o.txProposals - TxProposals to be deserialized by {@link TxProposals#fromObj} * @param {string} o.nickname - user's nickname * - * @param readOpts.storage * @param readOpts.network * @param readOpts.blockchain * @param readOpts.isImported {boolean} - tag wallet as 'imported' (skip forced backup step) @@ -1083,9 +1041,7 @@ Wallet.fromObj = function(o, readOpts) { preconditions.checkArgument(readOpts.networkOpts); preconditions.checkArgument(readOpts.blockchainOpts); - preconditions.checkArgument(readOpts.storage.setPassword); - var storage = readOpts.storage; var networkOpts = readOpts.networkOpts; var blockchainOpts = readOpts.blockchainOpts; var skipFields = readOpts.skipFields || []; @@ -1147,7 +1103,6 @@ Wallet.fromObj = function(o, readOpts) { opts.lastTimestamp = o.lastTimestamp || 0; - opts.storage = storage; opts.blockchainOpts = readOpts.blockchainOpts; opts.networkOpts = readOpts.networkOpts; opts.isImported = readOpts.isImported || false; @@ -1159,10 +1114,10 @@ Wallet.fromObj = function(o, readOpts) { * @desc Return a base64 encrypted version of the wallet * @return {string} base64 encoded string */ -Wallet.prototype.export = function() { - var walletObj = this.toObj(); - return this.storage.encrypt(walletObj); -}; +// Wallet.prototype.export = function() { +// var walletObj = this.toObj(); +// return this.storage.encrypt(walletObj); +// }; /** * @desc Send a message to other peers @@ -1817,7 +1772,7 @@ Wallet.prototype.sendPaymentTx = function(ntxid, options, cb) { log.debug('XHR status: ' + status); return self._checkSentTx(ntxid, function(txid) { log.debug('[Wallet.js.1581:txid:%s]', txid); - if (txid) + if (txid) self.emitAndKeepAlive('hasChange'); return cb(txid, txp.merchant); }); @@ -1850,7 +1805,7 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { log.debug('Sending to server was not met with a returned tx.'); return this._checkSentTx(ntxid, function(txid) { log.debug('[Wallet.js.1613:txid:%s]', txid); - if (txid) + if (txid) self.emitAndKeepAlive('hasChange'); return cb(txid, txp.merchant); }); @@ -2613,9 +2568,10 @@ Wallet.prototype.close = function(cb) { this.blockchain.destroy(); log.debug('## CLOSING Wallet: ' + this.id); - this.lock.release(function() { +// TODO +// this.lock.release(function() { if (cb) return cb(); - }); +// }); }; /** diff --git a/js/services/notifications.js b/js/services/notifications.js index c8efdbabc..d69658382 100644 --- a/js/services/notifications.js +++ b/js/services/notifications.js @@ -47,7 +47,7 @@ factory('notification', ['$timeout', }; function html5Notify(icon, title, content, ondisplay, onclose) { - if (window.webkitNotifications.checkPermission() === 0) { + if (window.webkitNotifications && window.webkitNotifications.checkPermission() === 0) { if (!icon) { icon = 'img/favicon.ico'; } diff --git a/js/util/crypto.js b/js/util/crypto.js index dd5cf8aff..1a55dc57a 100644 --- a/js/util/crypto.js +++ b/js/util/crypto.js @@ -1,7 +1,7 @@ /** - * Small module for some helpers that wrap CryptoJS with some good practices. + * Small module for some helpers that wrap sjcl with some good practices. */ -var sjcl = require('sjcl'); +var sjcl = require('../../lib/sjcl'); var log = require('../log.js'); var _ = require('underscore');