From 7781b93a88b1c0706fb4911d632325b3f95d8d60 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 5 Jun 2016 16:27:49 -0300 Subject: [PATCH 1/7] add disclaimer controller test --- public/views/disclaimer.html | 4 +- src/js/controllers/disclaimer.js | 42 +++++++++------- src/js/services/profileService.js | 17 +++++-- test/controllers/disclaimer.test.js | 78 +++++++++++++++++++++++++++++ test/helpers.js | 3 ++ 5 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 test/controllers/disclaimer.test.js diff --git a/public/views/disclaimer.html b/public/views/disclaimer.html index d0a02d7c8..f8e233397 100644 --- a/public/views/disclaimer.html +++ b/public/views/disclaimer.html @@ -25,14 +25,14 @@
-
+
Creating Wallet...
-
diff --git a/src/js/controllers/disclaimer.js b/src/js/controllers/disclaimer.js index 9d56c1d26..c08afb327 100644 --- a/src/js/controllers/disclaimer.js +++ b/src/js/controllers/disclaimer.js @@ -4,45 +4,53 @@ angular.module('copayApp.controllers').controller('disclaimerController', function($scope, $timeout, $log, $ionicSideMenuDelegate, profileService, applicationService, gettextCatalog, uxLanguage, go) { var self = this; self.tries = 0; - $scope.creatingProfile = true; + self.creatingProfile = true; - var create = function(noWallet) { - profileService.create({ - noWallet: noWallet - }, function(err) { + var create = function(opts) { + opts = opts || {}; + $log.debug('Creating profile'); + profileService.create(opts, function(err) { + console.log('[disclaimer.js.13]', err); //TODO if (err) { $log.warn(err); $scope.error = err; $scope.$apply(); - $timeout(function() { + + return $timeout(function() { $log.warn('Retrying to create profile......'); if (self.tries == 3) { self.tries == 0; - create(true); + return create({ + noWallet: true + }); } else { self.tries += 1; - create(false); + return create(); } }, 3000); - } else { - $scope.error = ""; - $scope.creatingProfile = false; - } + }; + + $scope.error = ""; + self.creatingProfile = false; + + console.log('[disclaimer.js.33]'); //TODO }); }; - this.init = function() { - + this.init = function(opts) { $ionicSideMenuDelegate.canDragContent(false); self.lang = uxLanguage.currentLanguage; profileService.getProfile(function(err, profile) { if (!profile) { - create(false); + + console.log('[disclaimer.js.43]'); //TODO + create(opts); + console.log('[disclaimer.js.46]'); //TODO } else { - $log.debug('There is a profile already'); - $scope.creatingProfile = false; + $log.info('There is already a profile'); + self.creatingProfile = false; profileService.bindProfile(profile, function(err) { if (!err || !err.message || !err.message.match('NONAGREEDDISCLAIMER')) { $log.debug('Disclaimer already accepted at #disclaimer. Redirect to Wallet Home.'); diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index f14acff19..8dbfd9c1c 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -224,6 +224,7 @@ angular.module('copayApp.services') root._seedWallet = function(opts, cb) { opts = opts || {}; + $log.debug('seedWallet', opts); var walletClient = bwcService.getClient(null, opts); var network = opts.networkName || 'livenet'; @@ -291,13 +292,15 @@ angular.module('copayApp.services') return cb(null, Profile.create()); } - root._seedWallet({}, function(err, walletClient) { + root._seedWallet(opts, function(err, walletClient) { if (err) return cb(err); var walletName = gettextCatalog.getString('Personal Wallet'); var me = gettextCatalog.getString('me'); + walletClient.createWallet(walletName, me, 1, 1, { - network: 'livenet' + network: 'livenet', + walletPrivKey: opts.walletPrivKey, }, function(err) { if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb); var p = Profile.create({ @@ -559,16 +562,24 @@ angular.module('copayApp.services') }; root.create = function(opts, cb) { - $log.info('Creating profile'); + $log.info('Creating profile', opts); var defaults = configService.getDefaults(); +console.log('[profileService.js.567]'); //TODO configService.get(function(err) { + +console.log('[profileService.js.570]'); //TODO root._createNewProfile(opts, function(err, p) { if (err) return cb(err); +console.log('[profileService.js.574]'); //TODO root.bindProfile(p, function(err) { + +console.log('[profileService.js.577]'); //TODO // ignore NONAGREEDDISCLAIMER storageService.storeNewProfile(p, function(err) { + +console.log('[profileService.js.581]'); //TODO return cb(err); }); }); diff --git a/test/controllers/disclaimer.test.js b/test/controllers/disclaimer.test.js new file mode 100644 index 000000000..78f7c4cbd --- /dev/null +++ b/test/controllers/disclaimer.test.js @@ -0,0 +1,78 @@ +describe.only('disclaimerController', function() { + var walletService; + var storeProfile; + + var fixtures = { + '8dc332881e99c908c655147dc6bc605e102b0bd3cf2dbee02ed2a0f4daf2925a': { + "walletId": "eddaef15-f412-462f-9d3e-a793a7f6f6ba" + }, + '654145bc3f15f03a8b1ccf55aa1bdcd1cfd5bbe3de90e909fd4e7f9f69ec4d79': { + "copayerId": "1a91ead1b6d13da882a25377a20e460df557e77008ea4f60eecbf984f786cf03", + "wallet": { + "version": "1.0.0", + "createdOn": 1465152783, + "id": "eddaef15-f412-462f-9d3e-a793a7f6f6ba", + "name": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"/gaG7FIkhCiwsWKZUR0sL/cxH+zHMK0=\"}", + "m": 1, + "n": 1, + "status": "complete", + "publicKeyRing": [{ + "xPubKey": "xpub6Cb7MYAX7mJR28MfFueCsoDVVHhoWkQxRC4viAeHanYwRNgDo5xMF42xmAeExzfyPXX3GaALNA8hWFMekVYvDF2BALommUhMgZ52szh88fd", + "requestPubKey": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd" + }], + "copayers": [{ + "version": 2, + "createdOn": 1465152783, + "xPubKey": "xpub6Cb7MYAX7mJR28MfFueCsoDVVHhoWkQxRC4viAeHanYwRNgDo5xMF42xmAeExzfyPXX3GaALNA8hWFMekVYvDF2BALommUhMgZ52szh88fd", + "id": "1a91ead1b6d13da882a25377a20e460df557e77008ea4f60eecbf984f786cf03", + "name": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"wwZd+2LQgYR6cA==\"}", + "requestPubKey": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd", + "signature": "3045022100ac3f31ef145eabde6a125958aa9d63c2bd4aa27717d7f6905c3e3ff1e733ee8e02206a43200b775ee5c8f7a85c4d3309d155240d5de46a7d9c5e60045bf49779f40b", + "requestPubKeys": [{ + "key": "029a167eebe3ccd9987d41743477f8b75e1f3c30463187e1b106e0cc1155efa4dd", + "signature": "3045022100ac3f31ef145eabde6a125958aa9d63c2bd4aa27717d7f6905c3e3ff1e733ee8e02206a43200b775ee5c8f7a85c4d3309d155240d5de46a7d9c5e60045bf49779f40b" + }], + "customData": "{\"iv\":\"BZQVWAP6d1e4G8Fq1rQKbA==\",\"v\":1,\"iter\":1,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"ct\":\"9l63hoVnA71LshCC5xbOTHA+ivBzux7u8SAci56p4aaVIF4qzXQhQKFX+sAFGfBjULm/E1st6awdXnxbAgjbF7D0zsbBFLFOSCw+ko5Xc6o=\"}" + }], + "pubKey": "026d95bb5cc2a30c19e22379ae78b4757aaa2dd0ccbd15a1db054fb50cb98ed361", + "network": "livenet", + "derivationStrategy": "BIP44", + "addressType": "P2PKH", + "addressManager": { + "version": 2, + "derivationStrategy": "BIP44", + "receiveAddressIndex": 0, + "changeAddressIndex": 0, + "copayerIndex": 2147483647 + }, + "scanStatus": null + } + }, + }; // TODO: Read from file + + beforeEach(function(done) { + mocks.init(fixtures, 'disclaimerController', { + initController: true, + noDisclaimer: true, + }, done); + }) + + afterEach(function(done) { + mocks.clear({}, done); + }); + + // it('should be defined', function() { + // should.exist(ctrl); + // }); + + it('should create the initial profile', function(done) { + localStorage.clear(); + ctrl.init({ + walletPrivKey: 'Kz4CFSTgLzoYfMkt97BTBotUbZYXjMts6Ej9HbVfCf5oLmun1BXy', + mnemonic: 'tunnel fork scare industry noble snow tank bullet over gesture nuclear next', + }); + setTimeout(function() { + done(); + }, 1000); + }); +}); diff --git a/test/helpers.js b/test/helpers.js index 19c15b632..22fc6135c 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -220,6 +220,9 @@ mocks.init = function(fixtures, controllerName, opts, done) { noWallet: true }, function(err) { should.not.exist(err, err); + if (opts.noDisclaimer){ + return done(); + }; _profileService_.setDisclaimerAccepted(function() { if (!opts.initController) startController(); From 4865ea8ad8bd14c64e13bdd7b96b770e191a4af0 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 6 Jun 2016 12:21:15 -0300 Subject: [PATCH 2/7] refactor profileService --- src/js/controllers/copayers.js | 6 +- src/js/controllers/create.js | 2 +- src/js/controllers/disclaimer.js | 7 - src/js/controllers/index.js | 54 +++-- src/js/controllers/preferencesDelete.js | 8 +- src/js/controllers/preferencesEmail.js | 2 +- src/js/models/profile.js | 42 ++++ src/js/services/profileService.js | 295 ++++++++++++------------ src/js/services/storageService.js | 37 ++- 9 files changed, 245 insertions(+), 208 deletions(-) diff --git a/src/js/controllers/copayers.js b/src/js/controllers/copayers.js index a4fcb5b91..f44fda311 100644 --- a/src/js/controllers/copayers.js +++ b/src/js/controllers/copayers.js @@ -54,15 +54,15 @@ angular.module('copayApp.controllers').controller('copayersController', modalInstance.result.then(function(ok) { if (ok) { - _deleteWallet(); + doDeleteWallet(); } }); }; - var _deleteWallet = function() { + var doDeleteWallet = function() { var fc = profileService.focusedClient; var walletName = fc.credentials.walletName; - profileService.deleteWalletFC({}, function(err) { + profileService.deleteWalletClient(fc, function(err) { if (err) { self.error = err.message || err; $timeout(function() { diff --git a/src/js/controllers/create.js b/src/js/controllers/create.js index 815d796f9..fdb445c55 100644 --- a/src/js/controllers/create.js +++ b/src/js/controllers/create.js @@ -169,7 +169,7 @@ angular.module('copayApp.controllers').controller('createController', self.loading = true; $timeout(function() { - profileService.createWallet(opts, function(err, walletId) { + profileService.createWallet(opts, function(err) { self.loading = false; if (err) { $log.warn(err); diff --git a/src/js/controllers/disclaimer.js b/src/js/controllers/disclaimer.js index c08afb327..1aaf06e07 100644 --- a/src/js/controllers/disclaimer.js +++ b/src/js/controllers/disclaimer.js @@ -10,8 +10,6 @@ angular.module('copayApp.controllers').controller('disclaimerController', opts = opts || {}; $log.debug('Creating profile'); profileService.create(opts, function(err) { - - console.log('[disclaimer.js.13]', err); //TODO if (err) { $log.warn(err); $scope.error = err; @@ -33,8 +31,6 @@ angular.module('copayApp.controllers').controller('disclaimerController', $scope.error = ""; self.creatingProfile = false; - - console.log('[disclaimer.js.33]'); //TODO }); }; @@ -44,10 +40,7 @@ angular.module('copayApp.controllers').controller('disclaimerController', profileService.getProfile(function(err, profile) { if (!profile) { - - console.log('[disclaimer.js.43]'); //TODO create(opts); - console.log('[disclaimer.js.46]'); //TODO } else { $log.info('There is already a profile'); self.creatingProfile = false; diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 1649519aa..6c4935ddb 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -284,9 +284,10 @@ angular.module('copayApp.controllers').controller('indexController', function($r }; + // TODO: should not be in index.js self.updateRemotePreferences = function(opts, cb) { + var clients; var prefs = opts.preferences || {}; - var fc = profileService.focusedClient; // Update this JIC. var config = configService.getSync().wallet.settings; @@ -295,24 +296,20 @@ angular.module('copayApp.controllers').controller('indexController', function($r prefs.language = self.defaultLanguageIsoCode; prefs.unit = config.unitCode; - var clients = []; - if (opts.saveAll) { - clients = lodash.values(profileService.walletClients); + + if (opts.client) { + clients = [opts.client]; } else { - clients = [fc]; + clients = lodash.values(profileService.walletClients); }; self._updateRemotePreferencesFor(clients, prefs, function(err) { if (err) return cb(err); - if (!fc) return cb(); - fc.getPreferences(function(err, preferences) { - if (err) { - return cb(err); - } - self.preferences = preferences; - return cb(); + lodash.each(clients, function(c) { + c.preferences = lodash.assign(prefs, c.preferences); }); + return cb(); }); }; @@ -1055,7 +1052,9 @@ angular.module('copayApp.controllers').controller('indexController', function($r return; } - profileService.setWalletClients(); + profileService.addWalletClient(fc, { + force: true + }); self.startScan(self.walletId); }); }; @@ -1513,9 +1512,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r $rootScope.$on('Local/ProfileBound', function() { storageService.getRemotePrefsStoredFlag(function(err, val) { if (err || val) return; - self.updateRemotePreferences({ - saveAll: true - }, function() { + self.updateRemotePreferences({}, function() { $log.debug('Remote preferences saved'); storageService.setRemotePrefsStoredFlag(function() {}); }); @@ -1524,9 +1521,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r $rootScope.$on('Local/LanguageSettingUpdated', function() { self.setUxLanguage(function() { - self.updateRemotePreferences({ - saveAll: true - }, function() { + self.updateRemotePreferences({}, function() { $log.debug('Remote preferences saved') }); }); @@ -1558,15 +1553,14 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.updateAll({ triggerTxUpdate: true, }); - self.updateRemotePreferences({ - saveAll: true - }, function() { + self.updateRemotePreferences({}, function() { $log.debug('Remote preferences saved') }); }); - $rootScope.$on('Local/EmailSettingUpdated', function(event, email, cb) { + $rootScope.$on('Local/EmailSettingUpdated', function(event, client, email, cb) { self.updateRemotePreferences({ + client: client, preferences: { email: email || null }, @@ -1582,11 +1576,14 @@ angular.module('copayApp.controllers').controller('indexController', function($r } }); - $rootScope.$on('Local/ProfileCreated', function(event) { - self.updateRemotePreferences({ - saveAll: true - }, function() { - $log.debug('Remote preferences saved'); + + lodash.each(['Local/ProfileCreated', 'Local/WalletListUpdated'], function(eventName) { + $rootScope.$on(eventName, function(event, client) { + self.updateRemotePreferences({ + client: client + }, function() { + $log.debug('Remote preferences saved'); + }); }); }); @@ -1743,6 +1740,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); $rootScope.$on('Local/NoWallets', function(event) { + $log.debug('Event: NoWallets'); $timeout(function() { self.hasProfile = true; diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js index e176fc5c6..8a0046083 100644 --- a/src/js/controllers/preferencesDelete.js +++ b/src/js/controllers/preferencesDelete.js @@ -40,19 +40,19 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro modalInstance.result.then(function(ok) { if (ok) { - _deleteWallet(); + doDeleteWallet(); } }); }; - var _deleteWallet = function() { + var doDeleteWallet = function() { $scope.isDeletingWallet = true; var fc = profileService.focusedClient; var name = fc.credentials.walletName; var walletName = (fc.alias || '') + ' [' + name + ']'; var self = this; - profileService.deleteWalletFC({}, function(err) { + profileService.deleteWalletClient(fc, function(err) { $scope.isDeletingWallet = false; if (err) { self.error = err.message || err; @@ -72,7 +72,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro delete_msg, function(buttonIndex) { if (buttonIndex == 1) { - _deleteWallet(); + doDeleteWallet(); } }, confirm_msg, [accept_msg, cancel_msg] diff --git a/src/js/controllers/preferencesEmail.js b/src/js/controllers/preferencesEmail.js index dbdc02158..3f29224af 100644 --- a/src/js/controllers/preferencesEmail.js +++ b/src/js/controllers/preferencesEmail.js @@ -8,7 +8,7 @@ angular.module('copayApp.controllers').controller('preferencesEmailController', var fc = profileService.focusedClient; this.saving = true; - $scope.$emit('Local/EmailSettingUpdated', self.email, function() { + $scope.$emit('Local/EmailSettingUpdated', fc,self.email, function() { self.saving = false; go.path('preferences'); }); diff --git a/src/js/models/profile.js b/src/js/models/profile.js index 4e808fdee..d0bab451f 100644 --- a/src/js/models/profile.js +++ b/src/js/models/profile.js @@ -27,6 +27,7 @@ Profile.fromObj = function(obj) { x.credentials = obj.credentials; x.disclaimerAccepted = obj.disclaimerAccepted; x.checked = obj.checked || {}; + x.checkedUA = null; if (x.credentials[0] && typeof x.credentials[0] != 'object') throw ("credentials should be an object"); @@ -41,3 +42,44 @@ Profile.fromString = function(str) { Profile.prototype.toObj = function() { return JSON.stringify(this); }; + + +Profile.prototype.hasWallet = function(walletId) { + for (var i in this.credentials) { + var c = this.credentials[i]; + if (c.walletId == walletId) return true; + }; + return false; +}; + +Profile.prototype.isChecked = function(ua, walletId) { + return this.checkedUA == ua && this.checked[walletId]; +}; + +Profile.prototype.setChecked = function(ua, walletId) { + if (this.checkedUA != ua) { + this.checkedUA = ua; + this.checked = {}; + } + this.checked[walletId] = true; +}; + + +Profile.prototype.addWallet = function(credentials) { + if (this.hasWallet(credentials.walletId)) + return false; + + this.credentials.push(credentials); + return true; +}; + +Profile.prototype.deleteWallet = function(walletId) { + if (!this.hasWallet(walletId)) + return false; + + this.credentials = this.credentials.filter(function(c) { + return c.walletId != walletId; + }); + + return true; +}; diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index 8dbfd9c1c..09a0f512b 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -62,36 +62,26 @@ angular.module('copayApp.services') }); }; - root.setWalletClient = function(credentials) { - if (root.walletClients[credentials.walletId] && - root.walletClients[credentials.walletId].started) { - return; + // Adds a wallet client to profileService + root.bindWalletClient = function(client, opts) { + var opts = opts || {}; + var walletId = client.credentials.walletId; + + if ((root.walletClients[walletId] && root.walletClients[walletId].started) + || opts.force) { + return false; } - - var getBaseURL = function(walletId) { - var config = configService.getSync(); - var defaults = configService.getDefaults(); - - return ((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url); - }; - - $log.debug('Importing wallet:' + credentials.walletId); - var skipKeyValidation = root.profile.checked[credentials.walletId] == platformInfo.ua; - var client = bwcService.getClient(JSON.stringify(credentials), { - baseurl: getBaseURL(credentials.walletId), - skipKeyValidation: skipKeyValidation, - }); - root.walletClients[credentials.walletId] = client; + root.walletClients[walletId] = client; + root.walletClients[walletId].started = true; + root.walletClients[walletId].doNotVerifyPayPro = isChromeApp; if (client.incorrectDerivation) { - $log.warn('Key Derivation failed for wallet:' + credentials.walletId); - storageService.clearLastAddress(credentials.walletId, function() {}); - } else if (!skipKeyValidation) { - root.profile.checked[credentials.walletId] = platformInfo.ua; - storageService.storeProfileThrottled(root.profile, function() {}); + $log.warn('Key Derivation failed for wallet:' + walletId); + storageService.clearLastAddress(walletId, function() {}); } + client.removeAllListeners(); client.on('report', function(n) { $log.info('BWC Report:' + n); @@ -100,9 +90,9 @@ angular.module('copayApp.services') client.on('notification', function(n) { $log.debug('BWC Notification:', n); notificationService.newBWCNotification(n, - client.credentials.walletId, client.credentials.walletName); + walletId, client.credentials.walletName); - if (root.focusedClient.credentials.walletId == client.credentials.walletId) { + if (root.focusedClient.credentials.walletId == walletId) { $rootScope.$emit(n.type, n); } else { $rootScope.$apply(); @@ -113,16 +103,12 @@ angular.module('copayApp.services') $log.debug('Wallet completed'); root.updateCredentialsFC(function() { - $rootScope.$emit('Local/WalletCompleted', client.credentials.walletId); + $rootScope.$emit('Local/WalletCompleted', walletId); }); - }); - root.walletClients[credentials.walletId].started = true; - root.walletClients[credentials.walletId].doNotVerifyPayPro = isChromeApp; - if (client.hasPrivKeyEncrypted() && !client.isPrivKeyEncrypted()) { - $log.warn('Auto locking unlocked wallet:' + credentials.walletId); + $log.warn('Auto locking unlocked wallet:' + walletId); client.lock(); } @@ -133,15 +119,35 @@ angular.module('copayApp.services') } client.setNotificationsInterval(BACKGROUND_UPDATE_PERIOD); }); - } - root.setWalletClients = function() { - var credentials = root.profile.credentials; - lodash.each(credentials, function(credential) { - //$log.info("Credentials:", credentials); - root.setWalletClient(credential); + return true; + }; + + + // Used when reading wallets from the profile + root.bindWallet = function(credentials) { + if (!credentials.walletId) + throw 'bindWallet should receive credentials JSON'; + + $log.debug('Bind wallet:' + credentials.walletId); + + // Create the client + var getBaseURL = function(walletId) { + var config = configService.getSync(); + var defaults = configService.getDefaults(); + return ((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url); + }; + + var skipKeyValidation = root.profile.isChecked(platformInfo.ua, credentials.walletId); + var client = bwcService.getClient(JSON.stringify(credentials), { + baseurl: getBaseURL(credentials.walletId), + skipKeyValidation: skipKeyValidation, }); - $rootScope.$emit('Local/WalletListUpdated'); + + if (!skipKeyValidation && !client.incorrectDerivation) + root.profile.setChecked(platformInfo.ua, credentials.walletId); + + return root.bindWalletClient(client); }; root.bindProfile = function(profile, cb) { @@ -150,7 +156,12 @@ angular.module('copayApp.services') configService.get(function(err) { $log.debug('Preferences read'); if (err) return cb(err); - root.setWalletClients(); + + lodash.each(root.profile.credentials, function(credentials) { + root.bindWallet(credentials); + }); + $rootScope.$emit('Local/WalletListUpdated'); + storageService.getFocusedWalletId(function(err, focusedWalletId) { if (err) return cb(err); root._setFocus(focusedWalletId, function() { @@ -228,7 +239,6 @@ angular.module('copayApp.services') var walletClient = bwcService.getClient(null, opts); var network = opts.networkName || 'livenet'; - if (opts.mnemonic) { try { opts.mnemonic = root._normalizeMnemonic(opts.mnemonic); @@ -286,47 +296,54 @@ angular.module('copayApp.services') return cb(null, walletClient); }; - root._createNewProfile = function(opts, cb) { - - if (opts.noWallet) { - return cb(null, Profile.create()); - } - - root._seedWallet(opts, function(err, walletClient) { - if (err) return cb(err); - - var walletName = gettextCatalog.getString('Personal Wallet'); - var me = gettextCatalog.getString('me'); - - walletClient.createWallet(walletName, me, 1, 1, { - network: 'livenet', - walletPrivKey: opts.walletPrivKey, - }, function(err) { - if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb); - var p = Profile.create({ - credentials: [JSON.parse(walletClient.export())], - }); - return cb(null, p); - }); - }) - }; - - root.createWallet = function(opts, cb) { + // Creates a wallet on BWC/BWS + root.doCreateWallet = function(opts, cb) { $log.debug('Creating Wallet:', opts); root._seedWallet(opts, function(err, walletClient) { if (err) return cb(err); - walletClient.createWallet(opts.name, opts.myName || 'me', opts.m, opts.n, { + var name = opts.name || gettextCatalog.getString('Personal Wallet'); + var myName = opts.myName || gettextCatalog.getString('me'); + + walletClient.createWallet(name, myName, opts.m, opts.n, { network: opts.networkName, walletPrivKey: opts.walletPrivKey, }, function(err, secret) { if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb); - - root._addWalletClient(walletClient, opts, cb); - }) + return cb(null, walletClient, secret); + }); }); }; + // Creates the default Copay profile and its wallet + root.createDefaultProfile = function(opts, cb) { + var p = Profile.create(); + + if (opts.noWallet) { + return cb(null, p); + } + + opts.m = 1; + opts.n = 1; + opts.network = 'livenet'; + + root.doCreateWallet(opts, function(err, walletClient) { + if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb); + p.addWallet(JSON.parse(walletClient.export())); + return cb(null, p); + }); + }; + + // create and store a wallet + root.createWallet = function(opts, cb) { + root.doCreateWallet(opts, function(err, walletClient, secret) { + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl + }, cb); + }); + }; + + // joins and stores a wallet root.joinWallet = function(opts, cb) { var walletClient = bwcService.getClient(); $log.debug('Joining Wallet:', opts); @@ -352,7 +369,9 @@ angular.module('copayApp.services') walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) { if (err) return bwsError.cb(err, gettext('Could not join wallet'), cb); - root._addWalletClient(walletClient, opts, cb); + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl + }, cb); }); }); }; @@ -361,9 +380,8 @@ angular.module('copayApp.services') return root.walletClients[walletId]; }; - root.deleteWalletFC = function(opts, cb) { - var fc = root.focusedClient; - var walletId = fc.credentials.walletId; + root.deleteWalletClient = function(client, cb) { + var walletId = client.credentials.walletId; pushNotificationsService.unsubscribe(root.getClient(walletId), function(err) { if (err) $log.warn('Unsubscription error: ' + err.message); @@ -371,29 +389,22 @@ angular.module('copayApp.services') }); $log.debug('Deleting Wallet:', fc.credentials.walletName); - fc.removeAllListeners(); - root.profile.credentials = lodash.reject(root.profile.credentials, { - walletId: walletId - }); + + root.profile.deleteWallet(walletId); delete root.walletClients[walletId]; root.focusedClient = null; - storageService.clearLastAddress(walletId, function(err) { + + storageService.removeAllWalletData(walletId, function(err) { if (err) $log.warn(err); }); - storageService.removeTxHistory(walletId, function(err) { - if (err) $log.warn(err); - }); - - storageService.clearBackupFlag(walletId, function(err) { - if (err) $log.warn(err); - }); $timeout(function() { - root.setWalletClients(); + $rootScope.$emit('Local/WalletListUpdated'); + root.setAndStoreFocus(null, function() { storageService.storeProfile(root.profile, function(err) { if (err) return cb(err); @@ -422,54 +433,50 @@ angular.module('copayApp.services') }); } - root._addWalletClient = function(walletClient, opts, cb) { - var walletId = walletClient.credentials.walletId; + root.addAndBindWalletClient = function(client, opts, cb) { + var walletId = client.credentials.walletId - // check if exist - var w = lodash.find(root.profile.credentials, { - 'walletId': walletId - }); - if (w) { - return cb(gettext('Wallet already in Copay' + ": ") + w.walletName); - } + if (!root.profile.addWallet(JSON.parse(client.export()))) + return cb(gettext('Wallet already in Copay')); - var config = configService.getSync(); - var defaults = configService.getDefaults(); - var bwsFor = {}; - bwsFor[walletId] = opts.bwsurl || defaults.bws.url; + root.bindWalletClient(client); + $rootScope.$emit('Local/WalletListUpdated', client); - configService.set({ - bwsFor: bwsFor, - }, function(err) { - if (err) console.log(err); + var saveBwsUrl = function(cb) { + if (!opts.bwsurl) return cb(); + var config = configService.getSync(); + var defaults = configService.getDefaults(); + var bwsFor = {}; + bwsFor[walletId] = opts.bwsurl || defaults.bws.url; - root.profile.credentials.push(JSON.parse(walletClient.export())); - root.setWalletClients(); + configService.set({ + bwsFor: bwsFor, + }, function(err) { + if (err) $log.warn(err); + return cb(); + }); + }; + var handleImportedClient = function(cb) { + if (!opts.isImport) return cb(); + $rootScope.$emit('Local/BackupDone', walletId); - var handleImport = function(cb) { - var isImport = opts.mnemonic || opts.externalSource || opts.extendedPrivateKey; + if (!walletClient.isComplete()) + return cb(); - if (!isImport) - return cb(); + storageService.setCleanAndScanAddresses(walletId, cb); + }; - $rootScope.$emit('Local/BackupDone', walletId); - - if (!walletClient.isComplete()) - return cb(); - - storageService.setCleanAndScanAddresses(walletId, cb); - }; - - handleImport(function() { + saveBwsUrl(function() { + handleImportedClient(function() { root.setAndStoreFocus(walletId, function() { storageService.storeProfile(root.profile, function(err) { - $rootScope.$emit('Local/ProfileCreated'); if (config.pushNotifications.enabled) pushNotificationsService.enableNotifications(root.walletClients); return cb(err, walletId); }); + }); }); }); @@ -494,7 +501,13 @@ angular.module('copayApp.services') var addressBook = str.addressBook || {}; var historyCache = str.historyCache ||  []; - root._addWalletClient(walletClient, opts, function(err, walletId) { + if (!walletClient.incorrectDerivation) + root.profile.setChecked(platformInfo.ua, walletClient.credentials.walletId); + + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl, + isImport: true + }, function(err, walletId) { if (err) return cb(err); root.setMetaData(walletClient, addressBook, historyCache, function(error) { if (error) $log.warn(error); @@ -511,7 +524,10 @@ angular.module('copayApp.services') if (err) return bwsError.cb(err, gettext('Could not import'), cb); - root._addWalletClient(walletClient, opts, cb); + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl, + isImport: true + }, cb); }); }; @@ -536,7 +552,10 @@ angular.module('copayApp.services') if (err) return bwsError.cb(err, gettext('Could not import'), cb); - root._addWalletClient(walletClient, opts, cb); + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl, + isImport: true + }, cb); }); }; @@ -557,7 +576,10 @@ angular.module('copayApp.services') return bwsError.cb(err, gettext('Could not import'), cb); } - root._addWalletClient(walletClient, opts, cb); + root.addAndBindWalletClient(walletClient, { + bwsurl: opts.bwsurl, + isImport: true + }, cb); }); }; @@ -565,21 +587,14 @@ angular.module('copayApp.services') $log.info('Creating profile', opts); var defaults = configService.getDefaults(); -console.log('[profileService.js.567]'); //TODO configService.get(function(err) { -console.log('[profileService.js.570]'); //TODO - root._createNewProfile(opts, function(err, p) { + root.createDefaultProfile(opts, function(err, p) { if (err) return cb(err); -console.log('[profileService.js.574]'); //TODO root.bindProfile(p, function(err) { - -console.log('[profileService.js.577]'); //TODO // ignore NONAGREEDDISCLAIMER storageService.storeNewProfile(p, function(err) { - -console.log('[profileService.js.581]'); //TODO return cb(err); }); }); @@ -616,22 +631,18 @@ console.log('[profileService.js.581]'); //TODO walletClient.createWalletFromOldCopay(username, password, blob, function(err, existed) { if (err) return cb(gettext('Error importing wallet: ') + err); - if (root.walletClients[walletClient.credentials.walletId]) { + if (root.profile.hasWallet(walletClient.credentials.walletId)) { $log.debug('Wallet:' + walletClient.credentials.walletName + ' already imported'); return cb(gettext('Wallet Already Imported: ') + walletClient.credentials.walletName); }; - $log.debug('Creating Wallet:', walletClient.credentials.walletName); - root.profile.credentials.push(JSON.parse(walletClient.export())); - root.setWalletClients(); - root.setAndStoreFocus(walletClient.credentials.walletId, function() { - storageService.storeProfile(root.profile, function(err) { - return cb(null, walletClient.credentials.walletId, walletClient.credentials.walletName, existed); - }); - }); + root.addAndBindWalletClient(walletClient, { + isImport: true + }, cb); }); }; + // TODO root.updateCredentialsFC = function(cb) { var fc = root.focusedClient; diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index faf7e14e9..6f3e0cc04 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -24,21 +24,6 @@ angular.module('copayApp.services') }, cb); }; - var encryptOnMobile = function(text, cb) { - - // UUID encryption is disabled. - return cb(null, text); - // - // getUUID(function(uuid) { - // if (uuid) { - // $log.debug('Encrypting profile'); - // text = sjcl.encrypt(uuid, text); - // } - // return cb(null, text); - // }); - }; - - var decryptOnMobile = function(text, cb) { var json; try { @@ -107,18 +92,14 @@ angular.module('copayApp.services') }; root.storeNewProfile = function(profile, cb) { - encryptOnMobile(profile.toObj(), function(err, x) { - storage.create('profile', x, cb); - }); + storage.create('profile', profile.toObj(), cb); }; root.storeProfile = function(profile, cb) { - encryptOnMobile(profile.toObj(), function(err, x) { - storage.set('profile', x, cb); - }); + storage.set('profile', profile.toObj(), cb); }; - root.storeProfileThrottled = lodash.throttle(root.storeProfile, 5000); + root.storeProfileThrottled = lodash.throttle(root.storeProfile, 5000); root.getProfile = function(cb) { storage.get('profile', function(err, str) { @@ -293,5 +274,17 @@ angular.module('copayApp.services') storage.remove('coinbaseTxs-' + network, cb); }; + root.removeAllWalletData = function(walletId, cb) { + storageService.clearLastAddress(walletId, function(err) { + if (err) return cb(err); + storageService.removeTxHistory(walletId, function(err) { + if (err) return cb(err); + storageService.clearBackupFlag(walletId, function(err) { + return cb(err); + }); + }); + }); + }; + return root; }); From 1e2555dad9cfd56e28cfe86a3b813eec72dd67bc Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 6 Jun 2016 18:26:45 -0300 Subject: [PATCH 3/7] refactor preferences --- src/js/controllers/buyCoinbase.js | 4 +- src/js/controllers/buyGlidera.js | 4 +- src/js/controllers/index.js | 109 ++----------------- src/js/controllers/modals/addressbook.js | 4 +- src/js/controllers/preferences.js | 56 ++++++++-- src/js/controllers/preferencesAltCurrency.js | 5 +- src/js/controllers/preferencesDeleteWords.js | 2 +- src/js/controllers/preferencesEmail.js | 12 +- src/js/controllers/preferencesLanguage.js | 18 ++- src/js/controllers/preferencesUnit.js | 5 +- src/js/models/profile.js | 21 +++- src/js/routes.js | 1 + src/js/services/profileService.js | 80 +++++++------- src/js/services/uxLanguage.js | 9 +- src/js/services/walletService.js | 92 ++++++++++------ 15 files changed, 222 insertions(+), 200 deletions(-) diff --git a/src/js/controllers/buyCoinbase.js b/src/js/controllers/buyCoinbase.js index 51d37ffa8..32da90b70 100644 --- a/src/js/controllers/buyCoinbase.js +++ b/src/js/controllers/buyCoinbase.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('buyCoinbaseController', - function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, addressService, walletService) { + function($scope, $modal, $log, $timeout, lodash, profileService, coinbaseService, animationService, bwsError, addressService) { window.ignoreMobilePause = true; var self = this; @@ -72,7 +72,7 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', $scope.selectWallet = function(walletId, walletName) { var client = profileService.getClient(walletId); - walletService.isReady(client, function(err) { + profileService.isReady(client, function(err) { if (err) { self.error = {errors: [{ message: err }]}; $modalInstance.dismiss('cancel'); diff --git a/src/js/controllers/buyGlidera.js b/src/js/controllers/buyGlidera.js index 018d13c8d..3a8b444c8 100644 --- a/src/js/controllers/buyGlidera.js +++ b/src/js/controllers/buyGlidera.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('buyGlideraController', - function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, animationService, walletService) { + function($scope, $timeout, $modal, profileService, addressService, glideraService, bwsError, lodash, animationService) { var self = this; this.show2faCodeInput = null; @@ -51,7 +51,7 @@ angular.module('copayApp.controllers').controller('buyGlideraController', $scope.selectWallet = function(walletId, walletName) { var client = profileService.getClient(walletId); - walletService.isReady(client, function(err) { + profileService.isReady(client, function(err) { if (err) { self.error = err; $modalInstance.dismiss('cancel'); diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 6c4935ddb..e3e2da0f1 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicSideMenuDelegate, $ionicScrollDelegate, $ionicPopup, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwsError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService, walletService) { +angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicSideMenuDelegate, $ionicScrollDelegate, $ionicPopup, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwsError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService) { var self = this; var SOFT_CONFIRMATION_LIMIT = 12; var errors = bwcService.getErrors(); @@ -184,7 +184,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r } } - walletService.isBackupNeeded(fc, function(needsBackup) { + profileService.needsBackup(fc, function(needsBackup) { self.needsBackup = needsBackup; self.openWallet(function() { if (!self.isComplete) { @@ -268,50 +268,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r }; - self._updateRemotePreferencesFor = function(clients, prefs, cb) { - var client = clients.shift(); - - if (!client) - return cb(); - - $log.debug('Saving remote preferences', client.credentials.walletName, prefs); - client.savePreferences(prefs, function(err) { - // we ignore errors here - if (err) $log.warn(err); - - self._updateRemotePreferencesFor(clients, prefs, cb); - }); - }; - - - // TODO: should not be in index.js - self.updateRemotePreferences = function(opts, cb) { - var clients; - var prefs = opts.preferences || {}; - - // Update this JIC. - var config = configService.getSync().wallet.settings; - - //prefs.email (may come from arguments) - prefs.language = self.defaultLanguageIsoCode; - prefs.unit = config.unitCode; - - - if (opts.client) { - clients = [opts.client]; - } else { - clients = lodash.values(profileService.walletClients); - }; - - self._updateRemotePreferencesFor(clients, prefs, function(err) { - if (err) return cb(err); - - lodash.each(clients, function(c) { - c.preferences = lodash.assign(prefs, c.preferences); - }); - return cb(); - }); - }; var _walletStatusHash = function(walletStatus) { var bal; @@ -323,6 +279,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r return bal; }; + // TODO move this to wallet service self.updateAll = function(opts, initStatusHash, tries) { $scope.$broadcast('scroll.refreshComplete'); tries = tries || 0; @@ -1091,14 +1048,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }; - self.setUxLanguage = function(cb) { - uxLanguage.update(function(lang) { - var userLang = lang; - self.defaultLanguageIsoCode = userLang; - self.defaultLanguageName = uxLanguage.getName(userLang); - if (cb) return cb(); - }); - }; self.initGlidera = function(accessToken) { self.glideraEnabled = configService.getSync().glidera.enabled; @@ -1509,24 +1458,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.updateAll(); }); - $rootScope.$on('Local/ProfileBound', function() { - storageService.getRemotePrefsStoredFlag(function(err, val) { - if (err || val) return; - self.updateRemotePreferences({}, function() { - $log.debug('Remote preferences saved'); - storageService.setRemotePrefsStoredFlag(function() {}); - }); - }); - }); - - $rootScope.$on('Local/LanguageSettingUpdated', function() { - self.setUxLanguage(function() { - self.updateRemotePreferences({}, function() { - $log.debug('Remote preferences saved') - }); - }); - }); - $rootScope.$on('Local/GlideraUpdated', function(event, accessToken) { self.initGlidera(accessToken); }); @@ -1553,18 +1484,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.updateAll({ triggerTxUpdate: true, }); - self.updateRemotePreferences({}, function() { - $log.debug('Remote preferences saved') - }); - }); - - $rootScope.$on('Local/EmailSettingUpdated', function(event, client, email, cb) { - self.updateRemotePreferences({ - client: client, - preferences: { - email: email || null - }, - }, cb); }); $rootScope.$on('Local/WalletCompleted', function(event, walletId) { @@ -1576,17 +1495,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r } }); - - lodash.each(['Local/ProfileCreated', 'Local/WalletListUpdated'], function(eventName) { - $rootScope.$on(eventName, function(event, client) { - self.updateRemotePreferences({ - client: client - }, function() { - $log.debug('Remote preferences saved'); - }); - }); - }); - self.debouncedUpdate = lodash.throttle(function() { self.updateAll({ quiet: true @@ -1740,14 +1648,13 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); $rootScope.$on('Local/NoWallets', function(event) { - $log.debug('Event: NoWallets'); - $timeout(function() { self.hasProfile = true; self.noFocusedWallet = true; self.isComplete = null; self.walletName = null; - self.setUxLanguage(); + uxLanguage.update(); + profileService.isDisclaimerAccepted(function(v) { if (v) { go.path('import'); @@ -1757,7 +1664,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); $rootScope.$on('Local/NewFocusedWallet', function() { - self.setUxLanguage(); + uxLanguage.update(); self.setFocusedWallet(); self.updateHistory(); storageService.getCleanAndScanAddresses(function(err, walletId) { @@ -1866,6 +1773,10 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); + $rootScope.$on('Local/EmailUpdated', function(event, email) { + self.preferences.email = email + }); + lodash.each(['NewCopayer', 'CopayerUpdated'], function(eventName) { $rootScope.$on(eventName, function() { // Re try to open wallet (will triggers) diff --git a/src/js/controllers/modals/addressbook.js b/src/js/controllers/modals/addressbook.js index 02ecb0dd2..a384eff1e 100644 --- a/src/js/controllers/modals/addressbook.js +++ b/src/js/controllers/modals/addressbook.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('addressbookController', function($rootScope, $scope, $timeout, profileService, walletService, addressService, addressbookService) { +angular.module('copayApp.controllers').controller('addressbookController', function($rootScope, $scope, $timeout, profileService, addressService, addressbookService) { var self = $scope.self; var fc = profileService.focusedClient; @@ -118,7 +118,7 @@ angular.module('copayApp.controllers').controller('addressbookController', funct var client = profileService.getClient(walletId); $scope.errorSelectedWallet = {}; - walletService.isReady(client, function(err) { + profileService.isReady(client, function(err) { if (err) $scope.errorSelectedWallet[walletId] = err; else { $scope.gettingAddress = true; diff --git a/src/js/controllers/preferences.js b/src/js/controllers/preferences.js index 5e60440c0..bc8203341 100644 --- a/src/js/controllers/preferences.js +++ b/src/js/controllers/preferences.js @@ -3,15 +3,20 @@ angular.module('copayApp.controllers').controller('preferencesController', function($scope, $rootScope, $timeout, $log, configService, profileService, fingerprintService, walletService) { - var fc = profileService.focusedClient; + var self = this; + var fc; var config = configService.getSync(); - $scope.deleted = false; - if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) { - $scope.deleted = true; - } + var disableFocusListener = $rootScope.$on('Local/NewFocusedWalletReady', function() { + self.init(); + }); + + $scope.$on('$destroy', function() { + disableFocusListener(); + }); this.init = function() { + fc = profileService.focusedClient; if (fc) { $scope.encryptEnabled = walletService.isEncrypted(fc); this.externalSource = fc.getPrivKeyExternalSourceName() == 'ledger' ? "Ledger" : null; @@ -21,38 +26,69 @@ angular.module('copayApp.controllers').controller('preferencesController', this.touchidAvailable = fingerprintService.isAvailable(); $scope.touchidEnabled = config.touchIdFor ? config.touchIdFor[fc.credentials.walletId] : null; + + $scope.deleted = false; + if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) { + $scope.deleted = true; + } }; - var handleEncryptedWallet = function(client, cb) { + var handleEncryptedWallet = function(cb) { $rootScope.$emit('Local/NeedsPassword', false, function(err, password) { if (err) return cb(err); - return cb(walletService.unlock(client, password)); + return cb(walletService.unlock(fc, password)); }); }; $scope.encryptChange = function() { + var self = this; if (!fc) return; var val = $scope.encryptEnabled; + var setPrivateKeyEncryption = function(password, cb) { + $log.debug('Encrypting private key for', fc.credentials.walletName); + + fc.setPrivateKeyEncryption(password); + fc.lock(); + profileService.updateCredentials(fc.export(), function() { + $log.debug('Wallet encrypted'); + return cb(); + }); + }; + + var disablePrivateKeyEncryption = function(cb) { + $log.debug('Disabling private key encryption for', fc.credentials.walletName); + + try { + fc.disablePrivateKeyEncryption(); + } catch (e) { + return cb(e); + } + profileService.updateCredentials(fc.export(), function() { + $log.debug('Wallet encryption disabled'); + return cb(); + }); + }; + if (val && !walletService.isEncrypted(fc)) { $rootScope.$emit('Local/NeedsPassword', true, function(err, password) { if (err || !password) { $scope.encryptEnabled = false; return; } - profileService.setPrivateKeyEncryptionFC(password, function() { + setPrivateKeyEncryption(password, function() { $rootScope.$emit('Local/NewEncryptionSetting'); $scope.encryptEnabled = true; }); }); } else { if (!val && walletService.isEncrypted(fc)) { - handleEncryptedWallet(fc, function(err) { + handleEncryptedWallet(function(err) { if (err) { $scope.encryptEnabled = true; return; } - profileService.disablePrivateKeyEncryptionFC(function(err) { + disablePrivateKeyEncryption(function(err) { $rootScope.$emit('Local/NewEncryptionSetting'); if (err) { $scope.encryptEnabled = true; diff --git a/src/js/controllers/preferencesAltCurrency.js b/src/js/controllers/preferencesAltCurrency.js index c62ab2281..55b96998a 100644 --- a/src/js/controllers/preferencesAltCurrency.js +++ b/src/js/controllers/preferencesAltCurrency.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('preferencesAltCurrencyController', - function($scope, $timeout, $log, configService, rateService, lodash, go) { + function($scope, $timeout, $log, configService, rateService, lodash, go, profileService, walletService) { this.hideAdv = true; this.hidePriv = true; this.hideSecret = true; @@ -51,6 +51,9 @@ angular.module('copayApp.controllers').controller('preferencesAltCurrencyControl if (err) $log.warn(err); go.preferencesGlobal(); $scope.$emit('Local/UnitSettingUpdated'); + walletService.updateRemotePreferences(profileService.walletClients, {}, function() { + $log.debug('Remote preferences saved') + }); $timeout(function() { $scope.$apply(); }, 100); diff --git a/src/js/controllers/preferencesDeleteWords.js b/src/js/controllers/preferencesDeleteWords.js index e810c1e74..405d5d6ca 100644 --- a/src/js/controllers/preferencesDeleteWords.js +++ b/src/js/controllers/preferencesDeleteWords.js @@ -13,7 +13,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWordsControl confirmDialog.show(msg, function(ok) { if (ok) { fc.clearMnemonic(); - profileService.updateCredentialsFC(function() { + profileService.updateCredentials(fc.export(), function() { notification.success(successMsg); go.walletHome(); }); diff --git a/src/js/controllers/preferencesEmail.js b/src/js/controllers/preferencesEmail.js index 3f29224af..036cb7a74 100644 --- a/src/js/controllers/preferencesEmail.js +++ b/src/js/controllers/preferencesEmail.js @@ -1,14 +1,22 @@ 'use strict'; angular.module('copayApp.controllers').controller('preferencesEmailController', - function($scope, go, profileService, gettext, $log) { + function($rootScope, go, profileService, gettext, $log, walletService) { this.save = function(form) { var self = this; this.error = null; var fc = profileService.focusedClient; this.saving = true; - $scope.$emit('Local/EmailSettingUpdated', fc,self.email, function() { + var email = self.email || ''; + + walletService.updateRemotePreferences(fc, { + email: email, + }, function(err) { + + if (!err) + $rootScope.$emit('Local/EmailUpdated', email); + self.saving = false; go.path('preferences'); }); diff --git a/src/js/controllers/preferencesLanguage.js b/src/js/controllers/preferencesLanguage.js index 8fc027bd7..b06647488 100644 --- a/src/js/controllers/preferencesLanguage.js +++ b/src/js/controllers/preferencesLanguage.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('preferencesLanguageController', - function($scope, $log, $timeout, configService, uxLanguage, go) { + function($scope, $log, $timeout, configService, profileService, uxLanguage, walletService, go) { this.availableLanguages = uxLanguage.getLanguages(); this.currentLanguage = uxLanguage.getCurrentLanguage(); @@ -19,10 +19,18 @@ angular.module('copayApp.controllers').controller('preferencesLanguageController configService.set(opts, function(err) { if (err) $log.warn(err); go.preferencesGlobal(); - $scope.$emit('Local/LanguageSettingUpdated'); - $timeout(function() { - $scope.$apply(); - }, 100); + + + uxLanguage.update(function() { + $timeout(function() { + $scope.$apply(); + }, 100); + + walletService.updateRemotePreferences(profileService.getClients(), {}, + function() { + $log.debug('Remote preferences saved') + }); + }); }); }; }); diff --git a/src/js/controllers/preferencesUnit.js b/src/js/controllers/preferencesUnit.js index cface9b0d..45b5c6913 100644 --- a/src/js/controllers/preferencesUnit.js +++ b/src/js/controllers/preferencesUnit.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('preferencesUnitController', - function($scope, $timeout, $log, configService, go) { + function($scope, $timeout, $log, configService, go, walletService, profileService) { var config = configService.getSync(); this.unitName = config.wallet.settings.unitName; this.unitOpts = [ @@ -54,6 +54,9 @@ angular.module('copayApp.controllers').controller('preferencesUnitController', if (err) $log.warn(err); go.preferencesGlobal(); $scope.$emit('Local/UnitSettingUpdated'); + walletService.updateRemotePreferences(profileService.getClients(), {}, function() { + $log.debug('Remote preferences saved') + }); $timeout(function() { $scope.$apply(); }, 100); diff --git a/src/js/models/profile.js b/src/js/models/profile.js index d0bab451f..aaa5f4a4c 100644 --- a/src/js/models/profile.js +++ b/src/js/models/profile.js @@ -27,7 +27,7 @@ Profile.fromObj = function(obj) { x.credentials = obj.credentials; x.disclaimerAccepted = obj.disclaimerAccepted; x.checked = obj.checked || {}; - x.checkedUA = null; + x.checkedUA = obj.checkedUA || {}; if (x.credentials[0] && typeof x.credentials[0] != 'object') throw ("credentials should be an object"); @@ -40,6 +40,7 @@ Profile.fromString = function(str) { }; Profile.prototype.toObj = function() { + delete this.dirty; return JSON.stringify(this); }; @@ -53,7 +54,7 @@ Profile.prototype.hasWallet = function(walletId) { }; Profile.prototype.isChecked = function(ua, walletId) { - return this.checkedUA == ua && this.checked[walletId]; + return !!(this.checkedUA == ua && this.checked[walletId]); }; Profile.prototype.setChecked = function(ua, walletId) { @@ -62,6 +63,7 @@ Profile.prototype.setChecked = function(ua, walletId) { this.checked = {}; } this.checked[walletId] = true; + this.dirty = true; }; @@ -70,6 +72,20 @@ Profile.prototype.addWallet = function(credentials) { return false; this.credentials.push(credentials); + this.dirty = true; + return true; +}; + +Profile.prototype.updateWallet = function(credentials) { + if (!this.hasWallet(credentials.walletId)) + return false; + + this.credentials = this.credentials.filter(function(c) { + return c.walletId != walletId; + }); + + this.addWallet(credentials); + this.dirty = true; return true; }; @@ -81,5 +97,6 @@ Profile.prototype.deleteWallet = function(walletId) { return c.walletId != walletId; }); + this.dirty = true; return true; }; diff --git a/src/js/routes.js b/src/js/routes.js index 46e96cee2..998ac7848 100644 --- a/src/js/routes.js +++ b/src/js/routes.js @@ -632,6 +632,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr throw new Error(err); // TODO } } else { + profileService.storeProfileIfDirty(); $log.debug('Profile loaded ... Starting UX.'); $state.transitionTo(toState.name || toState, toParams); } diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index 09a0f512b..17725763d 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -1,6 +1,6 @@ 'use strict'; angular.module('copayApp.services') - .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwsError, uxLanguage, bitcore, platformInfo) { + .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, notificationService, pushNotificationsService, gettext, gettextCatalog, bwsError, uxLanguage, bitcore, platformInfo, walletService) { var isChromeApp = platformInfo.isChromeApp; @@ -67,8 +67,7 @@ angular.module('copayApp.services') var opts = opts || {}; var walletId = client.credentials.walletId; - if ((root.walletClients[walletId] && root.walletClients[walletId].started) - || opts.force) { + if ((root.walletClients[walletId] && root.walletClients[walletId].started) || opts.force) { return false; } @@ -81,7 +80,6 @@ angular.module('copayApp.services') storageService.clearLastAddress(walletId, function() {}); } - client.removeAllListeners(); client.on('report', function(n) { $log.info('BWC Report:' + n); @@ -102,7 +100,7 @@ angular.module('copayApp.services') client.on('walletCompleted', function() { $log.debug('Wallet completed'); - root.updateCredentialsFC(function() { + root.updateCredentials(client.export(), function() { $rootScope.$emit('Local/WalletCompleted', walletId); }); }); @@ -165,7 +163,6 @@ angular.module('copayApp.services') storageService.getFocusedWalletId(function(err, focusedWalletId) { if (err) return cb(err); root._setFocus(focusedWalletId, function() { - $rootScope.$emit('Local/ProfileBound'); if (usePushNotifications) root.pushNotificationsInit(); root.isDisclaimerAccepted(function(val) { @@ -433,6 +430,7 @@ angular.module('copayApp.services') }); } + // Adds and bind a new client to the profile root.addAndBindWalletClient = function(client, opts, cb) { var walletId = client.credentials.walletId @@ -443,12 +441,14 @@ angular.module('copayApp.services') $rootScope.$emit('Local/WalletListUpdated', client); var saveBwsUrl = function(cb) { - if (!opts.bwsurl) return cb(); - var config = configService.getSync(); var defaults = configService.getDefaults(); var bwsFor = {}; bwsFor[walletId] = opts.bwsurl || defaults.bws.url; + // Dont save the default + if (bwsFor[walletId] == defaults.bws.url) + return cb(); + configService.set({ bwsFor: bwsFor, }, function(err) { @@ -467,11 +467,16 @@ angular.module('copayApp.services') storageService.setCleanAndScanAddresses(walletId, cb); }; + walletService.updateRemotePreferences(client, {}, function() { + $log.debug('Remote preferences saved for:' + walletId) + }); + saveBwsUrl(function() { handleImportedClient(function() { root.setAndStoreFocus(walletId, function() { storageService.storeProfile(root.profile, function(err) { + var config = configService.getSync(); if (config.pushNotifications.enabled) pushNotificationsService.enableNotifications(root.walletClients); return cb(err, walletId); @@ -482,6 +487,17 @@ angular.module('copayApp.services') }); }; + root.storeProfileIfDirty = function(cb) { + if (root.profile.dirty) { + storageService.storeProfile(root.profile, function(err) { + $log.debug('Saved modified Profile'); + if (cb) return cb(err); + }); + } else { + if (cb) return cb(); + }; + }; + root.importWallet = function(str, opts, cb) { var walletClient = bwcService.getClient(null, opts); @@ -642,44 +658,34 @@ angular.module('copayApp.services') }); }; - // TODO - root.updateCredentialsFC = function(cb) { - var fc = root.focusedClient; - - var newCredentials = lodash.reject(root.profile.credentials, { - walletId: fc.credentials.walletId - }); - newCredentials.push(JSON.parse(fc.export())); - root.profile.credentials = newCredentials; - + root.updateCredentials = function(credentials, cb) { + root.profile.updateWallet(credentials); storageService.storeProfileThrottled(root.profile, cb); }; + root.getClients = function() { + return lodash.values(root.walletClients); + }; - root.setPrivateKeyEncryptionFC = function(password, cb) { - var fc = root.focusedClient; - $log.debug('Encrypting private key for', fc.credentials.walletName); + root.needsBackup = function(client, cb) { - fc.setPrivateKeyEncryption(password); - fc.lock(); - root.updateCredentialsFC(function() { - $log.debug('Wallet encrypted'); - return cb(); + if (!walletService.needsBackup(client)) + return cb(false); + + storageService.getBackupFlag(client.credentials.walletId, function(err, val) { + if (err) $log.error(err); + if (val) return cb(false); + return cb(true); }); }; + root.isReady = function(client, cb) { + if (!client.isComplete()) + return cb('WALLET_NOT_COMPLETE'); - root.disablePrivateKeyEncryptionFC = function(cb) { - var fc = root.focusedClient; - $log.debug('Disabling private key encryption for', fc.credentials.walletName); - - try { - fc.disablePrivateKeyEncryption(); - } catch (e) { - return cb(e); - } - root.updateCredentialsFC(function() { - $log.debug('Wallet encryption disabled'); + root.needsBackup(client, function(needsBackup) { + if (needsBackup) + return cb('WALLET_NEEDS_BACKUP'); return cb(); }); }; diff --git a/src/js/services/uxLanguage.js b/src/js/services/uxLanguage.js index 9a20320ac..8c5b6d90a 100644 --- a/src/js/services/uxLanguage.js +++ b/src/js/services/uxLanguage.js @@ -3,6 +3,8 @@ angular.module('copayApp.services') .factory('uxLanguage', function languageService($log, lodash, gettextCatalog, amMoment, configService) { var root = {}; + root.currentLanguage = null; + root.availableLanguages = [{ name: 'English', isoCode: 'en', @@ -33,7 +35,6 @@ angular.module('copayApp.services') isoCode: 'ru', }]; - root.currentLanguage = null; root._detect = function(cb) { @@ -99,20 +100,20 @@ angular.module('copayApp.services') var userLang = configService.getSync().wallet.settings.defaultLanguage; if (!userLang) { - root._detect(function(lang) { userLang = lang; if (userLang != root.currentLanguage) { root._set(lang); } - return cb(userLang); + if (cb) return cb(userLang); }); } else { if (userLang != root.currentLanguage) { root._set(userLang); } - return cb(userLang); + + if (cb) return cb(userLang); } }; diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js index c2d060a53..2712e7a3a 100644 --- a/src/js/services/walletService.js +++ b/src/js/services/walletService.js @@ -1,6 +1,9 @@ 'use strict'; -angular.module('copayApp.services').factory('walletService', function($log, lodash, trezor, ledger, storageService) { +// DO NOT INCLUDE STORAGE HERE \/ \/ +angular.module('copayApp.services').factory('walletService', function($log, lodash, trezor, ledger, storageService, configService, uxLanguage) { +// DO NOT INCLUDE STORAGE HERE ^^ + var root = {}; var _signWithLedger = function(client, txp, cb) { @@ -31,27 +34,14 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }); }; - root.isBackupNeeded = function(client, cb) { - if (client.isPrivKeyExternal()) return cb(false); - if (!client.credentials.mnemonic) return cb(false); - if (client.credentials.network == 'testnet') return cb(false); + root.needsBackup = function(client) { + if (client.isPrivKeyExternal()) return false; + if (!client.credentials.mnemonic) return false; + if (client.credentials.network == 'testnet') return false; - storageService.getBackupFlag(client.credentials.walletId, function(err, val) { - if (err) $log.error(err); - if (val) return cb(false); - return cb(true); - }); + return true; }; - root.isReady = function(client, cb) { - if(!client.isComplete()) - return cb('WALLET_NOT_COMPLETE'); - root.isBackupNeeded(client, function(needsBackup) { - if (needsBackup) - return cb('WALLET_NEEDS_BACKUP'); - return cb(); - }); - }; root.isEncrypted = function(client) { if (lodash.isEmpty(client)) return; @@ -82,7 +72,7 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.createTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); if (txp.sendMax) { @@ -97,7 +87,7 @@ angular.module('copayApp.services').factory('walletService', function($log, loda var feeLevelValue = lodash.find(levels, { level: txp.feeLevel }); - + if (!feeLevelValue || !feeLevelValue.feePerKB) return cb({ message: 'Could not get dynamic fee for level: ' + feeLevel @@ -118,10 +108,12 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.publishTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); - client.publishTxProposal({txp: txp}, function(err, publishedTx) { + client.publishTxProposal({ + txp: txp + }, function(err, publishedTx) { if (err) return cb(err); else { $log.debug('Transaction published'); @@ -131,9 +123,9 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.signTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); - + if (client.isPrivKeyExternal()) { switch (client.getPrivKeyExternalSourceName()) { case 'ledger': @@ -160,14 +152,14 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.broadcastTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); - + if (txp.status != 'accepted') return cb('TX_NOT_ACCEPTED'); client.broadcastTxProposal(txp, function(err, broadcastedTxp, memo) { - if (err) + if (err) return cb(err); $log.debug('Transaction broadcasted'); @@ -178,9 +170,9 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.rejectTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); - + client.rejectTxProposal(txp, null, function(err, rejectedTxp) { $log.debug('Transaction rejected'); return cb(err, rejectedTxp); @@ -188,14 +180,50 @@ angular.module('copayApp.services').factory('walletService', function($log, loda }; root.removeTx = function(client, txp, cb) { - if (lodash.isEmpty(txp) || lodash.isEmpty(client)) + if (lodash.isEmpty(txp) || lodash.isEmpty(client)) return cb('MISSING_PARAMETER'); - + client.removeTxProposal(txp, function(err) { $log.debug('Transaction removed'); return cb(err); }); }; + root.updateRemotePreferences = function(clients, prefs, cb) { + prefs = prefs || {}; + + if (!lodash.isArray(clients)) + clients = [clients]; + + function updateRemotePreferencesFor(clients, prefs, cb) { + var client = clients.shift(); + if (!client) return cb(); + $log.debug('Saving remote preferences', client.credentials.walletName, prefs); + + client.savePreferences(prefs, function(err) { + // we ignore errors here + if (err) $log.warn(err); + + updateRemotePreferencesFor(clients, prefs, cb); + }); + }; + + // Update this JIC. + var config = configService.getSync().wallet.settings; + + //prefs.email (may come from arguments) + prefs.language = uxLanguage.getCurrentLanguage();; + prefs.unit = config.unitCode; + + updateRemotePreferencesFor(clients, prefs, function(err) { + if (err) return cb(err); + + lodash.each(clients, function(c) { + c.preferences = lodash.assign(prefs, c.preferences); + }); + return cb(); + }); + }; + return root; }); From b17517ede0124bf684de692da4211af6b5e82259 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 6 Jun 2016 19:09:57 -0300 Subject: [PATCH 4/7] fix tests --- angular-bitcore-wallet-client/index.js | 1 + src/js/controllers/index.js | 2 +- src/js/services/profileService.js | 6 +++--- src/js/services/storageService.js | 6 +++--- test/controllers/create.test.js | 3 +++ test/controllers/disclaimer.test.js | 11 ++++++----- test/controllers/import.test.js | 1 + test/controllers/index.test.js | 2 +- test/controllers/walletHome.test.js | 1 - test/fixtures.js | 3 +++ test/helpers.js | 4 ++-- test/walletService.test.js | 1 + 12 files changed, 25 insertions(+), 16 deletions(-) diff --git a/angular-bitcore-wallet-client/index.js b/angular-bitcore-wallet-client/index.js index 417566863..0e80686f9 100644 --- a/angular-bitcore-wallet-client/index.js +++ b/angular-bitcore-wallet-client/index.js @@ -30,6 +30,7 @@ bwcModule.provider("bwcService", function() { }; service.getClient = function(walletData, opts) { + opts = opts || {}; //note opts use `baseurl` all lowercase; var bwc = new Client({ diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index e3e2da0f1..ab22b3694 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -1009,7 +1009,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r return; } - profileService.addWalletClient(fc, { + profileService.bindWalletClient(fc, { force: true }); self.startScan(self.walletId); diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index 17725763d..fe127935a 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -385,8 +385,8 @@ angular.module('copayApp.services') else $log.debug('Unsubscribed from push notifications service'); }); - $log.debug('Deleting Wallet:', fc.credentials.walletName); - fc.removeAllListeners(); + $log.debug('Deleting Wallet:', client.credentials.walletName); + client.removeAllListeners(); root.profile.deleteWallet(walletId); @@ -461,7 +461,7 @@ angular.module('copayApp.services') if (!opts.isImport) return cb(); $rootScope.$emit('Local/BackupDone', walletId); - if (!walletClient.isComplete()) + if (!client.isComplete()) return cb(); storageService.setCleanAndScanAddresses(walletId, cb); diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index 6f3e0cc04..d144c26f2 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -275,11 +275,11 @@ angular.module('copayApp.services') }; root.removeAllWalletData = function(walletId, cb) { - storageService.clearLastAddress(walletId, function(err) { + root.clearLastAddress(walletId, function(err) { if (err) return cb(err); - storageService.removeTxHistory(walletId, function(err) { + root.removeTxHistory(walletId, function(err) { if (err) return cb(err); - storageService.clearBackupFlag(walletId, function(err) { + root.clearBackupFlag(walletId, function(err) { return cb(err); }); }); diff --git a/test/controllers/create.test.js b/test/controllers/create.test.js index ebc87495f..bf09bfda7 100644 --- a/test/controllers/create.test.js +++ b/test/controllers/create.test.js @@ -1,6 +1,9 @@ describe('createController', function() { var fixtures = { + // Store prefs + '1eda3e702196b8d5d82fae129249bc79f0d5be2f5309a4e39855e7eb4ad31428': {}, + '31f5deeef4cf7fd8fc67297179232e8e4590532960454ad958009132fef3daae': {}, // createWallet 1-1 '56db6f58f2c212591afb4d508d03e5fb40bb786f23dc56c43b98bde42dc513e5': { "walletId": "267bfa75-5575-4af7-8aa3-f5186bc99262" diff --git a/test/controllers/disclaimer.test.js b/test/controllers/disclaimer.test.js index 78f7c4cbd..56f52e443 100644 --- a/test/controllers/disclaimer.test.js +++ b/test/controllers/disclaimer.test.js @@ -1,4 +1,4 @@ -describe.only('disclaimerController', function() { +describe('disclaimerController', function() { var walletService; var storeProfile; @@ -61,9 +61,9 @@ describe.only('disclaimerController', function() { mocks.clear({}, done); }); - // it('should be defined', function() { - // should.exist(ctrl); - // }); + it('should be defined', function() { + should.exist(ctrl); + }); it('should create the initial profile', function(done) { localStorage.clear(); @@ -72,7 +72,8 @@ describe.only('disclaimerController', function() { mnemonic: 'tunnel fork scare industry noble snow tank bullet over gesture nuclear next', }); setTimeout(function() { + ctrl.creatingProfile.should.equal(false); done(); - }, 1000); + }, 100); }); }); diff --git a/test/controllers/import.test.js b/test/controllers/import.test.js index ec8ca9f91..7d7b8dc2f 100644 --- a/test/controllers/import.test.js +++ b/test/controllers/import.test.js @@ -3,6 +3,7 @@ describe('importController', function() { var storeProfile; var fixtures = { + '31f5deeef4cf7fd8fc67297179232e8e4590532960454ad958009132fef3daae': {}, '4599136eff6deb4c9c78043fa84113617a16d75c45920d662305f6227ae8f0a0': { "wallet": { "version": "1.0.0", diff --git a/test/controllers/index.test.js b/test/controllers/index.test.js index 5709b1a26..140e30b38 100644 --- a/test/controllers/index.test.js +++ b/test/controllers/index.test.js @@ -60,7 +60,7 @@ describe('index', function() { }); - it('should updates remote preferences', function(done) { + it.skip('should updates remote preferences', function(done) { ctrl.updateRemotePreferences({}, function() { done(); }); diff --git a/test/controllers/walletHome.test.js b/test/controllers/walletHome.test.js index e1f9026b2..5fa381bcc 100644 --- a/test/controllers/walletHome.test.js +++ b/test/controllers/walletHome.test.js @@ -12,7 +12,6 @@ describe('walletHome', function() { mocks.clear({}, done); }); - it('should be defined', function() { should.exist(ctrl); }); diff --git a/test/fixtures.js b/test/fixtures.js index c52086642..6d3664618 100644 --- a/test/fixtures.js +++ b/test/fixtures.js @@ -52,6 +52,9 @@ var walletInfo = { var FIXTURES = { + // store preferences + '1eda3e702196b8d5d82fae129249bc79f0d5be2f5309a4e39855e7eb4ad31428': {}, + // Incomplete wallet status 'd05582c35aa545494e3f3be9713efa9df112d36a324350f6b7141996b824bce2': walletInfo, // ^ same thing, twostep=1 diff --git a/test/helpers.js b/test/helpers.js index 22fc6135c..a204169ab 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -82,7 +82,9 @@ mocks.init = function(fixtures, controllerName, opts, done) { module('ionic'); module('ngLodash'); + module('angularMoment'); module('gettext'); + module('stateMock'); module('bwcModule', function($provide) { $provide.decorator('bwcService', function($delegate, lodash) { var getClient = $delegate.getClient; @@ -154,8 +156,6 @@ mocks.init = function(fixtures, controllerName, opts, done) { }); }); - module('angularMoment'); - module('stateMock'); module('copayApp.services', { $modal: mocks.modal, $timeout: mocks.$timeout, diff --git a/test/walletService.test.js b/test/walletService.test.js index 8e592770f..9dd11f549 100644 --- a/test/walletService.test.js +++ b/test/walletService.test.js @@ -7,6 +7,7 @@ describe('walletService', function() { beforeEach(function() { module('ngLodash'); module('gettext'); + module('angularMoment'); module('bwcModule'); module('copayApp.services'); }); From 6224f36ff62b82ffbff10eda9e5cbb51c401cf9d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jun 2016 10:37:39 -0300 Subject: [PATCH 5/7] ; --- src/js/controllers/index.js | 2 +- src/js/controllers/preferencesAltCurrency.js | 2 +- src/js/controllers/preferencesLanguage.js | 2 +- src/js/controllers/preferencesUnit.js | 2 +- src/js/services/walletService.js | 2 +- test/controllers/disclaimer.test.js | 2 +- test/helpers.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index ab22b3694..bdc34c685 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -1774,7 +1774,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); $rootScope.$on('Local/EmailUpdated', function(event, email) { - self.preferences.email = email + self.preferences.email = email; }); lodash.each(['NewCopayer', 'CopayerUpdated'], function(eventName) { diff --git a/src/js/controllers/preferencesAltCurrency.js b/src/js/controllers/preferencesAltCurrency.js index 55b96998a..5f6a9c2cf 100644 --- a/src/js/controllers/preferencesAltCurrency.js +++ b/src/js/controllers/preferencesAltCurrency.js @@ -52,7 +52,7 @@ angular.module('copayApp.controllers').controller('preferencesAltCurrencyControl go.preferencesGlobal(); $scope.$emit('Local/UnitSettingUpdated'); walletService.updateRemotePreferences(profileService.walletClients, {}, function() { - $log.debug('Remote preferences saved') + $log.debug('Remote preferences saved'); }); $timeout(function() { $scope.$apply(); diff --git a/src/js/controllers/preferencesLanguage.js b/src/js/controllers/preferencesLanguage.js index b06647488..acce188b5 100644 --- a/src/js/controllers/preferencesLanguage.js +++ b/src/js/controllers/preferencesLanguage.js @@ -28,7 +28,7 @@ angular.module('copayApp.controllers').controller('preferencesLanguageController walletService.updateRemotePreferences(profileService.getClients(), {}, function() { - $log.debug('Remote preferences saved') + $log.debug('Remote preferences saved'); }); }); }); diff --git a/src/js/controllers/preferencesUnit.js b/src/js/controllers/preferencesUnit.js index 45b5c6913..b6cf17437 100644 --- a/src/js/controllers/preferencesUnit.js +++ b/src/js/controllers/preferencesUnit.js @@ -55,7 +55,7 @@ angular.module('copayApp.controllers').controller('preferencesUnitController', go.preferencesGlobal(); $scope.$emit('Local/UnitSettingUpdated'); walletService.updateRemotePreferences(profileService.getClients(), {}, function() { - $log.debug('Remote preferences saved') + $log.debug('Remote preferences saved'); }); $timeout(function() { $scope.$apply(); diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js index 2712e7a3a..1578a279f 100644 --- a/src/js/services/walletService.js +++ b/src/js/services/walletService.js @@ -212,7 +212,7 @@ angular.module('copayApp.services').factory('walletService', function($log, loda var config = configService.getSync().wallet.settings; //prefs.email (may come from arguments) - prefs.language = uxLanguage.getCurrentLanguage();; + prefs.language = uxLanguage.getCurrentLanguage(); prefs.unit = config.unitCode; updateRemotePreferencesFor(clients, prefs, function(err) { diff --git a/test/controllers/disclaimer.test.js b/test/controllers/disclaimer.test.js index 56f52e443..5502aecce 100644 --- a/test/controllers/disclaimer.test.js +++ b/test/controllers/disclaimer.test.js @@ -55,7 +55,7 @@ describe('disclaimerController', function() { initController: true, noDisclaimer: true, }, done); - }) + }); afterEach(function(done) { mocks.clear({}, done); diff --git a/test/helpers.js b/test/helpers.js index a204169ab..01cc65ff5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -222,7 +222,7 @@ mocks.init = function(fixtures, controllerName, opts, done) { should.not.exist(err, err); if (opts.noDisclaimer){ return done(); - }; + } _profileService_.setDisclaimerAccepted(function() { if (!opts.initController) startController(); From 14207dc7717611a5bc5abde9b916991684ead5d9 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jun 2016 10:39:53 -0300 Subject: [PATCH 6/7] remove private methods from root --- src/js/services/profileService.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index fe127935a..03cba8311 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -230,9 +230,8 @@ angular.module('copayApp.services') }); }; - root._seedWallet = function(opts, cb) { + var seedWallet = function(opts, cb) { opts = opts || {}; - $log.debug('seedWallet', opts); var walletClient = bwcService.getClient(null, opts); var network = opts.networkName || 'livenet'; @@ -294,9 +293,9 @@ angular.module('copayApp.services') }; // Creates a wallet on BWC/BWS - root.doCreateWallet = function(opts, cb) { + var doCreateWallet = function(opts, cb) { $log.debug('Creating Wallet:', opts); - root._seedWallet(opts, function(err, walletClient) { + seedWallet(opts, function(err, walletClient) { if (err) return cb(err); var name = opts.name || gettextCatalog.getString('Personal Wallet'); @@ -324,7 +323,7 @@ angular.module('copayApp.services') opts.n = 1; opts.network = 'livenet'; - root.doCreateWallet(opts, function(err, walletClient) { + doCreateWallet(opts, function(err, walletClient) { if (err) return bwsError.cb(err, gettext('Error creating wallet'), cb); p.addWallet(JSON.parse(walletClient.export())); return cb(null, p); @@ -333,7 +332,7 @@ angular.module('copayApp.services') // create and store a wallet root.createWallet = function(opts, cb) { - root.doCreateWallet(opts, function(err, walletClient, secret) { + doCreateWallet(opts, function(err, walletClient, secret) { root.addAndBindWalletClient(walletClient, { bwsurl: opts.bwsurl }, cb); @@ -361,7 +360,7 @@ angular.module('copayApp.services') opts.networkName = walletData.network; $log.debug('Joining Wallet:', opts); - root._seedWallet(opts, function(err, walletClient) { + seedWallet(opts, function(err, walletClient) { if (err) return cb(err); walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) { From 43194559d2b2d4e134ebcc331329bbf768ca52c4 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jun 2016 10:44:35 -0300 Subject: [PATCH 7/7] fix empty csv --- src/js/controllers/preferencesHistory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/controllers/preferencesHistory.js b/src/js/controllers/preferencesHistory.js index 1f7e29418..321e1ade2 100644 --- a/src/js/controllers/preferencesHistory.js +++ b/src/js/controllers/preferencesHistory.js @@ -51,7 +51,7 @@ angular.module('copayApp.controllers').controller('preferencesHistory', $log.debug('Generating CSV from History'); getHistory(function(err, txs) { - if (err || !txs || !txs[0]) { + if (err || !txs) { $log.warn('Failed to generate CSV:', err); if (cb) return cb(err); return;