diff --git a/bower.json b/bower.json index 719abb2ff..152bf929a 100644 --- a/bower.json +++ b/bower.json @@ -21,7 +21,6 @@ "socket.io-client": ">=1.0.0", "ng-idle": "*", "inherits": "~0.0.1", - "angular-load": "0.2.0", "lodash": "~2.4.1", "angular-gravatar": "*", "angular-touch": "~1.3.0" diff --git a/copay.js b/copay.js index bf94a1538..462ad98da 100644 --- a/copay.js +++ b/copay.js @@ -5,19 +5,22 @@ module.exports.TxProposals = require('./js/models/TxProposals'); module.exports.PrivateKey = require('./js/models/PrivateKey'); module.exports.HDPath = require('./js/models/HDPath'); module.exports.HDParams = require('./js/models/HDParams'); -module.exports.crypto = require('./js/util/crypto'); -module.exports.logger = require('./js/util/log'); -module.exports.csv = require('./js/util/csv'); - - -// components -var Async = module.exports.Async = require('./js/models/Async'); -var Insight = module.exports.Insight = require('./js/models/Insight'); -var RateService = module.exports.RateService = require('./js/models/RateService'); - +module.exports.Async = require('./js/models/Async'); +module.exports.Insight = require('./js/models/Insight'); +module.exports.RateService = require('./js/models/RateService'); module.exports.Identity = require('./js/models/Identity'); module.exports.Wallet = require('./js/models/Wallet'); module.exports.Compatibility = require('./js/models/Compatibility'); module.exports.PluginManager = require('./js/models/PluginManager'); + + +module.exports.crypto = require('./js/util/crypto'); +module.exports.logger = require('./js/util/log'); +module.exports.csv = require('./js/util/csv'); + module.exports.version = require('./version').version; module.exports.commitHash = require('./version').commitHash; + + +module.exports.defaultConfig = require('./config'); + diff --git a/js/app.js b/js/app.js index e2ef9e359..f93bf2ac1 100644 --- a/js/app.js +++ b/js/app.js @@ -2,16 +2,17 @@ var copay = require('copay'); var _ = require('lodash'); -var config = defaultConfig; var LS = require('../js/plugins/LocalStorage'); var ls = new LS(); -var localConfig; -var defaults = JSON.parse(JSON.stringify(defaultConfig)); - +// TODO move this to configService ! +var config = copay.defaultConfig; ls.getItem('config', function(err, data) { + var localConfig; + try { localConfig = JSON.parse(data); + } catch(e) {}; if (localConfig) { var cmv = copay.version.split('.')[1]; var lmv = localConfig.version ? localConfig.version.split('.')[1] : '-1'; @@ -38,12 +39,9 @@ var modules = [ 'copayApp.directives', ]; -if (Object.keys(config.plugins).length) - modules.push('angularLoad'); - - var copayApp = window.copayApp = angular.module('copayApp', modules); +var defaults = JSON.parse(JSON.stringify(copay.defaultConfig)); copayApp.value('defaults', defaults); copayApp.config(function($sceDelegateProvider) { diff --git a/js/controllers/createProfile.js b/js/controllers/createProfile.js index 6e4981f3d..acf8c86fa 100644 --- a/js/controllers/createProfile.js +++ b/js/controllers/createProfile.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('CreateProfileController', function($scope, $rootScope, $location, $timeout, notification, pluginManager, identityService, pinService, isMobile) { +angular.module('copayApp.controllers').controller('CreateProfileController', function($scope, $rootScope, $location, $timeout, notification, pluginManager, identityService, pinService, isMobile, configService) { var _credentials, _firstpin; @@ -51,28 +51,27 @@ angular.module('copayApp.controllers').controller('CreateProfileController', fun }; - $scope.selectStorage = function (storage) { + $scope.setStep = function(step) { + $scope.error = null; + $scope.createStep = step; + $timeout(function() { + $scope.$digest(); + }, 1); + }; + + $scope.selectStorage = function(storage) { $scope.useLocalstorage = storage == 'local'; $timeout(function() { $scope.$digest(); }, 1); }; - $scope.setStorage = function(useLocalstorage) { - console.log('[createProfile.js.53:useLocalstorage:]', useLocalstorage); //TODO - console.log('[createProfile.js.53:useLocalstorage:]', $scope.useLocalstorage); //TODO - //settingsService.save({...}) + $scope.goToEmail = function() { $scope.createStep = 'email'; - $scope.useEmail = !useLocalstorage; - $scope.useLocalstorage = useLocalstorage; - $timeout(function() { - $scope.$digest(); - }, 1); + $scope.useEmail = !$scope.useLocalstorage; }; $scope.setEmailOrUsername = function(form) { - console.log('[createProfile.js.53:useLocalstorage:]', $scope.useLocalstorage); //TODO - $scope.userOrEmail = $scope.useLocalstorage ? form.username.$modelValue : form.email.$modelValue; preconditions.checkState($scope.userOrEmail); @@ -97,32 +96,24 @@ angular.module('copayApp.controllers').controller('CreateProfileController', fun }); }; - $scope.createProfile = function(form) { - $rootScope.hideNavigation = false; - if (form && form.$invalid) { - $scope.error = 'Please enter the required fields'; - return; - } - $scope.loading = true; - identityService.create( $scope.userOrEmail, form.password.$modelValue, function(err) { - $scope.loading = false; + $scope._doCreateProfile = function(emailOrUsername, password, cb) { + preconditions.checkArgument(_.isString(emailOrUsername)); + preconditions.checkArgument(_.isString(password)); + + $rootScope.hideNavigation = false; + $scope.loading = true; + + identityService.create(emailOrUsername, password, function(err) { + $scope.loading = false; + $scope.error = null; if (err) { var msg = err.toString(); if (msg.indexOf('EEXIST') >= 0 || msg.indexOf('BADC') >= 0) { msg = 'This profile already exists' } - $timeout(function() { - form.password.$setViewValue(''); - form.password.$render(); - form.repeatpassword.$setViewValue(''); - form.repeatpassword.$render(); - form.$setPristine(); - $scope.error = msg; - }, 1); $scope.error = msg; } else { - $scope.error = null; // mobile if ($scope.isMobile) { _credentials = { @@ -134,12 +125,47 @@ angular.module('copayApp.controllers').controller('CreateProfileController', fun $timeout(function() { $rootScope.$digest(); }, 1); - return; } else { $scope.createDefaultWallet(); } } + return cb(); }); - } + }; + + + $scope.saveSettings = function(cb) { + var plugins = config.plugins; + + plugins.EncryptedLocalStorage = false; + plugins.EncryptedInsightStorage = false; + + var pluginName = $scope.useLocalstorage ? 'EncryptedLocalStorage' : 'EncryptedInsightStorage'; + plugins[pluginName] = true; + + configService.set({ + plugins: plugins + }, cb); + }; + + + $scope.createProfile = function(form) { + if (form && form.$invalid) { + $scope.error = 'Please enter the required fields'; + return; + } + $scope.saveSettings(function(err) { + $scope._doCreateProfile($scope.userOrEmail, form.password.$modelValue, function(err) { + $timeout(function() { + form.password.$setViewValue(''); + form.password.$render(); + form.repeatpassword.$setViewValue(''); + form.repeatpassword.$render(); + form.$setPristine(); + }, 1); + }); + }); + }; + }); diff --git a/js/controllers/home.js b/js/controllers/home.js index 1c08e4514..e75fe7638 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -4,9 +4,9 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc var _credentials, _firstpin; - $scope.init = function() { $scope.isMobile = isMobile.any(); + $scope.attempt=0; // This is only for backwards compat, insight api should link to #!/confirmed directly if (getParam('confirmed')) { @@ -28,6 +28,7 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc pinService.check(function(err, value) { $rootScope.hasPin = value; }); + $scope.usingLocalStorage = config.plugins.EncryptedLocalStorage; }; pinService.makePinInput($scope, 'pin', function(newValue) { @@ -139,8 +140,13 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc copay.logger.warn(err); if ((err.toString() || '').match('PNOTFOUND')) { $scope.error = 'Invalid email or password'; + + if($scope.attempt++>1) { + var storage = $scope.usingLocalStorage ? 'this device storage' : 'cloud storage'; + $scope.error = 'Invalid email or password. You are trying to sign in using ' + storage + '. Change it on settings is necessary.'; + }; + pinService.clear(function() { - copay.logger.debug('PIN erased'); }); } else if ((err.toString() || '').match('Connection')) { $scope.error = 'Could not connect to Insight Server'; @@ -150,7 +156,9 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc $scope.error = 'Unknown error'; } $rootScope.starting = false; - $rootScope.$digest(); + $timeout(function(){ + $rootScope.$digest(); + },1) return; } diff --git a/js/controllers/homeWallet.js b/js/controllers/homeWallet.js index 400cc5329..55c4a00bb 100644 --- a/js/controllers/homeWallet.js +++ b/js/controllers/homeWallet.js @@ -64,8 +64,10 @@ angular.module('copayApp.controllers').controller('HomeWalletController', functi $scope.$on("$destroy", function() { var w = $rootScope.wallet; - removeWatch(); - w.removeListener('txProposalEvent', _updateTxs); + if (w) { + removeWatch(); + w.removeListener('txProposalEvent', _updateTxs); + }; }); $scope.setAlternativeAmount = function(w, tx, cb) { diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 05da4110c..4b2ef366b 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('SettingsController', function($scope, $rootScope, $window, $route, $location, $anchorScroll, notification, applicationService, localstorageService) { +angular.module('copayApp.controllers').controller('SettingsController', function($scope, $rootScope, $window, $route, $location, notification, configService) { $scope.title = 'Settings'; $scope.defaultLanguage = config.defaultLanguage || 'en'; $scope.insightLivenet = config.network.livenet.url; @@ -18,10 +18,10 @@ angular.module('copayApp.controllers').controller('SettingsController', function } $scope.availableStorages = [{ - name: 'Insight', + name: 'In the cloud (Insight server)', pluginName: 'EncryptedInsightStorage', }, { - name: 'Localstorage', + name: 'In this device (localstorage)', pluginName: 'EncryptedLocalStorage', }, // { @@ -57,7 +57,6 @@ angular.module('copayApp.controllers').controller('SettingsController', function } } - $scope.save = function() { $scope.insightLivenet = copay.Insight.setCompleteUrl($scope.insightLivenet); $scope.insightTestnet = copay.Insight.setCompleteUrl($scope.insightTestnet); @@ -73,33 +72,32 @@ angular.module('copayApp.controllers').controller('SettingsController', function }, } - var plugins = {}; plugins[$scope.selectedStorage.pluginName] = true; - copay.logger.setLevel($scope.selectedLogLevel.name); - - localstorageService.setItem('config', JSON.stringify({ - network: insightSettings, - version: copay.version, - defaultLanguage: $scope.selectedLanguage.isoCode, - plugins: plugins, - logLevel: $scope.selectedLogLevel.name, - EncryptedInsightStorage: _.extend(config.EncryptedInsightStorage, { - url: insightSettings.livenet.url + '/api/email' - }), - rates: _.extend(config.rates, { - url: insightSettings.livenet.url + '/api/rates' - }), - }), function() { - applicationService.restart(); - }); + configService.set({ + network: insightSettings, + version: copay.version, + defaultLanguage: $scope.selectedLanguage.isoCode, + plugins: plugins, + logLevel: $scope.selectedLogLevel.name, + EncryptedInsightStorage: _.extend(config.EncryptedInsightStorage, { + url: insightSettings.livenet.url + '/api/email' + }), + rates: _.extend(config.rates, { + url: insightSettings.livenet.url + '/api/rates' + }), + }, + function() { + notification.success('Settings saved'); + $location.path('/'); + }); }; - $scope.reset = function() { - localstorageService.removeItem('config', function() { - applicationService.reload(); + configService.reset(function() { + notification.success('Settings reseted'); + $location.path('/'); }); }; diff --git a/js/services/configService.js b/js/services/configService.js new file mode 100644 index 000000000..f34013165 --- /dev/null +++ b/js/services/configService.js @@ -0,0 +1,38 @@ +'use strict'; + +angular.module('copayApp.services').factory('configService', function(localstorageService, gettextCatalog) { + var root = {}; + + root.set = function(opts, cb) { + + if (opts.logLevel) + copay.logger.setLevel(opts.logLevel); + + if (opts.defaultLanguage) + gettextCatalog.currentLanguage = opts.defaultLanguage; + + localstorageService.getItem('config', function(err, oldOpsStr) { + + var oldOpts = {}; + + try { + oldOpts = JSON.parse(oldOpsStr); + } catch (e) {}; + + var newOpts = {}; + _.extend(newOpts, copay.defaultConfig, oldOpts, opts); + + // TODO remove this gloval variable. + config = newOpts; + + localstorageService.setItem('config', JSON.stringify(newOpts), cb); + }); + }; + + root.reset = function(cb) { + config = copay.defaultConfig; + localstorageService.removeItem('config', cb); + }; + + return root; +}); diff --git a/js/services/identityService.js b/js/services/identityService.js index eda5435f0..8d497be39 100644 --- a/js/services/identityService.js +++ b/js/services/identityService.js @@ -11,10 +11,10 @@ angular.module('copayApp.services') var root = {}; root.check = function(scope) { copay.Identity.checkIfExistsAny({ - pluginManager: pluginManager, + pluginManager: pluginManager.getInstance(config), }, function(anyProfile) { copay.Wallet.checkIfExistsAny({ - pluginManager: pluginManager, + pluginManager: pluginManager.getInstance(config), }, function(anyWallet) { scope.loading = false; scope.anyProfile = anyProfile ? true : false; @@ -47,7 +47,7 @@ angular.module('copayApp.services') copay.Identity.create({ email: email, password: password, - pluginManager: pluginManager, + pluginManager: pluginManager.getInstance(config), network: config.network, networkName: config.networkName, walletDefaults: config.wallet, @@ -99,7 +99,7 @@ angular.module('copayApp.services') var opts = { email: email, password: password, - pluginManager: pluginManager, + pluginManager: pluginManager.getInstance(config), network: config.network, networkName: config.networkName, walletDefaults: config.wallet, @@ -344,7 +344,7 @@ angular.module('copayApp.services') root.importProfile = function(str, password, cb) { copay.Identity.importFromEncryptedFullJson(str, password, { - pluginManager: pluginManager, + pluginManager: pluginManager.getInstance(config), network: config.network, networkName: config.networkName, walletDefaults: config.wallet, diff --git a/js/services/pluginManager.js b/js/services/pluginManager.js index 2a86a03c9..76b6361e2 100644 --- a/js/services/pluginManager.js +++ b/js/services/pluginManager.js @@ -1,18 +1,10 @@ 'use strict'; -angular.module('copayApp.services').factory('pluginManager', function(angularLoad) { - var pm = new copay.PluginManager(config); - var scripts = pm.scripts; +angular.module('copayApp.services').factory('pluginManager', function() { + var root = {}; + root.getInstance = function(config){ + return new copay.PluginManager(config); + }; - for(var ii in scripts){ - var src = scripts[ii].src; - - console.log('\tLoading ',src); //TODO - angularLoad.loadScript(src) - .then(scripts[ii].then || null) - .catch(function() { - throw new Error('Loading ' + src); - }) - } - return pm; + return root; }); diff --git a/views/createProfile.html b/views/createProfile.html index 3b7024348..7df084927 100644 --- a/views/createProfile.html +++ b/views/createProfile.html @@ -59,7 +59,6 @@ Email address confirmation needed - In this Device @@ -82,17 +81,11 @@ - - Create in the cloud + + Create in the cloud + Create in this device - - Create in this device - - - - - @@ -100,17 +100,14 @@ - + {{error|translate}} - + @@ -122,41 +119,45 @@ - - Sign in + + Sign in - - + + - Sign in to Copay - - - {{error|translate}} - - - + + {{error|translate}} + + + + + + + + - + - - - Sign in + + + Sign in + + * Using this device storage. Change to cloud storage on 'settings'. + + + +
- - {{error|translate}} -
+ {{error|translate}} +