Merge pull request #3289 from cmgustavo/feat/touch-id-ios

Set touch id to spend funds (only iOS)
This commit is contained in:
Matias Alejo Garcia 2015-10-08 12:09:43 -03:00
commit 0cb4b6b2a3
6 changed files with 199 additions and 97 deletions

View file

@ -129,6 +129,9 @@ if [ ! -d $PROJECT ]; then
cordova plugin add org.apache.cordova.file cordova plugin add org.apache.cordova.file
checkOK checkOK
cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-touch-id && cordova prepare
checkOK
fi fi
if $DBGJS if $DBGJS

View file

@ -6,7 +6,7 @@
</div> </div>
<div class="content preferences" ng-controller="preferencesController as preferences"> <div class="content preferences" ng-controller="preferencesController as preferences" ng-init="preferences.init()">
<ul class="no-bullet m0 size-14" ng-show="!index.noFocusedWallet"> <ul class="no-bullet m0 size-14" ng-show="!index.noFocusedWallet">
<h4 class="title m0">{{index.alias}} [{{index.walletName}}] <span translate>settings</span></h4> <h4 class="title m0">{{index.alias}} [{{index.walletName}}] <span translate>settings</span></h4>
@ -40,6 +40,10 @@
<span translate>Request Password for Spending Funds</span> <span translate>Request Password for Spending Funds</span>
<switch id="network-name" name="encrypt" ng-model="encrypt" class="green right"></switch> <switch id="network-name" name="encrypt" ng-model="encrypt" class="green right"></switch>
</li> </li>
<li class="line-b p20" ng-show="preferences.touchidAvailable">
<span translate>Request Touch ID for Spending Funds</span>
<switch id="touchid" name="touchid" ng-model="touchid" class="green right"></switch>
</li>
<li class="line-b p20" ng-show="index.isPrivKeyExternal"> <li class="line-b p20" ng-show="index.isPrivKeyExternal">
<span translate>Hardware wallet</span> <span translate>Hardware wallet</span>
<span class="right text-gray"> <span class="right text-gray">

View file

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, amMoment, nodeWebkit, addonManager, feeService, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, isMobile) { angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, feeService, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, isMobile) {
var self = this; var self = this;
self.isCordova = isCordova; self.isCordova = isCordova;
self.isChromeApp = isChromeApp; self.isChromeApp = isChromeApp;
@ -1152,6 +1152,20 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.setTab(tab, reset); self.setTab(tab, reset);
}); });
$rootScope.$on('Local/RequestTouchid', function(event, cb) {
window.plugins.touchid.verifyFingerprint(
gettextCatalog.getString('Scan your fingerprint please'),
function(msg) {
// OK
return cb();
},
function(msg) {
// ERROR
return cb(gettext('Invalid Touch ID'));
}
);
});
$rootScope.$on('Local/ShowAlert', function(event, msg, cb) { $rootScope.$on('Local/ShowAlert', function(event, msg, cb) {
self.showErrorPopup(msg, cb); self.showErrorPopup(msg, cb);
}); });

View file

@ -2,6 +2,8 @@
angular.module('copayApp.controllers').controller('preferencesController', angular.module('copayApp.controllers').controller('preferencesController',
function($scope, $rootScope, $filter, $timeout, $modal, $log, lodash, configService, profileService, uxLanguage) { function($scope, $rootScope, $filter, $timeout, $modal, $log, lodash, configService, profileService, uxLanguage) {
this.init = function() {
var config = configService.getSync(); var config = configService.getSync();
this.unitName = config.wallet.settings.unitName; this.unitName = config.wallet.settings.unitName;
this.bwsurl = config.bws.url; this.bwsurl = config.bws.url;
@ -21,6 +23,14 @@ angular.module('copayApp.controllers').controller('preferencesController',
//this.externalIndex = fc.getExternalIndex(); //this.externalIndex = fc.getExternalIndex();
} }
if (window.touchidAvailable) {
var walletId = fc.credentials.walletId;
this.touchidAvailable = true;
config.touchIdFor = config.touchIdFor || {};
$scope.touchid = config.touchIdFor[walletId];
}
};
var unwatchSpendUnconfirmed = $scope.$watch('spendUnconfirmed', function(newVal, oldVal) { var unwatchSpendUnconfirmed = $scope.$watch('spendUnconfirmed', function(newVal, oldVal) {
if (newVal == oldVal) return; if (newVal == oldVal) return;
var opts = { var opts = {
@ -94,10 +104,43 @@ angular.module('copayApp.controllers').controller('preferencesController',
}); });
}); });
var unwatchRequestTouchid = $scope.$watch('touchid', function(newVal, oldVal) {
if (newVal == oldVal || $scope.touchidError) {
$scope.touchidError = false;
return;
}
var walletId = profileService.focusedClient.credentials.walletId;
var opts = {
touchIdFor: {}
};
opts.touchIdFor[walletId] = newVal;
$rootScope.$emit('Local/RequestTouchid', function(err) {
if (err) {
$log.debug(err);
$timeout(function() {
$scope.touchidError = true;
$scope.touchid = oldVal;
}, 100);
}
else {
configService.set(opts, function(err) {
if (err) {
$log.debug(err);
$scope.touchidError = true;
$scope.touchid = oldVal;
}
});
}
});
});
$scope.$on('$destroy', function() { $scope.$on('$destroy', function() {
unwatch(); unwatch();
unwatchSpendUnconfirmed(); unwatchSpendUnconfirmed();
unwatchGlideraEnabled(); unwatchGlideraEnabled();
unwatchGlideraTestnet(); unwatchGlideraTestnet();
unwatchRequestTouchid();
}); });
}); });

View file

@ -5,17 +5,19 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
var self = this; var self = this;
$rootScope.hideMenuBar = false; $rootScope.hideMenuBar = false;
$rootScope.wpInputFocused = false; $rootScope.wpInputFocused = false;
$scope.currentSpendUnconfirmed = configService.getSync().wallet.spendUnconfirmed; var config = configService.getSync();
var configWallet = config.wallet;
$scope.currentSpendUnconfirmed = configWallet.spendUnconfirmed;
// INIT // INIT
var config = configService.getSync().wallet.settings; var walletSettings = configWallet.settings;
this.unitToSatoshi = config.unitToSatoshi; this.unitToSatoshi = walletSettings.unitToSatoshi;
this.satToUnit = 1 / this.unitToSatoshi; this.satToUnit = 1 / this.unitToSatoshi;
this.unitName = config.unitName; this.unitName = walletSettings.unitName;
this.alternativeIsoCode = config.alternativeIsoCode; this.alternativeIsoCode = walletSettings.alternativeIsoCode;
this.alternativeName = config.alternativeName; this.alternativeName = walletSettings.alternativeName;
this.alternativeAmount = 0; this.alternativeAmount = 0;
this.unitDecimals = config.unitDecimals; this.unitDecimals = walletSettings.unitDecimals;
this.isCordova = isCordova; this.isCordova = isCordova;
this.addresses = []; this.addresses = [];
this.isMobile = isMobile.any(); this.isMobile = isMobile.any();
@ -85,6 +87,16 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
$rootScope.hideMenuBar = false; $rootScope.hideMenuBar = false;
}); });
var requestTouchid = function(cb) {
var fc = profileService.focusedClient;
config.touchIdFor = config.touchIdFor || {};
if (window.touchidAvailable && config.touchIdFor[fc.credentials.walletId]) {
$rootScope.$emit('Local/RequestTouchid', cb);
} else {
return cb();
}
};
rateService.whenAvailable(function() { rateService.whenAvailable(function() {
self.isRateAvailable = true; self.isRateAvailable = true;
$rootScope.$digest(); $rootScope.$digest();
@ -264,11 +276,21 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
}); });
return; return;
}; };
self._setOngoingForSigning();
self._setOngoingForSigning();
$scope.loading = true; $scope.loading = true;
$scope.error = null; $scope.error = null;
$timeout(function() { $timeout(function() {
requestTouchid(function(err) {
if (err) {
self.setOngoingProcess();
$scope.loading = false;
profileService.lockFC();
$scope.error = err;
$scope.$digest();
return;
}
profileService.signTxProposal(txp, function(err, txpsi) { profileService.signTxProposal(txp, function(err, txpsi) {
self.setOngoingProcess(); self.setOngoingProcess();
if (err) { if (err) {
@ -304,6 +326,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
} }
} }
}); });
});
}, 100); }, 100);
}; };
@ -789,6 +812,17 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
} }
}; };
requestTouchid(function(err) {
if (err) {
profileService.lockFC();
self.setOngoingProcess();
self.error = err;
$timeout(function() {
$scope.$digest();
}, 1);
return;
}
getFee(function(err, feePerKb) { getFee(function(err, feePerKb) {
if (err) $log.debug(err); if (err) $log.debug(err);
fc.sendTxProposal({ fc.sendTxProposal({
@ -828,6 +862,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
}); });
}); });
}); });
});
}, 100); }, 100);
}; };
@ -1122,7 +1157,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
var fc = profileService.focusedClient; var fc = profileService.focusedClient;
var ModalInstanceCtrl = function($scope, $modalInstance) { var ModalInstanceCtrl = function($scope, $modalInstance) {
$scope.btx = btx; $scope.btx = btx;
$scope.settings = config; $scope.settings = walletSettings;
$scope.color = fc.backgroundColor; $scope.color = fc.backgroundColor;
$scope.copayerId = fc.credentials.copayerId; $scope.copayerId = fc.credentials.copayerId;
$scope.isShared = fc.credentials.n > 1; $scope.isShared = fc.credentials.n > 1;

View file

@ -57,8 +57,6 @@ angular.element(document).ready(function() {
window.location = '#/preferences'; window.location = '#/preferences';
}, false); }, false);
setTimeout(function() { setTimeout(function() {
navigator.splashscreen.hide(); navigator.splashscreen.hide();
}, 2000); }, 2000);
@ -67,6 +65,11 @@ angular.element(document).ready(function() {
window.plugins.webintent.onNewIntent(handleBitcoinURI); window.plugins.webintent.onNewIntent(handleBitcoinURI);
window.handleOpenURL = handleBitcoinURI; window.handleOpenURL = handleBitcoinURI;
window.plugins.touchid.isAvailable(
function(msg) { window.touchidAvailable = true; }, // success handler: TouchID available
function(msg) { window.touchidAvailable = false; } // error handler: no TouchID available
);
startAngular(); startAngular();
}, false); }, false);
} else { } else {