From 9835992e166c03334f3106f104f939cdc8e88522 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 12 Nov 2018 15:16:50 -0600 Subject: [PATCH] Privs small refactor --- .../directives/functional/infiniteScroll.js | 3 - .../directives/views/privilegesAuthModal.js | 26 +++++---- .../views/privilegesManagementModal.js | 47 +++++++--------- .../javascripts/app/models/privileges.js | 34 ++++++++++++ .../javascripts/app/services/modelManager.js | 3 +- .../app/services/privilegesManager.js | 55 ++++++------------- .../privileges-auth-modal.html.haml | 8 +-- .../privileges-management-modal.html.haml | 13 ++--- 8 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 app/assets/javascripts/app/models/privileges.js diff --git a/app/assets/javascripts/app/directives/functional/infiniteScroll.js b/app/assets/javascripts/app/directives/functional/infiniteScroll.js index 3e1e633ef..21bacd325 100644 --- a/app/assets/javascripts/app/directives/functional/infiniteScroll.js +++ b/app/assets/javascripts/app/directives/functional/infiniteScroll.js @@ -2,9 +2,6 @@ angular.module('app').directive('infiniteScroll', [ '$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) { return { link: function(scope, elem, attrs) { - // elem.css('overflow-x', 'hidden'); - // elem.css('height', 'inherit'); - var offset = parseInt(attrs.threshold) || 0; var e = elem[0] diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js index 087d1ae04..99dad564d 100644 --- a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -24,35 +24,41 @@ class PrivilegesAuthModal { controller($scope, privilegesManager, $timeout) { 'ngInject'; - privilegesManager.requiredCredentialsForAction($scope.action).then((privs) => { + $scope.authenticationParameters = {}; + + privilegesManager.getPrivileges().then((privileges) => { $timeout(() => { - $scope.privileges = privs; + $scope.privileges = privileges; + $scope.requiredCredentials = privileges.getCredentialsForAction($scope.action); }) - }) + }); + + $scope.promptForCredential = function(credential) { + return privilegesManager.displayInfoForCredential(credential).prompt; + } $scope.cancel = function() { $scope.dismiss(); $scope.onCancel && $scope.onCancel(); } - $scope.doesPrivHaveFail = function(priv) { - if(!$scope.failedPrivs) { + $scope.isCredentialInFailureState = function(credential) { + if(!$scope.failedCredentials) { return false; } - return $scope.failedPrivs.find((failedPriv) => { - return failedPriv.name == priv.name; + return $scope.failedCredentials.find((candidate) => { + return candidate == credential; }) != null; } $scope.submit = function() { - privilegesManager.authenticateAction($scope.action, $scope.privileges).then((result) => { - console.log("Result", result); + privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => { $timeout(() => { if(result.success) { $scope.onSuccess(); $scope.dismiss(); } else { - $scope.failedPrivs = result.failedPrivs; + $scope.failedCredentials = result.failedCredentials; } }) }) diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js index a1c4aaa45..b792d3858 100644 --- a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -17,36 +17,29 @@ class PrivilegesManagementModal { controller($scope, privilegesManager, $timeout) { 'ngInject'; - $scope.reloadPrivileges = async function() { - console.log("Reloading privs"); - $scope.availableActions = privilegesManager.getAvailableActions(); - $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + $scope.dummy = {}; - let metadata = {}; - for(let action of $scope.availableActions) { - var requiredCreds = await privilegesManager.requiredCredentialsForAction(action); - metadata[action] = { - displayInfo: privilegesManager.displayInfoForAction(action), - requiredCredentials: requiredCreds - } - - metadata[action]["credentialValues"] = {}; - for(var availableCred of $scope.availableCredentials) { - metadata[action]["credentialValues"][availableCred] = requiredCreds.includes(availableCred); - } - } - - $timeout(() => { - $scope.metadata = metadata; - }) + $scope.displayInfoForCredential = function(credential) { + return privilegesManager.displayInfoForCredential(credential).label; } - $scope.checkboxValueChanged = function(action) { - let credentialValues = $scope.metadata[action]["credentialValues"]; - let keys = Object.keys(credentialValues).filter((key) => { - return credentialValues[key] == true; - }); - privilegesManager.setCredentialsForAction(action, keys); + $scope.displayInfoForAction = function(action) { + return privilegesManager.displayInfoForAction(action).label; + } + + $scope.isCredentialRequiredForAction = function(action, credential) { + return $scope.privileges.isCredentialRequiredForAction(action, credential); + } + + $scope.reloadPrivileges = async function() { + $scope.privileges = await privilegesManager.getPrivileges(); + $scope.availableActions = privilegesManager.getAvailableActions(); + $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + } + + $scope.checkboxValueChanged = function(action, credential) { + $scope.privileges.toggleCredentialForAction(action, credential); + privilegesManager.savePrivileges(); } $scope.reloadPrivileges(); diff --git a/app/assets/javascripts/app/models/privileges.js b/app/assets/javascripts/app/models/privileges.js new file mode 100644 index 000000000..3fb5f96fa --- /dev/null +++ b/app/assets/javascripts/app/models/privileges.js @@ -0,0 +1,34 @@ +class SNPrivileges extends SFItem { + + setCredentialsForAction(action, credentials) { + this.content.desktopPrivileges[action] = credentials; + } + + getCredentialsForAction(action) { + return this.content.desktopPrivileges[action] || []; + } + + toggleCredentialForAction(action, credential) { + if(this.isCredentialRequiredForAction(action, credential)) { + this.removeCredentialForAction(action, credential); + } else { + this.addCredentialForAction(action, credential); + } + } + + removeCredentialForAction(action, credential) { + _.pull(this.content.desktopPrivileges[action], credential); + } + + addCredentialForAction(action, credential) { + var credentials = this.getCredentialsForAction(action); + credentials.push(credential); + this.setCredentialsForAction(action, credentials); + } + + isCredentialRequiredForAction(action, credential) { + var credentialsRequired = this.getCredentialsForAction(action); + return credentialsRequired.includes(credential); + } + +} diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index c3f30c207..9af2df562 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -7,7 +7,8 @@ SFModelManager.ContentTypeClassMapping = { "SN|Theme" : SNTheme, "SN|Component" : SNComponent, "SF|Extension" : SNServerExtension, - "SF|MFA" : SNMfa + "SF|MFA" : SNMfa, + "SN|Privileges" : SNPrivileges }; SFItem.AppDomain = "org.standardnotes.sn"; diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js index 857a55d9f..18dd7c386 100644 --- a/app/assets/javascripts/app/services/privilegesManager.js +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -74,12 +74,12 @@ class PrivilegesManager { this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { this.privileges = resolvedSingleton; if(!this.privileges.content.desktopPrivileges) { - this.privileges.content.desktopPrivileges = []; + this.privileges.content.desktopPrivileges = {}; } resolve(resolvedSingleton); }, (valueCallback) => { // Safe to create. Create and return object. - var privs = new SFItem({content_type: prefsContentType}); + var privs = new Privilege({content_type: prefsContentType}); this.modelManager.addItem(privs); privs.setDirty(true); this.$rootScope.sync(); @@ -97,11 +97,6 @@ class PrivilegesManager { } } - async requiredCredentialsForAction(action) { - let privs = await this.getPrivileges(); - return privs.content.desktopPrivileges[action] || []; - } - displayInfoForCredential(credential) { let metadata = {} @@ -132,14 +127,7 @@ class PrivilegesManager { } async actionRequiresPrivilege(action) { - return (await this.requiredCredentialsForAction(action)).length > 0; - } - - async setCredentialsForAction(action, credentials) { - console.log("Setting credentials for action", action, credentials); - let privs = await this.getPrivileges(); - privs.content.desktopPrivileges[action] = credentials; - this.savePrivileges(); + return (await this.getPrivileges()).getCredentialsForAction(action).length > 0; } async savePrivileges() { @@ -148,34 +136,27 @@ class PrivilegesManager { this.$rootScope.sync(); } - async authenticateAction(action, inputPrivs) { + async authenticateAction(action, credentialAuthMapping) { + var requiredCredentials = (await this.getPrivileges()).getCredentialsForAction(action); + var successfulCredentials = [], failedCredentials = []; - let findInputPriv = (name) => { - return inputPrivs.find((priv) => { - return priv.name == name; - }) - } - - var requiredPrivileges = await this.requiredCredentialsForAction(action); - var successfulPrivs = [], failedPrivs = []; - for(let requiredPriv of requiredPrivileges) { - var matchingPriv = findInputPriv(requiredPriv.name); - var passesAuth = await this._verifyAuthenticationParameters(matchingPriv); + for(let requiredCredential of requiredCredentials) { + var passesAuth = await this._verifyAuthenticationParameters(requiredCredential, credentialAuthMapping[requiredCredential]); if(passesAuth) { - successfulPrivs.push(matchingPriv); + successfulCredentials.push(requiredCredential); } else { - failedPrivs.push(matchingPriv); + failedCredentials.push(requiredCredential); } } return { - success: failedPrivs.length == 0, - successfulPrivs: successfulPrivs, - failedPrivs: failedPrivs + success: failedCredentials.length == 0, + successfulCredentials: successfulCredentials, + failedCredentials: failedCredentials } } - async _verifyAuthenticationParameters(parameters) { + async _verifyAuthenticationParameters(credential, value) { let verifyAccountPassword = async (password) => { return this.authManager.verifyAccountPassword(password); @@ -185,10 +166,10 @@ class PrivilegesManager { return this.passcodeManager.verifyPasscode(passcode); } - if(parameters.name == PrivilegesManager.CredentialAccountPassword) { - return verifyAccountPassword(parameters.authenticationValue); - } else if(parameters.name == PrivilegesManager.CredentialLocalPasscode) { - return verifyLocalPasscode(parameters.authenticationValue); + if(credential == PrivilegesManager.CredentialAccountPassword) { + return verifyAccountPassword(value); + } else if(credential == PrivilegesManager.CredentialLocalPasscode) { + return verifyLocalPasscode(value); } } diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml index a83f99b80..2603614a0 100644 --- a/app/assets/templates/directives/privileges-auth-modal.html.haml +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -8,10 +8,10 @@ %a.close-button.info{"ng-click" => "cancel()"} Cancel .content .panel-section - .panel-row{"ng-repeat" => "priv in privileges"} - %p {{priv.prompt}} - %input{"type" => "password", "ng-model" => "priv.authenticationValue"} - %label.danger{"ng-if" => "doesPrivHaveFail(priv)"} Invalid authentication. Please try again. + .panel-row{"ng-repeat" => "credential in requiredCredentials"} + %p {{promptForCredential(credential)}} + %input{"type" => "password", "ng-model" => "authenticationParameters[credential]"} + %label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. .footer .button.info.big.block.bold{"ng-click" => "submit()"} Submit diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml index 028393d74..94292cf7e 100644 --- a/app/assets/templates/directives/privileges-management-modal.html.haml +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -5,7 +5,7 @@ .panel .header %h1.title Manage Privileges - %a.close-button.info{"ng-click" => "cancel()"} Cancel + %a.close-button.info{"ng-click" => "cancel()"} Done .content .panel-section %table @@ -13,13 +13,10 @@ %tr %th %th{"ng-repeat" => "cred in availableCredentials"} - {{cred}} + {{displayInfoForCredential(cred)}} %tbody %tr{"ng-repeat" => "action in availableActions"} %td - %p {{metadata[action].displayInfo.label}} - %th{"ng-repeat" => "cred in availableCredentials"} - %input{"type" => "checkbox", "ng-model" => "metadata[action]['credentialValues'][cred]", "ng-change" => "checkboxValueChanged(action)"} - - .footer - .button.info.big.block.bold{"ng-click" => "submit()"} Save + %p {{displayInfoForAction(action)}} + %th{"ng-repeat" => "credential in availableCredentials"} + %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"}