Session clearing, more actions

This commit is contained in:
Mo Bitar
2018-11-20 13:13:58 -06:00
parent 16296e7f80
commit c5d50728c0
10 changed files with 144 additions and 41 deletions

View File

@@ -22,7 +22,8 @@ angular.module('app')
} }
} }
}) })
.controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory) { .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager,
syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory, privilegesManager) {
this.spellcheck = true; this.spellcheck = true;
this.componentManager = componentManager; this.componentManager = componentManager;
@@ -382,16 +383,28 @@ angular.module('app')
} }
} }
this.deleteNote = function() { this.deleteNote = async function() {
if(this.note.locked) { let run = () => {
alert("This note is locked. If you'd like to delete it, unlock it, and try again."); $timeout(() => {
return; if(this.note.locked) {
alert("This note is locked. If you'd like to delete it, unlock it, and try again.");
return;
}
let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note";
if(confirm(`Are you sure you want to delete ${title}?`)) {
this.remove()(this.note);
this.showMenu = false;
}
});
} }
let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note"; if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDeleteNote)) {
if(confirm(`Are you sure you want to delete ${title}?`)) { privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDeleteNote, () => {
this.remove()(this.note); run();
this.showMenu = false; });
} else {
run();
} }
} }

View File

@@ -169,8 +169,20 @@ class AccountMenu {
authManager.presentPasswordWizard(type); authManager.presentPasswordWizard(type);
} }
$scope.openPrivilegesModal = function() { $scope.openPrivilegesModal = async function() {
privilegesManager.presentPrivilegesManagementModal(); let run = () => {
$timeout(() => {
privilegesManager.presentPrivilegesManagementModal();
})
}
if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePrivileges)) {
privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePrivileges, () => {
run();
});
} else {
run();
}
} }
// Allows indexeddb unencrypted logs to be deleted // Allows indexeddb unencrypted logs to be deleted
@@ -387,8 +399,20 @@ class AccountMenu {
$scope.reloadAutoLockInterval(); $scope.reloadAutoLockInterval();
$scope.selectAutoLockInterval = async function(interval) { $scope.selectAutoLockInterval = async function(interval) {
await passcodeManager.setAutoLockInterval(interval); let run = async () => {
$scope.reloadAutoLockInterval(); await passcodeManager.setAutoLockInterval(interval);
$timeout(() => {
$scope.reloadAutoLockInterval();
});
}
if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) {
privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => {
run();
});
} else {
run();
}
} }
$scope.hasPasscode = function() { $scope.hasPasscode = function() {
@@ -422,27 +446,51 @@ class AccountMenu {
}) })
} }
$scope.changePasscodePressed = function() { $scope.changePasscodePressed = async function() {
$scope.formData.changingPasscode = true; let run = () => {
$scope.addPasscodeClicked(); $timeout(() => {
$scope.formData.changingPasscode = false; $scope.formData.changingPasscode = true;
$scope.addPasscodeClicked();
$scope.formData.changingPasscode = false;
})
}
if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) {
privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => {
run();
});
} else {
run();
}
} }
$scope.removePasscodePressed = function() { $scope.removePasscodePressed = async function() {
var signedIn = !authManager.offline(); let run = () => {
var message = "Are you sure you want to remove your local passcode?"; $timeout(() => {
if(!signedIn) { var signedIn = !authManager.offline();
message += " This will remove encryption from your local data."; var message = "Are you sure you want to remove your local passcode?";
} if(!signedIn) {
if(confirm(message)) { message += " This will remove encryption from your local data.";
passcodeManager.clearPasscode(); }
if(confirm(message)) {
passcodeManager.clearPasscode();
if(authManager.offline()) { if(authManager.offline()) {
syncManager.markAllItemsDirtyAndSaveOffline(); syncManager.markAllItemsDirtyAndSaveOffline();
// Don't create backup here, as if the user is temporarily removing the passcode to change it, // Don't create backup here, as if the user is temporarily removing the passcode to change it,
// we don't want to write unencrypted data to disk. // we don't want to write unencrypted data to disk.
// $rootScope.$broadcast("major-data-change"); // $rootScope.$broadcast("major-data-change");
} }
}
})
}
if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) {
privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => {
run();
});
} else {
run();
} }
} }

View File

@@ -7,6 +7,7 @@ class MenuRow {
this.scope = { this.scope = {
action: "&", action: "&",
circle: "=", circle: "=",
circleAlign: "=",
label: "=", label: "=",
subtitle: "=", subtitle: "=",
hasButton: "=", hasButton: "=",

View File

@@ -28,13 +28,30 @@ class PrivilegesManagementModal {
} }
$scope.isCredentialRequiredForAction = function(action, credential) { $scope.isCredentialRequiredForAction = function(action, credential) {
if(!$scope.privileges) {
return false;
}
return $scope.privileges.isCredentialRequiredForAction(action, credential); return $scope.privileges.isCredentialRequiredForAction(action, credential);
} }
$scope.clearSession = function() {
privilegesManager.clearSession().then(() => {
$scope.reloadPrivileges();
})
}
$scope.reloadPrivileges = async function() { $scope.reloadPrivileges = async function() {
$scope.privileges = await privilegesManager.getPrivileges();
$scope.availableActions = privilegesManager.getAvailableActions(); $scope.availableActions = privilegesManager.getAvailableActions();
$scope.availableCredentials = privilegesManager.getAvailableCredentials(); $scope.availableCredentials = privilegesManager.getAvailableCredentials();
let sessionEndDate = await privilegesManager.getSessionExpirey();
$scope.sessionExpirey = sessionEndDate.toLocaleString();
$scope.sessionExpired = new Date() >= sessionEndDate;
privilegesManager.getPrivileges().then((privs) => {
$timeout(() => {
$scope.privileges = privs;
})
})
} }
$scope.checkboxValueChanged = function(action, credential) { $scope.checkboxValueChanged = function(action, credential) {

View File

@@ -2,7 +2,6 @@ class PasscodeManager {
constructor(authManager, storageManager) { constructor(authManager, storageManager) {
document.addEventListener('visibilitychange', (e) => { document.addEventListener('visibilitychange', (e) => {
console.log("visibilitychange", e, document.visibilityState);
this.documentVisibilityChanged(document.visibilityState); this.documentVisibilityChanged(document.visibilityState);
}); });

View File

@@ -18,12 +18,14 @@ class PrivilegesManager {
PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup"; PrivilegesManager.ActionDownloadBackup = "ActionDownloadBackup";
PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes"; PrivilegesManager.ActionViewLockedNotes = "ActionViewLockedNotes";
PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges";
PrivilegesManager.ActionManagePasscode = "ActionManagePasscode";
PrivilegesManager.ActionDeleteNote = "ActionDeleteNote";
PrivilegesManager.SessionExpiresAtKey = "SessionExpiresAtKey"; PrivilegesManager.SessionExpiresAtKey = "SessionExpiresAtKey";
PrivilegesManager.SessionLengthKey = "SessionLengthKey"; PrivilegesManager.SessionLengthKey = "SessionLengthKey";
PrivilegesManager.SessionLengthNone = 0; PrivilegesManager.SessionLengthNone = 0;
PrivilegesManager.SessionLengthFiveMinutes = 5; PrivilegesManager.SessionLengthFiveMinutes = 300;
PrivilegesManager.SessionLengthOneHour = 3600; PrivilegesManager.SessionLengthOneHour = 3600;
PrivilegesManager.SessionLengthOneWeek = 604800; PrivilegesManager.SessionLengthOneWeek = 604800;
@@ -31,7 +33,9 @@ class PrivilegesManager {
PrivilegesManager.ActionManageExtensions, PrivilegesManager.ActionManageExtensions,
PrivilegesManager.ActionDownloadBackup, PrivilegesManager.ActionDownloadBackup,
PrivilegesManager.ActionViewLockedNotes, PrivilegesManager.ActionViewLockedNotes,
PrivilegesManager.ActionManagePrivileges PrivilegesManager.ActionManagePrivileges,
PrivilegesManager.ActionManagePasscode,
PrivilegesManager.ActionDeleteNote
] ]
this.availableCredentials = [ this.availableCredentials = [
@@ -86,8 +90,6 @@ class PrivilegesManager {
if(cred == PrivilegesManager.CredentialAccountPassword) { if(cred == PrivilegesManager.CredentialAccountPassword) {
if(!this.authManager.offline()) { if(!this.authManager.offline()) {
netCredentials.push(cred); netCredentials.push(cred);
} else {
console.log("WE ARE OFFLINE");
} }
} else if(cred == PrivilegesManager.CredentialLocalPasscode) { } else if(cred == PrivilegesManager.CredentialLocalPasscode) {
if(this.passcodeManager.hasPasscode()) { if(this.passcodeManager.hasPasscode()) {
@@ -174,6 +176,14 @@ class PrivilegesManager {
label: "Manage Privileges" label: "Manage Privileges"
}; };
metadata[PrivilegesManager.ActionManagePasscode] = {
label: "Manage Passcode"
}
metadata[PrivilegesManager.ActionDeleteNote] = {
label: "Delete Note"
}
return metadata[action]; return metadata[action];
} }
@@ -185,11 +195,11 @@ class PrivilegesManager {
}, },
{ {
value: PrivilegesManager.SessionLengthFiveMinutes, value: PrivilegesManager.SessionLengthFiveMinutes,
label: "5 Min" label: "5 Minutes"
}, },
{ {
value: PrivilegesManager.SessionLengthOneHour, value: PrivilegesManager.SessionLengthOneHour,
label: "1 Hr" label: "1 Hour"
}, },
{ {
value: PrivilegesManager.SessionLengthOneWeek, value: PrivilegesManager.SessionLengthOneWeek,
@@ -213,6 +223,10 @@ class PrivilegesManager {
]) ])
} }
async clearSession() {
return this.setSessionLength(PrivilegesManager.SessionLengthNone);
}
async getSelectedSessionLength() { async getSelectedSessionLength() {
let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, StorageManager.FixedEncrypted); let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, StorageManager.FixedEncrypted);
if(length) { if(length) {

View File

@@ -14,6 +14,10 @@
#privileges-modal { #privileges-modal {
width: 700px; width: 700px;
th {
text-align: left;
}
} }
#password-wizard { #password-wizard {

View File

@@ -1,7 +1,7 @@
.row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} .row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"}
.column .column
.left .left
.column{"ng-if" => "circle"} .column{"ng-if" => "circle && (!circleAlign || circleAlign == 'left')"}
.circle.small{"ng-class" => "circle"} .circle.small{"ng-class" => "circle"}
.column{"ng-class" => "{'faded' : faded || disabled}"} .column{"ng-class" => "{'faded' : faded || disabled}"}
.label .label
@@ -13,6 +13,9 @@
%menu-row{"ng-repeat" => "row in subRows", "action" => "row.onClick()", %menu-row{"ng-repeat" => "row in subRows", "action" => "row.onClick()",
"label" => "row.label", "subtitle" => "row.subtitle", "spinner-class" => "row.spinnerClass"} "label" => "row.label", "subtitle" => "row.subtitle", "spinner-class" => "row.spinnerClass"}
.column{"ng-if" => "circle && circleAlign == 'right'"}
.circle.small{"ng-class" => "circle"}
.column{"ng-if" => "hasButton"} .column{"ng-if" => "hasButton"}
.button.info{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} .button.info{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"}
{{buttonText}} {{buttonText}}

View File

@@ -20,6 +20,10 @@
%p {{displayInfoForAction(action)}} %p {{displayInfoForAction(action)}}
%th{"ng-repeat" => "credential in availableCredentials"} %th{"ng-repeat" => "credential in availableCredentials"}
%input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} %input{"type" => "checkbox", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"}
.panel-section{"ng-if" => "sessionExpirey && !sessionExpired"}
%p You will not be asked to authenticate until {{sessionExpirey}}.
%a{"ng-click" => "clearSession()"} Clear Session
.footer .footer
%h2 About Privileges %h2 About Privileges
.panel-section.no-bottom-pad .panel-section.no-bottom-pad

View File

@@ -34,7 +34,7 @@
%menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"} %menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"}
%menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"} %menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"}
%menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"} %menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"}
%menu-row{"label" => "ctrl.note.content.hidePreview ? 'Unhide Preview' : 'Hide Preview'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} %menu-row{"label" => "'Preview'", "circle" => "ctrl.note.content.hidePreview ? 'danger' : 'success'", "circle-align" => "'right'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"}
%menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"} %menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"}
.section .section