From af8cdf5a41a73f27a7b7cd4c531207e39a212d37 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 19 Jan 2018 16:59:08 -0600 Subject: [PATCH] Ability to change passcode, passcode with ephemeral sessions --- .../app/directives/views/accountMenu.js | 15 +++++---- .../javascripts/app/services/authManager.js | 3 +- .../app/services/passcodeManager.js | 9 +++-- .../app/services/storageManager.js | 7 ++-- .../directives/account-menu.html.haml | 33 ++++++++++--------- app/assets/templates/footer.html.haml | 2 +- 6 files changed, 39 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index 2efe01744..99714b8f6 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -525,11 +525,6 @@ class AccountMenu { Passcode Lock */ - $scope.passcodeOptionAvailable = function() { - // If you're signed in with an ephemeral session, passcode lock is unavailable - return authManager.offline() || !authManager.isEphemeralSession(); - } - $scope.hasPasscode = function() { return passcodeManager.hasPasscode(); } @@ -545,7 +540,9 @@ class AccountMenu { return; } - passcodeManager.setPasscode(passcode, () => { + let fn = $scope.formData.changingPasscode ? passcodeManager.changePasscode : passcodeManager.setPasscode; + + fn(passcode, () => { $timeout(function(){ $scope.formData.showPasscodeForm = false; var offline = authManager.offline(); @@ -559,6 +556,12 @@ class AccountMenu { }) } + $scope.changePasscodePressed = function() { + $scope.formData.changingPasscode = true; + $scope.addPasscodeClicked(); + $scope.formData.changingPasscode = false; + } + $scope.removePasscodePressed = function() { var signedIn = !authManager.offline(); var message = "Are you sure you want to remove your local passcode?"; diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index af3f39d9c..db2c6a665 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -43,11 +43,10 @@ angular.module('app') this.ephemeral = ephemeral; if(ephemeral) { storageManager.setModelStorageMode(StorageManager.Ephemeral); - storageManager.setItemsMode(storageManager.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Ephemeral); + storageManager.setItemsMode(StorageManager.Ephemeral); } else { storageManager.setModelStorageMode(StorageManager.Fixed); storageManager.setItemsMode(storageManager.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Fixed); - storageManager.setItem("ephemeral", JSON.stringify(false), StorageManager.Fixed); } } diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 28202fdcc..a3a65ca86 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -41,7 +41,7 @@ angular.module('app') }.bind(this)); } - this.setPasscode = function(passcode, callback) { + this.setPasscode = (passcode, callback) => { var cost = Neeto.crypto.defaultPasswordGenerationCost(); var salt = Neeto.crypto.generateRandomKey(512); var defaultParams = {pw_cost: cost, pw_salt: salt, version: "002"}; @@ -60,6 +60,10 @@ angular.module('app') }.bind(this)); } + this.changePasscode = (newPasscode, callback) => { + this.setPasscode(newPasscode, callback); + } + this.clearPasscode = function() { storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.Fixed); // Transfer from Ephemeral storageManager.removeItem("offlineParams", StorageManager.Fixed); @@ -70,7 +74,8 @@ angular.module('app') this.encryptLocalStorage = function(keys) { storageManager.setKeys(keys); // Switch to Ephemeral storage, wiping Fixed storage - storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted); + // Last argument is `force`, which we set to true because in the case of changing passcode + storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted, true); } this.decryptLocalStorage = function(keys) { diff --git a/app/assets/javascripts/app/services/storageManager.js b/app/assets/javascripts/app/services/storageManager.js index 0d2f02164..a81abcb0d 100644 --- a/app/assets/javascripts/app/services/storageManager.js +++ b/app/assets/javascripts/app/services/storageManager.js @@ -62,9 +62,9 @@ class StorageManager { return this._memoryStorage; } - setItemsMode(mode) { + setItemsMode(mode, force) { var newStorage = this.getVault(mode); - if(newStorage !== this.storage) { + if(newStorage !== this.storage || mode !== this.itemsStorageMode || force) { // transfer storages var length = this.storage.length; for(var i = 0; i < length; i++) { @@ -101,6 +101,8 @@ class StorageManager { var storage = this.getVault(vaultKey); storage.setItem(key, value); + console.log(this.itemsStorageMode); + if(vaultKey === StorageManager.FixedEncrypted || (!vaultKey && this.itemsStorageMode === StorageManager.FixedEncrypted)) { this.writeEncryptedStorageToDisk(); } @@ -161,7 +163,6 @@ class StorageManager { for(var key of Object.keys(encryptedStorage.storage)) { this.setItem(key, encryptedStorage.storage[key]); } - } hasPasscode() { diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index de8ac2623..9a7d3c1ac 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -127,29 +127,30 @@ .panel-section %h3.title.panel-row Passcode Lock - %div{"ng-if" => "!hasPasscode() && passcodeOptionAvailable()"} + %div{"ng-if" => "!hasPasscode()"} .panel-row{"ng-if" => "!formData.showPasscodeForm"} .button.info{"ng-click" => "addPasscodeClicked(); $event.stopPropagation();"} .label Add Passcode %p Add an app passcode to lock the app and encrypt on-device key storage. - %form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} - %input.form-control{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} - %input.form-control{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Set Passcode - %a.panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel + %form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} + %input.form-control{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} + %input.form-control{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} + .button-group.stretch.panel-row.form-submit + %button.button.info{"type" => "submit"} + .label Set Passcode + %a.panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel - .panel-row{"ng-if" => "hasPasscode()"} - %p - Passcode lock is enabled. - %span{"ng-if" => "isDesktopApplication()"} Your passcode will be required on new sessions after app quit. - %a.block.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode - - .panel-row{"ng-if" => "!passcodeOptionAvailable()"} - %p Passcode lock is only available to permanent sessions. (You chose not to stay signed in.) + %div{"ng-if" => "hasPasscode() && !formData.showPasscodeForm"} + .panel-row + %p + Passcode lock is enabled. + %span{"ng-if" => "isDesktopApplication()"} Your passcode will be required on new sessions after app quit. + .panel-row.justify-left + .horizontal-group + %a.info{"ng-click" => "changePasscodePressed()"} Change Passcode + %a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index 8712d3b83..bfc79b75b 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -2,7 +2,7 @@ #footer-bar.app-bar.no-edges .left .item{"click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} - .column + .column{"ng-click" => "ctrl.accountMenuPressed()"} .circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} .column{"ng-click" => "ctrl.accountMenuPressed()"} .label.title{"ng-class" => "{red: ctrl.error}"} Account