diff --git a/src/js/controllers/backup.js b/src/js/controllers/backup.js
index 12356e9cf..320144800 100644
--- a/src/js/controllers/backup.js
+++ b/src/js/controllers/backup.js
@@ -1,37 +1,65 @@
'use strict';
angular.module('copayApp.controllers').controller('backupController',
- function($rootScope, $scope, $timeout, $log, go, lodash, profileService, gettext, bwcService, bwsError, walletService, ongoingProcess) {
+ function($rootScope, $scope, $timeout, $log, go, lodash, fingerprintService, platformInfo, configService, profileService, gettext, bwcService, bwsError, walletService, ongoingProcess) {
var fc = profileService.focusedClient;
+ var prevState;
$scope.customWords = [];
$scope.walletName = fc.credentials.walletName;
+ $scope.credentialsEncrypted = fc.isPrivKeyEncrypted;
- var handleEncryptedWallet = function(client, cb) {
- if (!walletService.isEncrypted(client)) return cb();
- $rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
- if (err) return cb(err);
- return cb(walletService.unlock(client, password));
+ $scope.init = function(state) {
+ prevState = state || 'walletHome';
+ $scope.step = 1;
+ $scope.deleted = isDeletedSeed();
+ if ($scope.deleted) return;
+
+ fingerprintService.check(fc, function(err) {
+ if (err) {
+ go.path(prevState);
+ return;
+ }
+
+ handleEncryptedWallet(fc, function(err) {
+ if (err) {
+ $scope.error = bwsError.msg(err, gettext('Could not decrypt'));
+ $log.warn('Error decrypting credentials:', $scope.error);
+ return;
+ }
+ $scope.credentialsEncrypted = false;
+ $scope.initFlow();
+ });
});
};
- if (fc.isPrivKeyEncrypted() && !isDeletedSeed()) {
- $scope.credentialsEncrypted = true;
- passwordRequest();
- } else {
- if (!isDeletedSeed())
- initWords();
- }
+ function shuffledWords(words) {
+ var sort = lodash.sortBy(words);
- $scope.init = function() {
- $scope.passphrase = '';
+ return lodash.map(sort, function(w) {
+ return {
+ word: w,
+ selected: false
+ };
+ });
+ };
+
+ $scope.initFlow = function() {
+ var words = fc.getMnemonic();
+ $scope.xPrivKey = fc.credentials.xPrivKey;
+ $scope.mnemonicWords = words.split(/[\u3000\s]+/);
$scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords);
+ $scope.mnemonicHasPassphrase = fc.mnemonicHasPassphrase();
+ $scope.useIdeograms = words.indexOf("\u3000") >= 0;
+ $scope.passphrase = '';
$scope.customWords = [];
$scope.step = 1;
- $scope.deleted = isDeletedSeed();
- $scope.credentialsEncrypted = false;
$scope.selectComplete = false;
$scope.backupError = false;
+
+ $timeout(function() {
+ $scope.$apply();
+ }, 10);
};
function isDeletedSeed() {
@@ -40,16 +68,14 @@ angular.module('copayApp.controllers').controller('backupController',
return false;
};
- $scope.backTo = function(state) {
- if (state == 'walletHome')
- go.walletHome();
- else
- go.preferences();
+ $scope.goBack = function() {
+ walletService.lock(fc);
+ go.path(prevState || 'walletHome');
};
$scope.goToStep = function(n) {
if (n == 1)
- $scope.init();
+ $scope.initFlow();
if (n == 2)
$scope.step = 2;
if (n == 3) {
@@ -76,66 +102,6 @@ angular.module('copayApp.controllers').controller('backupController',
};
};
- function initWords() {
- var words = fc.getMnemonic();
- $scope.xPrivKey = fc.credentials.xPrivKey;
- walletService.lock(fc);
- $scope.mnemonicWords = words.split(/[\u3000\s]+/);
- $scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords);
- $scope.mnemonicHasPassphrase = fc.mnemonicHasPassphrase();
- $scope.useIdeograms = words.indexOf("\u3000") >= 0;
- };
-
- function shuffledWords(words) {
- var sort = lodash.sortBy(words);
-
- return lodash.map(sort, function(w) {
- return {
- word: w,
- selected: false
- };
- });
- };
-
- $scope.toggle = function() {
- $scope.error = "";
-
- if ($scope.credentialsEncrypted)
- passwordRequest();
-
- $timeout(function() {
- $scope.$apply();
- }, 1);
- };
-
- function passwordRequest() {
- try {
- initWords();
- } catch (e) {
- if (e.message && e.message.match(/encrypted/) && fc.isPrivKeyEncrypted()) {
-
- $timeout(function() {
- $scope.$apply();
- }, 1);
-
- handleEncryptedWallet(fc, function(err) {
- if (err) {
- $scope.error = bwsError.msg(err, gettext('Could not decrypt'));
- $log.warn('Error decrypting credentials:', $scope.error); //TODO
- return;
- }
-
- $scope.credentialsEncrypted = false;
- initWords();
-
- $timeout(function() {
- $scope.$apply();
- }, 1);
- });
- }
- }
- };
-
$scope.addButton = function(index, item) {
var newWord = {
word: item.word,
@@ -196,6 +162,18 @@ angular.module('copayApp.controllers').controller('backupController',
}, 1);
};
+ function handleEncryptedWallet(client, cb) {
+ if (!walletService.isEncrypted(client)) {
+ $scope.credentialsEncrypted = false;
+ return cb();
+ }
+
+ $rootScope.$emit('Local/NeedsPassword', false, function(err, password) {
+ if (err) return cb(err);
+ return cb(walletService.unlock(client, password));
+ });
+ };
+
function backupError(err) {
ongoingProcess.set('validatingWords', false);
$log.debug('Failed to verify backup: ', err);
diff --git a/src/js/controllers/export.js b/src/js/controllers/export.js
index 5714f609e..5de429aa9 100644
--- a/src/js/controllers/export.js
+++ b/src/js/controllers/export.js
@@ -1,15 +1,35 @@
'use strict';
angular.module('copayApp.controllers').controller('exportController',
- function($rootScope, $scope, $timeout, $log, backupService, storageService, profileService, platformInfo, notification, go, gettext, gettextCatalog) {
+ function($rootScope, $scope, $timeout, $log, backupService, fingerprintService, configService, storageService, profileService, platformInfo, notification, go, gettext, gettextCatalog) {
var isWP = platformInfo.isWP;
var isAndroid = platformInfo.isAndroid;
-
- $scope.error = null;
- $scope.success = null;
- $scope.metaDataEnabled = true;
+ var isCordova = platformInfo.isCordova;
var fc = profileService.focusedClient;
$scope.isEncrypted = fc.isPrivKeyEncrypted();
+ $scope.touchidSuccess = null;
+ $scope.touchidEnabled = null;
+ $scope.error = null;
+
+ $scope.init = function(state) {
+ if (!isCordova) return;
+
+ var config = configService.getSync();
+ var touchidAvailable = fingerprintService.isAvailable();
+ var touchidEnabled = $scope.touchidEnabled = config.touchIdFor ? config.touchIdFor[fc.credentials.walletId] : null;
+
+ if (!touchidAvailable || !touchidEnabled) return;
+
+ fingerprintService.check(fc, function(err) {
+ if (err)
+ go.path(state || 'walletHome');
+
+ $scope.touchidSuccess = true;
+ $timeout(function() {
+ $scope.$apply();
+ }, 10);
+ });
+ };
$scope.downloadWalletBackup = function() {
$scope.getMetaData($scope.metaDataEnabled, function(err, txsFromLocal, localAddressBook) {
@@ -46,7 +66,7 @@ angular.module('copayApp.controllers').controller('exportController',
return cb(null, txsFromLocal, localAddressBook)
});
});
- }
+ };
$scope.getHistoryCache = function(cb) {
storageService.getTxHistory(fc.credentials.walletId, function(err, txs) {
@@ -63,7 +83,7 @@ angular.module('copayApp.controllers').controller('exportController',
return cb(null, localTxs);
});
- }
+ };
$scope.getAddressbook = function(cb) {
storageService.getAddressbook(fc.credentials.network, function(err, addressBook) {
@@ -78,7 +98,7 @@ angular.module('copayApp.controllers').controller('exportController',
return cb(null, localAddressBook);
});
- }
+ };
$scope.getBackup = function(cb) {
$scope.getMetaData($scope.metaDataEnabled, function(err, txsFromLocal, localAddressBook) {
@@ -101,7 +121,7 @@ angular.module('copayApp.controllers').controller('exportController',
}
return cb(ew);
});
- }
+ };
$scope.viewWalletBackup = function() {
$timeout(function() {
diff --git a/src/js/controllers/preferencesDeleteWords.js b/src/js/controllers/preferencesDeleteWords.js
index 2906cea2c..af7a9b140 100644
--- a/src/js/controllers/preferencesDeleteWords.js
+++ b/src/js/controllers/preferencesDeleteWords.js
@@ -12,7 +12,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWordsControl
confirmDialog.show(msg, function(ok) {
if (ok) {
fc.clearMnemonic();
- profileService.updateCredentials(fc.export(), function() {
+ profileService.updateCredentials(JSON.parse(fc.export()), function() {
notification.success(successMsg);
go.walletHome();
});
diff --git a/test/controllers/backup.test.js b/test/controllers/backup.test.js
index d1417e126..29c2a3f71 100644
--- a/test/controllers/backup.test.js
+++ b/test/controllers/backup.test.js
@@ -18,6 +18,7 @@ describe('Backup Controller', function() {
});
it('should set the mnemonic incomplete wallets', function(done) {
+ scope.initFlow();
should.exist(scope.mnemonicWords);
scope.mnemonicWords.should.deep.equal('dizzy cycle skirt decrease exotic fork sure mixture hair vapor copper hero'.split(' '));
done();
@@ -36,6 +37,7 @@ describe('Backup Controller', function() {
});
it('should not set the mnemonic for complete wallets', function() {
+ scope.initFlow();
scope.mnemonicWords.should.deep.equal('cheese where alarm job conduct donkey license pave congress pepper fence current'.split(' '));
});