Account menu TS

This commit is contained in:
Mo Bitar
2020-04-12 15:14:09 -05:00
parent 956c9a1814
commit a379ea9f54
2 changed files with 231 additions and 171 deletions

View File

@@ -1,7 +1,8 @@
import { WebDirective } from './../../types';
import { isDesktopApplication, isNullOrUndefined } from '@/utils'; import { isDesktopApplication, isNullOrUndefined } from '@/utils';
import template from '%/directives/account-menu.pug'; import template from '%/directives/account-menu.pug';
import { ProtectedAction } from 'snjs'; import { ProtectedAction, ContentType, SNComponent } from 'snjs';
import { PureCtrl } from '@Controllers'; import { PureCtrl } from '@Controllers/abstract/pure_ctrl';
import { import {
STRING_ACCOUNT_MENU_UNCHECK_MERGE, STRING_ACCOUNT_MENU_UNCHECK_MERGE,
STRING_SIGN_OUT_CONFIRMATION, STRING_SIGN_OUT_CONFIRMATION,
@@ -18,6 +19,9 @@ import {
STRING_GENERATING_REGISTER_KEYS, STRING_GENERATING_REGISTER_KEYS,
StringImportError StringImportError
} from '@/strings'; } from '@/strings';
import { SyncOpStatus } from '@/../../../../snjs/dist/@types/services/sync/sync_op_status';
import { PasswordWizardType } from '@/types';
import { BackupFile } from '@/../../../../snjs/dist/@types/services/protocol_service';
const ELEMENT_ID_IMPORT_PASSWORD_INPUT = 'import-password-request'; const ELEMENT_ID_IMPORT_PASSWORD_INPUT = 'import-password-request';
@@ -25,11 +29,46 @@ const ELEMENT_NAME_AUTH_EMAIL = 'email';
const ELEMENT_NAME_AUTH_PASSWORD = 'password'; const ELEMENT_NAME_AUTH_PASSWORD = 'password';
const ELEMENT_NAME_AUTH_PASSWORD_CONF = 'password_conf'; const ELEMENT_NAME_AUTH_PASSWORD_CONF = 'password_conf';
type FormData = {
email: string
user_password: string
password_conf: string
confirmPassword: boolean
showLogin: boolean
showRegister: boolean
showPasscodeForm: boolean
strictSignin?: boolean
ephemeral: boolean
mfa: { payload: any }
userMfaCode?: string
mergeLocal?: boolean
url: string
authenticating: boolean
status: string
passcode: string
confirmPasscode: string
changingPasscode: boolean
}
type AccountMenuState = {
formData: Partial<FormData>
appVersion: string
passcodeAutoLockOptions: any
user: any
mutable: any
importData: any
}
class AccountMenuCtrl extends PureCtrl { class AccountMenuCtrl extends PureCtrl {
public appVersion: string
private syncStatus?: SyncOpStatus
private closeFunction?: () => void
/* @ngInject */ /* @ngInject */
constructor( constructor(
$timeout, $timeout: ng.ITimeoutService,
appVersion, appVersion: string,
) { ) {
super($timeout); super($timeout);
this.appVersion = appVersion; this.appVersion = appVersion;
@@ -38,15 +77,19 @@ class AccountMenuCtrl extends PureCtrl {
/** @override */ /** @override */
getInitialState() { getInitialState() {
return { return {
appVersion: 'v' + (window.electronAppVersion || this.appVersion), appVersion: 'v' + ((window as any).electronAppVersion || this.appVersion),
passcodeAutoLockOptions: this.application.getLockService().getAutoLockIntervalOptions(), passcodeAutoLockOptions: this.application!.getLockService().getAutoLockIntervalOptions(),
user: this.application.getUser(), user: this.application!.getUser(),
formData: { formData: {
mergeLocal: true, mergeLocal: true,
ephemeral: false ephemeral: false
}, },
mutable: {} mutable: {}
}; } as AccountMenuState;
}
getState() {
return this.state as AccountMenuState;
} }
async onAppKeyChange() { async onAppKeyChange() {
@@ -64,9 +107,9 @@ class AccountMenuCtrl extends PureCtrl {
refreshedCredentialState() { refreshedCredentialState() {
return { return {
user: this.application.getUser(), user: this.application!.getUser(),
canAddPasscode: !this.application.isEphemeralSession(), canAddPasscode: !this.application!.isEphemeralSession(),
hasPasscode: this.application.hasPasscode(), hasPasscode: this.application!.hasPasscode(),
showPasscodeForm: false showPasscodeForm: false
}; };
} }
@@ -76,7 +119,7 @@ class AccountMenuCtrl extends PureCtrl {
this.initProps({ this.initProps({
closeFunction: this.closeFunction closeFunction: this.closeFunction
}); });
this.syncStatus = this.application.getSyncStatus(); this.syncStatus = this.application!.getSyncStatus();
} }
close() { close() {
@@ -86,24 +129,24 @@ class AccountMenuCtrl extends PureCtrl {
} }
async loadHost() { async loadHost() {
const host = await this.application.getHost(); const host = await this.application!.getHost();
this.setState({ this.setState({
server: host, server: host,
formData: { formData: {
...this.state.formData, ...this.getState().formData,
url: host url: host
} }
}); });
} }
onHostInputChange() { onHostInputChange() {
const url = this.state.formData.url; const url = this.getState().formData.url!;
this.application.setHost(url); this.application!.setHost(url);
} }
async loadBackupsAvailability() { async loadBackupsAvailability() {
const hasUser = !isNullOrUndefined(this.application.getUser()); const hasUser = !isNullOrUndefined(this.application!.getUser());
const hasPasscode = this.application.hasPasscode(); const hasPasscode = this.application!.hasPasscode();
const encryptedAvailable = hasUser || hasPasscode; const encryptedAvailable = hasUser || hasPasscode;
function encryptionStatusString() { function encryptionStatusString() {
@@ -120,7 +163,7 @@ class AccountMenuCtrl extends PureCtrl {
encryptionStatusString: encryptionStatusString(), encryptionStatusString: encryptionStatusString(),
encryptionEnabled: encryptedAvailable, encryptionEnabled: encryptedAvailable,
mutable: { mutable: {
...this.state.mutable, ...this.getState().mutable,
backupEncrypted: encryptedAvailable backupEncrypted: encryptedAvailable
} }
}); });
@@ -145,21 +188,21 @@ class AccountMenuCtrl extends PureCtrl {
} }
submitAuthForm() { submitAuthForm() {
if (!this.state.formData.email || !this.state.formData.user_password) { if (!this.getState().formData.email || !this.getState().formData.user_password) {
return; return;
} }
this.blurAuthFields(); this.blurAuthFields();
if (this.state.formData.showLogin) { if (this.getState().formData.showLogin) {
this.login(); this.login();
} else { } else {
this.register(); this.register();
} }
} }
async setFormDataState(formData) { async setFormDataState(formData: Partial<FormData>) {
return this.setState({ return this.setState({
formData: { formData: {
...this.state.formData, ...this.getState().formData,
...formData ...formData
} }
}); });
@@ -170,20 +213,21 @@ class AccountMenuCtrl extends PureCtrl {
status: STRING_GENERATING_LOGIN_KEYS, status: STRING_GENERATING_LOGIN_KEYS,
authenticating: true authenticating: true
}); });
const response = await this.application.signIn({ const formData = this.getState().formData;
email: this.state.formData.email, const response = await this.application!.signIn(
password: this.state.formData.user_password, formData.email!,
strict: this.state.formData.strictSignin, formData.user_password!,
ephemeral: this.state.formData.ephemeral, formData.strictSignin,
mfaKeyPath: this.state.formData.mfa && this.state.formData.mfa.payload.mfa_key, formData.ephemeral,
mfaCode: this.state.formData.userMfaCode, formData.mfa && formData.mfa.payload.mfa_key,
mergeLocal: this.state.formData.mergeLocal formData.userMfaCode,
}); formData.mergeLocal
);
const hasError = !response || response.error; const hasError = !response || response.error;
if (!hasError) { if (!hasError) {
await this.setFormDataState({ await this.setFormDataState({
authenticating: false, authenticating: false,
user_password: null user_password: undefined
}); });
this.close(); this.close();
return; return;
@@ -195,19 +239,17 @@ class AccountMenuCtrl extends PureCtrl {
await this.setFormDataState({ await this.setFormDataState({
showLogin: false, showLogin: false,
mfa: error, mfa: error,
status: null status: undefined
}); });
} else { } else {
await this.setFormDataState({ await this.setFormDataState({
showLogin: true, showLogin: true,
mfa: null, mfa: undefined,
status: null, status: undefined,
user_password: null user_password: undefined
}); });
if (error.message) { if (error.message) {
this.application.alertService.alert({ this.application!.alertService!.alert(error.message);
text: error.message
});
} }
} }
await this.setFormDataState({ await this.setFormDataState({
@@ -216,11 +258,11 @@ class AccountMenuCtrl extends PureCtrl {
} }
async register() { async register() {
const confirmation = this.state.formData.password_conf; const confirmation = this.getState().formData.password_conf;
if (confirmation !== this.state.formData.user_password) { if (confirmation !== this.getState().formData.user_password) {
this.application.alertService.alert({ this.application!.alertService!.alert(
text: STRING_NON_MATCHING_PASSWORDS STRING_NON_MATCHING_PASSWORDS
}); );
return; return;
} }
await this.setFormDataState({ await this.setFormDataState({
@@ -228,15 +270,15 @@ class AccountMenuCtrl extends PureCtrl {
status: STRING_GENERATING_REGISTER_KEYS, status: STRING_GENERATING_REGISTER_KEYS,
authenticating: true authenticating: true
}); });
const response = await this.application.register({ const response = await this.application!.register(
email: this.state.formData.email, this.getState().formData.email!,
password: this.state.formData.user_password, this.getState().formData.user_password!,
ephemeral: this.state.formData.ephemeral, this.getState().formData.ephemeral,
mergeLocal: this.state.formData.mergeLocal this.getState().formData.mergeLocal
}); );
if (!response || response.error) { if (!response || response.error) {
await this.setFormDataState({ await this.setFormDataState({
status: null status: undefined
}); });
const error = response const error = response
? response.error ? response.error
@@ -244,9 +286,9 @@ class AccountMenuCtrl extends PureCtrl {
await this.setFormDataState({ await this.setFormDataState({
authenticating: false authenticating: false
}); });
this.application.alertService.alert({ this.application!.alertService!.alert(
text: error.message error.message
}); );
} else { } else {
await this.setFormDataState({ authenticating: false }); await this.setFormDataState({ authenticating: false });
this.close(); this.close();
@@ -254,34 +296,38 @@ class AccountMenuCtrl extends PureCtrl {
} }
mergeLocalChanged() { mergeLocalChanged() {
if (!this.state.formData.mergeLocal) { if (!this.getState().formData.mergeLocal) {
this.application.alertService.confirm({ this.application!.alertService!.confirm(
text: STRING_ACCOUNT_MENU_UNCHECK_MERGE, STRING_ACCOUNT_MENU_UNCHECK_MERGE,
destructive: true, undefined,
onCancel: () => { undefined,
undefined,
undefined,
() => {
this.setFormDataState({ this.setFormDataState({
mergeLocal: true mergeLocal: true
}); });
} },
}); true,
);
} }
} }
openPasswordWizard() { openPasswordWizard() {
this.close(); this.close();
this.application.presentPasswordWizard(); this.application!.presentPasswordWizard(PasswordWizardType.ChangePassword);
} }
async openPrivilegesModal() { async openPrivilegesModal() {
this.close(); this.close();
const run = () => { const run = () => {
this.application.presentPrivilegesManagementModal(); this.application!.presentPrivilegesManagementModal();
}; };
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege( const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
ProtectedAction.ManagePrivileges ProtectedAction.ManagePrivileges
); );
if (needsPrivilege) { if (needsPrivilege) {
this.application.presentPrivilegesModal( this.application!.presentPrivilegesModal(
ProtectedAction.ManagePrivileges, ProtectedAction.ManagePrivileges,
() => { () => {
run(); run();
@@ -293,33 +339,37 @@ class AccountMenuCtrl extends PureCtrl {
} }
destroyLocalData() { destroyLocalData() {
this.application.alertService.confirm({ this.application!.alertService!.confirm(
text: STRING_SIGN_OUT_CONFIRMATION, STRING_SIGN_OUT_CONFIRMATION,
destructive: true, undefined,
onConfirm: async () => { undefined,
await this.application.signOut(); undefined,
} async () => {
}); await this.application!.signOut();
},
undefined,
true,
);
} }
async submitImportPassword() { async submitImportPassword() {
await this.performImport( await this.performImport(
this.state.importData.data, this.getState().importData.data,
this.state.importData.password this.getState().importData.password
); );
} }
async readFile(file) { async readFile(file: File): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve) => {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = function (e) { reader.onload = (e) => {
try { try {
const data = JSON.parse(e.target.result); const data = JSON.parse(e.target!.result as string);
resolve(data); resolve(data);
} catch (e) { } catch (e) {
this.application.alertService.alert({ this.application!.alertService!.alert(
text: STRING_INVALID_IMPORT_FILE STRING_INVALID_IMPORT_FILE
}); );
} }
}; };
reader.readAsText(file); reader.readAsText(file);
@@ -329,7 +379,7 @@ class AccountMenuCtrl extends PureCtrl {
/** /**
* @template * @template
*/ */
async importFileSelected(files) { async importFileSelected(files: File[]) {
const run = async () => { const run = async () => {
const file = files[0]; const file = files[0];
const data = await this.readFile(file); const data = await this.readFile(file);
@@ -339,7 +389,7 @@ class AccountMenuCtrl extends PureCtrl {
if (data.auth_params) { if (data.auth_params) {
await this.setState({ await this.setState({
importData: { importData: {
...this.state.importData, ...this.getState().importData,
requestPassword: true, requestPassword: true,
data: data data: data
} }
@@ -351,14 +401,14 @@ class AccountMenuCtrl extends PureCtrl {
element.scrollIntoView(false); element.scrollIntoView(false);
} }
} else { } else {
await this.performImport(data, null); await this.performImport(data, undefined);
} }
}; };
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege( const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
ProtectedAction.ManageBackups ProtectedAction.ManageBackups
); );
if (needsPrivilege) { if (needsPrivilege) {
this.application.presentPrivilegesModal( this.application!.presentPrivilegesModal(
ProtectedAction.ManageBackups, ProtectedAction.ManageBackups,
run run
); );
@@ -367,10 +417,10 @@ class AccountMenuCtrl extends PureCtrl {
} }
} }
async performImport(data, password) { async performImport(data: any, password?: string) {
await this.setState({ await this.setState({
importData: { importData: {
...this.state.importData, ...this.getState().importData,
loading: true loading: true
} }
}); });
@@ -380,44 +430,35 @@ class AccountMenuCtrl extends PureCtrl {
}); });
if (errorCount > 0) { if (errorCount > 0) {
const message = StringImportError(errorCount); const message = StringImportError(errorCount);
this.application.alertService.alert({ this.application!.alertService!.alert(
text: message message
}); );
} else { } else {
this.application.alertService.alert({ this.application!.alertService!.alert(
text: STRING_IMPORT_SUCCESS STRING_IMPORT_SUCCESS
}); );
} }
} }
async importJSONData(data, password) { async importJSONData(data: BackupFile, password?: string) {
const { affectedItems, errorCount } = await this.application.importData({ const { errorCount } = await this.application!.importData(
data: data.items, data,
password: password password
}); );
for (const item of affectedItems) {
/**
* Don't want to activate any components during import process in
* case of exceptions breaking up the import proccess
*/
if (item.content_type === 'SN|Component') {
item.active = false;
}
}
return errorCount; return errorCount;
} }
async downloadDataArchive() { async downloadDataArchive() {
this.application.getArchiveService().downloadBackup(this.state.mutable.backupEncrypted); this.application!.getArchiveService().downloadBackup(this.getState().mutable.backupEncrypted);
} }
notesAndTagsCount() { notesAndTagsCount() {
return this.application.getItems({ return this.application!.getItems(
contentType: [ [
'Note', ContentType.Note,
'Tag' ContentType.Tag
] ]
}).length; ).length;
} }
encryptionStatusForNotes() { encryptionStatusForNotes() {
@@ -426,22 +467,22 @@ class AccountMenuCtrl extends PureCtrl {
} }
async reloadAutoLockInterval() { async reloadAutoLockInterval() {
const interval = await this.application.getLockService().getAutoLockInterval(); const interval = await this.application!.getLockService().getAutoLockInterval();
this.setState({ this.setState({
selectedAutoLockInterval: interval selectedAutoLockInterval: interval
}); });
} }
async selectAutoLockInterval(interval) { async selectAutoLockInterval(interval: number) {
const run = async () => { const run = async () => {
await this.application.getLockService().setAutoLockInterval(interval); await this.application!.getLockService().setAutoLockInterval(interval);
this.reloadAutoLockInterval(); this.reloadAutoLockInterval();
}; };
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege( const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
ProtectedAction.ManagePasscode ProtectedAction.ManagePasscode
); );
if (needsPrivilege) { if (needsPrivilege) {
this.application.presentPrivilegesModal( this.application!.presentPrivilegesModal(
ProtectedAction.ManagePasscode, ProtectedAction.ManagePasscode,
() => { () => {
run(); run();
@@ -456,13 +497,13 @@ class AccountMenuCtrl extends PureCtrl {
this.setFormDataState({ this.setFormDataState({
showLogin: false, showLogin: false,
showRegister: false, showRegister: false,
user_password: null, user_password: undefined,
password_conf: null password_conf: undefined
}); });
} }
hasPasscode() { hasPasscode() {
return this.passcodeManager.hasPasscode(); return this.application!.hasPasscode();
} }
addPasscodeClicked() { addPasscodeClicked() {
@@ -472,20 +513,20 @@ class AccountMenuCtrl extends PureCtrl {
} }
submitPasscodeForm() { submitPasscodeForm() {
const passcode = this.state.formData.passcode; const passcode = this.getState().formData.passcode!;
if (passcode !== this.state.formData.confirmPasscode) { if (passcode !== this.getState().formData.confirmPasscode!) {
this.application.alertService.alert({ this.application!.alertService!.alert(
text: STRING_NON_MATCHING_PASSCODES STRING_NON_MATCHING_PASSCODES
}); );
return; return;
} }
(this.state.formData.changingPasscode (this.getState().formData.changingPasscode
? this.application.changePasscode(passcode) ? this.application!.changePasscode(passcode)
: this.application.setPasscode(passcode) : this.application!.setPasscode(passcode)
).then(() => { ).then(() => {
this.setFormDataState({ this.setFormDataState({
passcode: null, passcode: undefined,
confirmPasscode: null, confirmPasscode: undefined,
showPasscodeForm: false showPasscodeForm: false
}); });
}); });
@@ -493,14 +534,14 @@ class AccountMenuCtrl extends PureCtrl {
async changePasscodePressed() { async changePasscodePressed() {
const run = () => { const run = () => {
this.state.formData.changingPasscode = true; this.getState().formData.changingPasscode = true;
this.addPasscodeClicked(); this.addPasscodeClicked();
}; };
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege( const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
ProtectedAction.ManagePasscode ProtectedAction.ManagePasscode
); );
if (needsPrivilege) { if (needsPrivilege) {
this.application.presentPrivilegesModal( this.application!.presentPrivilegesModal(
ProtectedAction.ManagePasscode, ProtectedAction.ManagePasscode,
run run
); );
@@ -511,24 +552,28 @@ class AccountMenuCtrl extends PureCtrl {
async removePasscodePressed() { async removePasscodePressed() {
const run = async () => { const run = async () => {
const signedIn = !isNullOrUndefined(await this.application.getUser()); const signedIn = !isNullOrUndefined(await this.application!.getUser());
let message = STRING_REMOVE_PASSCODE_CONFIRMATION; let message = STRING_REMOVE_PASSCODE_CONFIRMATION;
if (!signedIn) { if (!signedIn) {
message += STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM; message += STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM;
} }
this.application.alertService.confirm({ this.application!.alertService!.confirm(
text: message, message,
destructive: true, undefined,
onConfirm: () => { undefined,
this.application.removePasscode(); undefined,
} () => {
}); this.application!.removePasscode();
},
undefined,
true,
);
}; };
const needsPrivilege = await this.application.privilegesService.actionRequiresPrivilege( const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
ProtectedAction.ManagePasscode ProtectedAction.ManagePasscode
); );
if (needsPrivilege) { if (needsPrivilege) {
this.application.presentPrivilegesModal( this.application!.presentPrivilegesModal(
ProtectedAction.ManagePasscode, ProtectedAction.ManagePasscode,
run run
); );
@@ -542,8 +587,9 @@ class AccountMenuCtrl extends PureCtrl {
} }
} }
export class AccountMenu { export class AccountMenu extends WebDirective {
constructor() { constructor() {
super();
this.restrict = 'E'; this.restrict = 'E';
this.template = template; this.template = template;
this.controller = AccountMenuCtrl; this.controller = AccountMenuCtrl;

View File

@@ -1,3 +1,4 @@
import { WebApplication } from './../application';
import { isDesktopApplication } from '@/utils'; import { isDesktopApplication } from '@/utils';
import { AppStateEvent } from '@/services/state'; import { AppStateEvent } from '@/services/state';
@@ -7,12 +8,20 @@ const LOCK_INTERVAL_NONE = 0;
const LOCK_INTERVAL_IMMEDIATE = 1; const LOCK_INTERVAL_IMMEDIATE = 1;
const LOCK_INTERVAL_ONE_MINUTE = 60 * MILLISECONDS_PER_SECOND; const LOCK_INTERVAL_ONE_MINUTE = 60 * MILLISECONDS_PER_SECOND;
const LOCK_INTERVAL_FIVE_MINUTES = 300 * MILLISECONDS_PER_SECOND; const LOCK_INTERVAL_FIVE_MINUTES = 300 * MILLISECONDS_PER_SECOND;
const LOCK_INTERVAL_ONE_HOUR= 3600 * MILLISECONDS_PER_SECOND; const LOCK_INTERVAL_ONE_HOUR = 3600 * MILLISECONDS_PER_SECOND;
const STORAGE_KEY_AUTOLOCK_INTERVAL = "AutoLockIntervalKey"; const STORAGE_KEY_AUTOLOCK_INTERVAL = "AutoLockIntervalKey";
export class LockManager { export class LockManager {
constructor(application) {
private application: WebApplication
private unsubState: any
private pollFocusInterval: any
private lastFocusState?: 'hidden' | 'visible'
private lockAfterDate?: Date
private lockTimeout?: any
constructor(application: WebApplication) {
this.application = application; this.application = application;
setImmediate(() => { setImmediate(() => {
this.observeVisibility(); this.observeVisibility();
@@ -20,13 +29,15 @@ export class LockManager {
} }
observeVisibility() { observeVisibility() {
this.unsubState = this.application.getAppState().addObserver((eventName) => { this.unsubState = this.application.getAppState().addObserver(
if(eventName === AppStateEvent.WindowDidBlur) { async (eventName) => {
this.documentVisibilityChanged(false); if (eventName === AppStateEvent.WindowDidBlur) {
} else if(eventName === AppStateEvent.WindowDidFocus) { this.documentVisibilityChanged(false);
this.documentVisibilityChanged(true); } else if (eventName === AppStateEvent.WindowDidFocus) {
this.documentVisibilityChanged(true);
}
} }
}); );
if (!isDesktopApplication()) { if (!isDesktopApplication()) {
this.beginWebFocusPolling(); this.beginWebFocusPolling();
} }
@@ -39,21 +50,24 @@ export class LockManager {
} }
} }
async setAutoLockInterval(interval) { async setAutoLockInterval(interval: number) {
return this.application.setValue(STORAGE_KEY_AUTOLOCK_INTERVAL, interval); return this.application!.setValue(
STORAGE_KEY_AUTOLOCK_INTERVAL,
interval
);
} }
async getAutoLockInterval() { async getAutoLockInterval() {
const interval = await this.application.getValue( const interval = await this.application!.getValue(
STORAGE_KEY_AUTOLOCK_INTERVAL, STORAGE_KEY_AUTOLOCK_INTERVAL
); );
if(interval) { if (interval) {
return interval; return interval;
} else { } else {
return LOCK_INTERVAL_NONE; return LOCK_INTERVAL_NONE;
} }
} }
/** /**
* Verify document is in focus every so often as visibilitychange event is * Verify document is in focus every so often as visibilitychange event is
* not triggered on a typical window blur event but rather on tab changes. * not triggered on a typical window blur event but rather on tab changes.
@@ -61,9 +75,9 @@ export class LockManager {
beginWebFocusPolling() { beginWebFocusPolling() {
this.pollFocusInterval = setInterval(() => { this.pollFocusInterval = setInterval(() => {
const hasFocus = document.hasFocus(); const hasFocus = document.hasFocus();
if(hasFocus && this.lastFocusState === 'hidden') { if (hasFocus && this.lastFocusState === 'hidden') {
this.documentVisibilityChanged(true); this.documentVisibilityChanged(true);
} else if(!hasFocus && this.lastFocusState === 'visible') { } else if (!hasFocus && this.lastFocusState === 'visible') {
this.documentVisibilityChanged(false); this.documentVisibilityChanged(false);
} }
/* Save this to compare against next time around */ /* Save this to compare against next time around */
@@ -96,12 +110,12 @@ export class LockManager {
]; ];
} }
async documentVisibilityChanged(visible) { async documentVisibilityChanged(visible: boolean) {
if(visible) { if (visible) {
const locked = await this.application.isLocked(); const locked = await this.application.isLocked();
if( if (
!locked && !locked &&
this.lockAfterDate && this.lockAfterDate &&
new Date() > this.lockAfterDate new Date() > this.lockAfterDate
) { ) {
this.application.lock(); this.application.lock();
@@ -114,7 +128,7 @@ export class LockManager {
async beginAutoLockTimer() { async beginAutoLockTimer() {
var interval = await this.getAutoLockInterval(); var interval = await this.getAutoLockInterval();
if(interval === LOCK_INTERVAL_NONE) { if (interval === LOCK_INTERVAL_NONE) {
return; return;
} }
/** /**
@@ -123,7 +137,7 @@ export class LockManager {
* persisted, as living in memory is sufficient. If memory is cleared, then the * persisted, as living in memory is sufficient. If memory is cleared, then the
* application will lock anyway. * application will lock anyway.
*/ */
const addToNow = (seconds) => { const addToNow = (seconds: number) => {
const date = new Date(); const date = new Date();
date.setSeconds(date.getSeconds() + seconds); date.setSeconds(date.getSeconds() + seconds);
return date; return date;
@@ -132,12 +146,12 @@ export class LockManager {
this.lockTimeout = setTimeout(() => { this.lockTimeout = setTimeout(() => {
this.cancelAutoLockTimer(); this.cancelAutoLockTimer();
this.application.lock(); this.application.lock();
this.lockAfterDate = null; this.lockAfterDate = undefined;
}, interval); }, interval);
} }
cancelAutoLockTimer() { cancelAutoLockTimer() {
clearTimeout(this.lockTimeout); clearTimeout(this.lockTimeout);
this.lockAfterDate = null; this.lockAfterDate = undefined;
} }
} }