diff --git a/src/js/controllers/create.js b/src/js/controllers/create.js index 658c604bba5..d7eff0ad4d5 100644 --- a/src/js/controllers/create.js +++ b/src/js/controllers/create.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('createController', - function($scope, $rootScope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, storageService, popupService, appConfigService, pushNotificationsService) { + function ($scope, $rootScope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, storageService, popupService, appConfigService, pushNotificationsService) { /* For compressed keys, m*73 + n*34 <= 496 */ var COPAYER_PAIR_LIMITS = { @@ -19,7 +19,7 @@ angular.module('copayApp.controllers').controller('createController', 12: 1, }; - $scope.$on("$ionicView.beforeEnter", function(event, data) { + $scope.$on("$ionicView.beforeEnter", function (event, data) { $scope.formData = {}; var defaults = configService.getDefaults(); var config = configService.getSync(); @@ -32,41 +32,17 @@ angular.module('copayApp.controllers').controller('createController', $scope.setTotalCopayers(tc); updateRCSelect(tc); - resetPasswordFields(); }); - $scope.showAdvChange = function() { + $scope.showAdvChange = function () { $scope.showAdv = !$scope.showAdv; - $scope.encrypt = null; $scope.resizeView(); }; - $scope.checkPassword = function(pw1, pw2) { - if (pw1 && pw1.length > 0) { - if (pw2 && pw2.length > 0) { - if (pw1 == pw2) $scope.result = 'correct'; - else { - $scope.formData.passwordSaved = null; - $scope.result = 'incorrect'; - } - } else - $scope.result = null; - } else - $scope.result = null; - }; - - $scope.resizeView = function() { - $timeout(function() { + $scope.resizeView = function () { + $timeout(function () { $ionicScrollDelegate.resize(); }, 10); - resetPasswordFields(); - }; - - function resetPasswordFields() { - $scope.formData.passphrase = $scope.formData.createPassphrase = $scope.formData.passwordSaved = $scope.formData.repeatPassword = $scope.result = null; - $timeout(function() { - $scope.$apply(); - }); }; function updateRCSelect(n) { @@ -123,13 +99,13 @@ angular.module('copayApp.controllers').controller('createController', $scope.seedOptions = seedOptions; }; - $scope.setTotalCopayers = function(tc) { + $scope.setTotalCopayers = function (tc) { $scope.formData.totalCopayers = tc; updateRCSelect(tc); updateSeedSourceSelect(tc); }; - $scope.create = function() { + $scope.create = function () { var opts = { name: $scope.formData.walletName, @@ -207,7 +183,7 @@ angular.module('copayApp.controllers').controller('createController', return; } - src.getInfoForNewWallet(opts.n > 1, account, opts.networkName, function(err, lopts) { + src.getInfoForNewWallet(opts.n > 1, account, opts.networkName, function (err, lopts) { ongoingProcess.set('connecting ' + $scope.formData.seedSource.id, false); if (err) { popupService.showAlert(gettextCatalog.getString('Error'), err); @@ -223,8 +199,8 @@ angular.module('copayApp.controllers').controller('createController', function _create(opts) { ongoingProcess.set('creatingWallet', true); - $timeout(function() { - profileService.createWallet(opts, function(err, client) { + $timeout(function () { + profileService.createWallet(opts, function (err, client) { ongoingProcess.set('creatingWallet', false); if (err) { $log.warn(err); @@ -246,7 +222,7 @@ angular.module('copayApp.controllers').controller('createController', disableAnimate: true }); $state.go('tabs.home'); - $timeout(function() { + $timeout(function () { $state.transitionTo('tabs.copayers', { walletId: client.credentials.walletId }); diff --git a/src/js/controllers/join.js b/src/js/controllers/join.js index 661170e7a6e..afb19653d16 100644 --- a/src/js/controllers/join.js +++ b/src/js/controllers/join.js @@ -1,9 +1,9 @@ 'use strict'; angular.module('copayApp.controllers').controller('joinController', - function($scope, $rootScope, $timeout, $state, $ionicHistory, $ionicScrollDelegate, profileService, configService, storageService, applicationService, gettextCatalog, lodash, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, $log, $stateParams, popupService, appConfigService) { + function ($scope, $rootScope, $timeout, $state, $ionicHistory, $ionicScrollDelegate, profileService, configService, storageService, applicationService, gettextCatalog, lodash, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, $log, $stateParams, popupService, appConfigService) { - $scope.$on("$ionicView.beforeEnter", function(event, data) { + $scope.$on("$ionicView.beforeEnter", function (event, data) { var defaults = configService.getDefaults(); var config = configService.getSync(); $scope.formData = {}; @@ -12,45 +12,22 @@ angular.module('copayApp.controllers').controller('joinController', $scope.formData.account = 1; $scope.formData.secret = null; $scope.formData.coin = data.stateParams.coin; - resetPasswordFields(); updateSeedSourceSelect(); }); - $scope.showAdvChange = function() { + $scope.showAdvChange = function () { $scope.showAdv = !$scope.showAdv; $scope.encrypt = null; $scope.resizeView(); }; - $scope.checkPassword = function(pw1, pw2) { - if (pw1 && pw1.length > 0) { - if (pw2 && pw2.length > 0) { - if (pw1 == pw2) $scope.result = 'correct'; - else { - $scope.formData.passwordSaved = null; - $scope.result = 'incorrect'; - } - } else - $scope.result = null; - } else - $scope.result = null; - }; - - $scope.resizeView = function() { - $timeout(function() { + $scope.resizeView = function () { + $timeout(function () { $ionicScrollDelegate.resize(); }, 10); - resetPasswordFields(); - }; - - function resetPasswordFields() { - $scope.formData.passphrase = $scope.formData.createPassphrase = $scope.formData.passwordSaved = $scope.formData.repeatPassword = $scope.result = null; - $timeout(function() { - $scope.$apply(); - }); }; - $scope.onQrCodeScannedJoin = function(data) { + $scope.onQrCodeScannedJoin = function (data) { $scope.formData.secret = data; $scope.$apply(); }; @@ -100,7 +77,7 @@ angular.module('copayApp.controllers').controller('joinController', } }; - $scope.join = function() { + $scope.join = function () { var opts = { secret: $scope.formData.secret, @@ -175,7 +152,7 @@ angular.module('copayApp.controllers').controller('joinController', } // TODO: cannot currently join an intelTEE testnet wallet (need to detect from the secret) - src.getInfoForNewWallet(true, account, 'livenet', function(err, lopts) { + src.getInfoForNewWallet(true, account, 'livenet', function (err, lopts) { ongoingProcess.set('connecting' + $scope.formData.seedSource.id, false); if (err) { popupService.showAlert(gettextCatalog.getString('Error'), err); @@ -192,8 +169,8 @@ angular.module('copayApp.controllers').controller('joinController', function _join(opts) { ongoingProcess.set('joiningWallet', true); - $timeout(function() { - profileService.joinWallet(opts, function(err, client) { + $timeout(function () { + profileService.joinWallet(opts, function (err, client) { ongoingProcess.set('joiningWallet', false); if (err) { popupService.showAlert(gettextCatalog.getString('Error'), err); @@ -208,7 +185,7 @@ angular.module('copayApp.controllers').controller('joinController', disableAnimate: true }); $state.go('tabs.home'); - $timeout(function() { + $timeout(function () { $state.transitionTo('tabs.copayers', { walletId: client.credentials.walletId }); diff --git a/src/js/controllers/onboarding/tour.js b/src/js/controllers/onboarding/tour.js index 5781ec22a7b..9e65d174243 100644 --- a/src/js/controllers/onboarding/tour.js +++ b/src/js/controllers/onboarding/tour.js @@ -1,6 +1,6 @@ 'use strict'; angular.module('copayApp.controllers').controller('tourController', - function($scope, $state, $log, $timeout, $filter, ongoingProcess, profileService, rateService, popupService, gettextCatalog) { + function ($scope, $state, $log, $timeout, $filter, ongoingProcess, profileService, rateService, popupService, gettextCatalog) { $scope.data = { index: 0 @@ -13,44 +13,44 @@ angular.module('copayApp.controllers').controller('tourController', spaceBetween: 100 } - $scope.$on("$ionicSlides.sliderInitialized", function(event, data) { + $scope.$on("$ionicSlides.sliderInitialized", function (event, data) { $scope.slider = data.slider; }); - $scope.$on("$ionicSlides.slideChangeStart", function(event, data) { + $scope.$on("$ionicSlides.slideChangeStart", function (event, data) { $scope.data.index = data.slider.activeIndex; }); - $scope.$on("$ionicSlides.slideChangeEnd", function(event, data) {}); + $scope.$on("$ionicSlides.slideChangeEnd", function (event, data) { }); - $scope.$on("$ionicView.enter", function(event, data) { - rateService.whenAvailable(function() { + $scope.$on("$ionicView.enter", function (event, data) { + rateService.whenAvailable(function () { var localCurrency = 'USD'; var btcAmount = 1; var rate = rateService.toFiat(btcAmount * 1e8, localCurrency, 'btc'); $scope.localCurrencySymbol = '$'; $scope.localCurrencyPerBtc = $filter('formatFiatAmount')(parseFloat(rate.toFixed(2), 10)); - $timeout(function() { + $timeout(function () { $scope.$apply(); }) }); }); var retryCount = 0; - $scope.createDefaultWallet = function() { + $scope.createDefaultWallet = function () { ongoingProcess.set('creatingWallet', true); - $timeout(function() { - profileService.createDefaultWallet(function(err, walletClient) { + $timeout(function () { + profileService.createDefaultWallet(function (err, walletClient) { if (err) { $log.warn(err); - return $timeout(function() { + return $timeout(function () { $log.warn('Retrying to create default wallet.....:' + ++retryCount); if (retryCount > 3) { ongoingProcess.set('creatingWallet', false); popupService.showAlert( gettextCatalog.getString('Cannot Create Wallet'), err, - function() { + function () { retryCount = 0; return $scope.createDefaultWallet(); }, gettextCatalog.getString('Retry')); @@ -67,21 +67,21 @@ angular.module('copayApp.controllers').controller('tourController', walletId: walletId }); - /* - $state.go('onboarding.backupRequest', { - walletId: walletId - }); - */ + /* + $state.go('onboarding.backupRequest', { + walletId: walletId + }); + */ }); }, 300); }; - $scope.goBack = function() { + $scope.goBack = function () { if ($scope.data.index != 0) $scope.slider.slidePrev(); else $state.go('onboarding.welcome'); } - $scope.slideNext = function() { + $scope.slideNext = function () { if ($scope.data.index != 2) $scope.slider.slideNext(); else $state.go('onboarding.welcome'); } diff --git a/src/js/services/onGoingProcess.js b/src/js/services/onGoingProcess.js index fe395350868..8623d69b866 100644 --- a/src/js/services/onGoingProcess.js +++ b/src/js/services/onGoingProcess.js @@ -6,6 +6,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP; var ongoingProcess = {}; + var pausedOngoingProcess = {}; var processNames = { 'broadcastingTx': gettext('Broadcasting transaction'), @@ -63,6 +64,18 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti return ongoingProcess[processName]; }; + root.pause = function() { + pausedOngoingProcess = ongoingProcess; + root.clear(); + } + + root.resume = function() { + lodash.forEach(pausedOngoingProcess, function(v, k) { + root.set(k, v); + }); + pausedOngoingProcess = {}; + } + root.set = function(processName, isOn, customHandler) { $log.debug('ongoingProcess', processName, isOn); root[processName] = isOn; diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index af6f43582d1..98c23a2f2dc 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, $state, sjcl, lodash, storageService, bwcService, configService, gettextCatalog, bwcError, uxLanguage, platformInfo, txFormatService, appConfigService) { + .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, $state, sjcl, lodash, storageService, bwcService, configService, gettextCatalog, bwcError, uxLanguage, platformInfo, txFormatService, appConfigService, popupService, ongoingProcess) { var isChromeApp = platformInfo.isChromeApp; @@ -505,45 +505,97 @@ angular.module('copayApp.services') }); } + // An alert dialog + var askPassword = function(name, title, cb) { + var opts = { + inputType: 'password', + forceHTMLPrompt: true, + class: 'text-warn' + }; + popupService.showPrompt(title, name, opts, function(res) { + if (!res) return cb(); + if (res) return cb(res) + }); + }; + + var showWarningNoEncrypt = function(cb) { + var title = gettextCatalog.getString('Are you sure?'); + var msg = gettextCatalog.getString('Your wallet keys will be stored in plan text in this device, if an other app access the store it will be able to access your Bitcoin'); + var yes = gettextCatalog.getString('Yes'); + var no = gettextCatalog.getString('No'); + popupService.showConfirm(title, msg, yes, no, function(res) { + return cb(res); + }); + }; + + var encryptWallet = function(wallet, cb) { + + var title = gettextCatalog.getString('Please enter a password to encrypt your wallet keys on this device storage'); + var warnMsg = gettextCatalog.getString('Your wallet key will be encrypted. The Spending Password cannot be recovered. Be sure to write it down.'); + askPassword(warnMsg, title, function(password) { + if (!password) { + showWarningNoEncrypt(function(res) { + if (res) return cb() + return encryptWallet(wallet, cb); + }); + } else { + title = gettextCatalog.getString('Confirm your new spending password'); + askPassword(warnMsg, title, function(password2) { + if (!password2 || password != password2) + return encryptWallet(wallet, cb); + + wallet.encryptPrivateKey(password); + return cb(); + }); + } + }); + }; + // Adds and bind a new client to the profile var addAndBindWalletClient = function(client, opts, cb) { if (!client || !client.credentials) return cb(gettextCatalog.getString('Could not access wallet')); - var walletId = client.credentials.walletId + // Encrypt wallet + ongoingProcess.pause(); + encryptWallet(client, function() { + ongoingProcess.resume(); - if (!root.profile.addWallet(JSON.parse(client.export()))) - return cb(gettextCatalog.getString("Wallet already in {{appName}}", { - appName: appConfigService.nameCase - })); + var walletId = client.credentials.walletId + if (!root.profile.addWallet(JSON.parse(client.export()))) + return cb(gettextCatalog.getString("Wallet already in {{appName}}", { + appName: appConfigService.nameCase + })); - var skipKeyValidation = shouldSkipValidation(walletId); - if (!skipKeyValidation) - root.runValidation(client); - root.bindWalletClient(client); + var skipKeyValidation = shouldSkipValidation(walletId); + if (!skipKeyValidation) + root.runValidation(client); - var saveBwsUrl = function(cb) { - var defaults = configService.getDefaults(); - var bwsFor = {}; - bwsFor[walletId] = opts.bwsurl || defaults.bws.url; + root.bindWalletClient(client); - // Dont save the default - if (bwsFor[walletId] == defaults.bws.url) - return cb(); + var saveBwsUrl = function(cb) { + var defaults = configService.getDefaults(); + var bwsFor = {}; + bwsFor[walletId] = opts.bwsurl || defaults.bws.url; - configService.set({ - bwsFor: bwsFor, - }, function(err) { - if (err) $log.warn(err); - return cb(); - }); - }; + // Dont save the default + if (bwsFor[walletId] == defaults.bws.url) + return cb(); - saveBwsUrl(function() { - storageService.storeProfile(root.profile, function(err) { - return cb(err, client); + configService.set({ + bwsFor: bwsFor, + }, function(err) { + if (err) $log.warn(err); + return cb(); + }); + }; + + saveBwsUrl(function() { + storageService.storeProfile(root.profile, function(err) { + return cb(err, client); + }); }); }); }; diff --git a/www/views/join.html b/www/views/join.html index 75b2dbf4e52..d8803140aab 100644 --- a/www/views/join.html +++ b/www/views/join.html @@ -14,11 +14,7 @@