diff --git a/src/js/controllers/lock.js b/src/js/controllers/lockSetup.js similarity index 67% rename from src/js/controllers/lock.js rename to src/js/controllers/lockSetup.js index 13c9fccb7..b9ad3a431 100644 --- a/src/js/controllers/lock.js +++ b/src/js/controllers/lockSetup.js @@ -1,21 +1,16 @@ 'use strict'; -angular.module('copayApp.controllers').controller('lockController', function($state, $scope, $timeout, $log, configService, popupService, gettextCatalog, appConfigService, fingerprintService, profileService, lodash) { +angular.module('copayApp.controllers').controller('lockSetupController', function($state, $scope, $timeout, $log, configService, popupService, gettextCatalog, appConfigService, fingerprintService, profileService, lodash) { function init() { - var config = configService.getSync(); - $scope.locking = config.lock.method != 'pin'; - $scope.options = [ { - method: 'none', + method: null, label: gettextCatalog.getString('Disabled'), - value: config.lock.method == '', }, { method: 'pin', - label: gettextCatalog.getString('Enable PIN'), - value: config.lock.method == 'pin', + label: gettextCatalog.getString('Lock by PIN'), needsBackup: null, }, ]; @@ -23,13 +18,17 @@ angular.module('copayApp.controllers').controller('lockController', function($st if (fingerprintService.isAvailable()) { $scope.options.push({ method: 'fingerprint', - label: gettextCatalog.getString('Enable Fingerprint'), - value: config.lock.method == 'fingerprint', + label: gettextCatalog.getString('Lock by Fingerprint'), needsBackup: null, }); } - $scope.currentOption = lodash.find($scope.options, 'value'); + var config = configService.getSync(); + var method = config.lock && config.lock.method; + if (!method) $scope.currentOption = $scope.options[0]; + else $scope.currentOption = lodash.find($scope.options, { + 'method': method + }); processWallets(); }; @@ -70,21 +69,24 @@ angular.module('copayApp.controllers').controller('lockController', function($st }); }; - $scope.select = function(method) { - if (method == 'none') + $scope.select = function(selectedMethod) { + var config = configService.getSync(); + var savedMethod = config.lock && config.lock.method; + + if (!selectedMethod) saveConfig(); - else if (method == 'fingerprint') { - var config = configService.getSync(); - if (config.lock.method == 'pin') { + else if (selectedMethod == 'fingerprint') { + if (savedMethod == 'pin') { askForDisablePin(function(disablePin) { if (disablePin) saveConfig('fingerprint'); else init(); }); } else saveConfig('fingerprint'); - } else if (method == 'pin') { - $state.transitionTo('tabs.lock.pin', { + } else if (selectedMethod == 'pin') { + if (savedMethod == 'pin') return; + $state.transitionTo('tabs.pin', { fromSettings: true, - locking: $scope.locking + locking: savedMethod == 'pin' ? false : true }); } $timeout(function() { @@ -93,7 +95,7 @@ angular.module('copayApp.controllers').controller('lockController', function($st }; function askForDisablePin(cb) { - var message = gettextCatalog.getString('{{appName}} is protected by Pin. Are you sure you want to disable it?', { + var message = gettextCatalog.getString('{{appName}} startup is locked by PIN. Are you sure you want to disable it?', { appName: appConfigService.nameCase }); var okText = gettextCatalog.getString('Continue'); @@ -107,8 +109,8 @@ angular.module('copayApp.controllers').controller('lockController', function($st function saveConfig(method) { var opts = { lock: { - method: method || '', - value: '', + method: method || null, + value: null, } }; diff --git a/src/js/controllers/pin.js b/src/js/controllers/pin.js index 94dd15d40..3156320fd 100644 --- a/src/js/controllers/pin.js +++ b/src/js/controllers/pin.js @@ -15,6 +15,7 @@ angular.module('copayApp.controllers').controller('pinController', function($sta $scope.$on("$ionicView.enter", function(event) { configService.whenAvailable(function(config) { + if (!config.lock) return; $scope.bannedUntil = config.lock.bannedUntil || null; if ($scope.bannedUntil) { var now = Math.floor(Date.now() / 1000); @@ -156,12 +157,13 @@ angular.module('copayApp.controllers').controller('pinController', function($sta function saveSettings(method, value) { var config = configService.getSync(); + var attempts = config.lock && config.lock.attempts ? config.lock.attempts : 0; var opts = { lock: { - method: method || '', - value: value || '', + method: method || null, + value: value || null, bannedUntil: null, - attempts: config.lock.attempts + 1, + attempts: attempts + 1, } }; @@ -173,7 +175,12 @@ angular.module('copayApp.controllers').controller('pinController', function($sta $scope.close = function(delay) { $timeout(function() { - $ionicHistory.viewHistory().backView ? $ionicHistory.goBack() : $state.go('tabs.home'); + var shouldReturn = $ionicHistory.viewHistory().backView && $ionicHistory.viewHistory().backView.stateName != 'starting'; + + if (shouldReturn) + $ionicHistory.goBack() + else + $state.go('tabs.home'); }, delay || 1); }; }); diff --git a/src/js/controllers/tab-settings.js b/src/js/controllers/tab-settings.js index 80152ca61..843059c84 100644 --- a/src/js/controllers/tab-settings.js +++ b/src/js/controllers/tab-settings.js @@ -54,8 +54,8 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct $scope.isDevel = platformInfo.isDevel; $scope.appName = appConfigService.nameCase; configService.whenAvailable(function(config) { - $scope.locked = config.lock && config.lock.method != '' ? true : false; - $scope.method = config.lock && config.lock.method != '' ? config.lock.method.charAt(0).toUpperCase() + config.lock.method.slice(1) : gettextCatalog.getString('Disabled'); + $scope.locked = config.lock && config.lock.method; + $scope.method = $scope.locked ? config.lock.method.charAt(0).toUpperCase() + config.lock.method.slice(1) : gettextCatalog.getString('Disabled'); }); }); diff --git a/src/js/routes.js b/src/js/routes.js index 0709e011d..1a3b795ee 100644 --- a/src/js/routes.js +++ b/src/js/routes.js @@ -463,16 +463,16 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr } } }) - .state('tabs.lock', { - url: '/lock', + .state('tabs.lockSetup', { + url: '/lockSetup', views: { 'tab-settings@tabs': { - controller: 'lockController', - templateUrl: 'views/lock.html', + controller: 'lockSetupController', + templateUrl: 'views/lockSetup.html', } } }) - .state('tabs.lock.pin', { + .state('tabs.pin', { url: '/pin/:fromSettings/:locking', views: { 'tab-settings@tabs': { @@ -1195,25 +1195,53 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr // Nothing to do }); - $ionicPlatform.on('resume', function() { - configService.whenAvailable(function(config) { - var nextView; - var lock = config.lock; - if (lock && lock.method == 'fingerprint' && fingerprintService.isAvailable()) { - fingerprintService.check('unlockingApp', function(err) { - if (err) goTo('lockedView'); - else if ($ionicHistory.currentStateName() == 'lockedView') goTo('tabs.home'); - }); - } else if (lock && lock.method == 'pin') { - goTo('pin'); - } - function goTo(nextView) { - $state.transitionTo(nextView).then(function() { - if (nextView == 'lockedView') $ionicHistory.clearHistory(); + function checkAndApplyLock(onResume) { + var defaultView = 'tabs.home'; + + if (!platformInfo.isCordova && !platformInfo.isDevel) { + goTo(defaultView); + } + + if (onResume) { + var now = Math.floor(Date.now() / 1000); + if (now < openURLService.unlockUntil) { + $log.debug('Skip startup locking'); + return; + } + } + + function goTo(nextView) { + nextView = nextView || defaultView; + $state.transitionTo(nextView).then(function() { + if (nextView == 'lockedView') + $ionicHistory.clearHistory(); + }); + }; + + startupService.ready(); + + configService.whenAvailable(function(config) { + var lockMethod = config.lock && config.lock.method; + $log.debug('App Lock:' + (lockMethod || 'no')); + + if (lockMethod == 'fingerprint' && fingerprintService.isAvailable()) { + fingerprintService.check('unlockingApp', function(err) { + if (err) + goTo('lockedView'); + if ($ionicHistory.currentStateName() == 'lockedView' || !onResume) + goTo('tabs.home'); }); - }; + } else if (lockMethod == 'pin') { + goTo('pin'); + } else { + goTo(defaultView); + } }); + } + + $ionicPlatform.on('resume', function() { + checkAndApplyLock(true); }); $ionicPlatform.on('menubutton', function() { @@ -1256,33 +1284,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr disableAnimate: true, historyRoot: true }); - if (platformInfo.isCordova || platformInfo.isDevel) { - startupService.ready(); - configService.whenAvailable(function(config) { - var lock = config.lock; - if (fingerprintService.isAvailable() && lock && lock.method == 'fingerprint') { - fingerprintService.check('unlockingApp', function(err) { - if (err) goTo('lockedView'); - else goTo('tabs.home'); - }); - } else if (lock && lock.method == 'pin') { - goTo('pin'); - } else - goTo('tabs.home'); - }); - } else goTo('tabs.home'); - function goTo(nextView) { - $state.transitionTo(nextView).then(function() { - $ionicHistory.clearHistory(); - }); - } + checkAndApplyLock(); }); }; // After everything have been loaded, initialize handler URL $timeout(function() { openURLService.init(); - }, 1000); + }); }); }); diff --git a/src/js/services/configService.js b/src/js/services/configService.js index 3d979af7f..2b92e58ff 100644 --- a/src/js/services/configService.js +++ b/src/js/services/configService.js @@ -54,8 +54,8 @@ angular.module('copayApp.services').factory('configService', function(storageSer }, lock: { - method: '', - value: '', + method: null, + value: null, bannedUntil: null, attempts: null, }, diff --git a/src/js/services/openURL.js b/src/js/services/openURL.js index 7c1af7417..8e6a768cf 100644 --- a/src/js/services/openURL.js +++ b/src/js/services/openURL.js @@ -1,9 +1,15 @@ 'use strict'; angular.module('copayApp.services').factory('openURLService', function($rootScope, $ionicHistory, $document, $log, $state, platformInfo, lodash, profileService, incomingData, appConfigService) { + var DELAY_UNLOCK_TIME = 2 * 60; var root = {}; + root.unlockUntil = null; + var handleOpenURL = function(args) { + root.unlockUntil = Math.floor(Date.now() / 1000) + DELAY_UNLOCK_TIME; + $log.debug('Set unlock time until: ' + root.unlockUntil); + $log.info('Handling Open URL: ' + JSON.stringify(args)); // Stop it from caching the first view as one to return when the app opens $ionicHistory.nextViewOptions({ @@ -103,5 +109,5 @@ angular.module('copayApp.services').factory('openURLService', function($rootScop }); }; -return root; + return root; }); diff --git a/www/views/lock.html b/www/views/lockSetup.html similarity index 88% rename from www/views/lock.html rename to www/views/lockSetup.html index 821cb7310..1bab91b8b 100644 --- a/www/views/lock.html +++ b/www/views/lockSetup.html @@ -1,6 +1,6 @@ - {{'Lock App' | translate}} + {{'Startup Lock' | translate}} diff --git a/www/views/tab-settings.html b/www/views/tab-settings.html index e0bbe0e0e..cfc054614 100644 --- a/www/views/tab-settings.html +++ b/www/views/tab-settings.html @@ -89,7 +89,7 @@ - + {{'Lock App' | translate}}