diff --git a/src/abstractions/index.ts b/src/abstractions/index.ts index c9d10b5e580..cec535ffabd 100644 --- a/src/abstractions/index.ts +++ b/src/abstractions/index.ts @@ -8,7 +8,6 @@ export { CryptoService } from './crypto.service'; export { EnvironmentService } from './environment.service'; export { FolderService } from './folder.service'; export { I18nService } from './i18n.service'; -export { LockService } from './lock.service'; export { LogService } from './log.service'; export { MessagingService } from './messaging.service'; export { PasswordGenerationService } from './passwordGeneration.service'; @@ -21,3 +20,4 @@ export { SyncService } from './sync.service'; export { TokenService } from './token.service'; export { TotpService } from './totp.service'; export { UserService } from './user.service'; +export { VaultTimeoutService } from './vaultTimeout.service'; diff --git a/src/abstractions/platformUtils.service.ts b/src/abstractions/platformUtils.service.ts index 188bd800901..070abf00275 100644 --- a/src/abstractions/platformUtils.service.ts +++ b/src/abstractions/platformUtils.service.ts @@ -14,6 +14,9 @@ export abstract class PlatformUtilsService { isMacAppStore: () => boolean; analyticsId: () => string; isViewOpen: () => Promise; + /** + * @deprecated This only ever returns null. Pull from your platform's storage using ConstantsService.vaultTimeoutKey + */ lockTimeout: () => number; launchUri: (uri: string, options?: any) => void; saveFile: (win: Window, blobData: any, blobOptions: any, fileName: string) => void; diff --git a/src/abstractions/lock.service.ts b/src/abstractions/vaultTimeout.service.ts similarity index 55% rename from src/abstractions/lock.service.ts rename to src/abstractions/vaultTimeout.service.ts index f43938bb46c..6f1fe5e6fc0 100644 --- a/src/abstractions/lock.service.ts +++ b/src/abstractions/vaultTimeout.service.ts @@ -1,11 +1,12 @@ import { CipherString } from '../models/domain/cipherString'; -export abstract class LockService { +export abstract class VaultTimeoutService { pinProtectedKey: CipherString; isLocked: () => Promise; - checkLock: () => Promise; + checkVaultTimeout: () => Promise; lock: (allowSoftLock?: boolean) => Promise; - setLockOption: (lockOption: number) => Promise; + logout: () => Promise; + setVaultTimeoutOptions: (vaultTimeout: number, vaultTimeoutAction: string) => Promise; isPinLockSet: () => Promise<[boolean, boolean]>; clear: () => Promise; } diff --git a/src/angular/components/lock.component.ts b/src/angular/components/lock.component.ts index 1258b545d5f..107ab471912 100644 --- a/src/angular/components/lock.component.ts +++ b/src/angular/components/lock.component.ts @@ -4,12 +4,12 @@ import { Router } from '@angular/router'; import { CryptoService } from '../../abstractions/crypto.service'; import { EnvironmentService } from '../../abstractions/environment.service'; import { I18nService } from '../../abstractions/i18n.service'; -import { LockService } from '../../abstractions/lock.service'; import { MessagingService } from '../../abstractions/messaging.service'; import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; import { StateService } from '../../abstractions/state.service'; import { StorageService } from '../../abstractions/storage.service'; import { UserService } from '../../abstractions/user.service'; +import { VaultTimeoutService } from '../../abstractions/vaultTimeout.service'; import { ConstantsService } from '../../services/constants.service'; @@ -35,12 +35,12 @@ export class LockComponent implements OnInit { constructor(protected router: Router, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected messagingService: MessagingService, protected userService: UserService, protected cryptoService: CryptoService, - protected storageService: StorageService, protected lockService: LockService, + protected storageService: StorageService, protected vaultTimeoutService: VaultTimeoutService, protected environmentService: EnvironmentService, protected stateService: StateService) { } async ngOnInit() { - this.pinSet = await this.lockService.isPinLockSet(); - this.pinLock = (this.pinSet[0] && this.lockService.pinProtectedKey != null) || this.pinSet[1]; + this.pinSet = await this.vaultTimeoutService.isPinLockSet(); + this.pinLock = (this.pinSet[0] && this.vaultTimeoutService.pinProtectedKey != null) || this.pinSet[1]; this.email = await this.userService.getEmail(); let vaultUrl = this.environmentService.getWebVaultUrl(); if (vaultUrl == null) { @@ -69,7 +69,7 @@ export class LockComponent implements OnInit { try { if (this.pinSet[0]) { const key = await this.cryptoService.makeKeyFromPin(this.pin, this.email, kdf, kdfIterations, - this.lockService.pinProtectedKey); + this.vaultTimeoutService.pinProtectedKey); const encKey = await this.cryptoService.getEncKey(key); const protectedPin = await this.storageService.get(ConstantsService.protectedPin); const decPin = await this.cryptoService.decryptToUtf8(new CipherString(protectedPin), encKey); @@ -106,7 +106,7 @@ export class LockComponent implements OnInit { const encKey = await this.cryptoService.getEncKey(key); const decPin = await this.cryptoService.decryptToUtf8(new CipherString(protectedPin), encKey); const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfIterations); - this.lockService.pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey); + this.vaultTimeoutService.pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey); } this.setKeyAndContinue(key); } else { diff --git a/src/angular/services/auth-guard.service.ts b/src/angular/services/auth-guard.service.ts index d8efd78b77b..0401c378757 100644 --- a/src/angular/services/auth-guard.service.ts +++ b/src/angular/services/auth-guard.service.ts @@ -6,14 +6,14 @@ import { RouterStateSnapshot, } from '@angular/router'; -import { LockService } from '../../abstractions/lock.service'; import { MessagingService } from '../../abstractions/messaging.service'; import { UserService } from '../../abstractions/user.service'; +import { VaultTimeoutService } from '../../abstractions/vaultTimeout.service'; @Injectable() export class AuthGuardService implements CanActivate { - constructor(private lockService: LockService, private userService: UserService, private router: Router, - private messagingService: MessagingService) { } + constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService, + private router: Router, private messagingService: MessagingService) { } async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) { const isAuthed = await this.userService.isAuthenticated(); @@ -22,7 +22,7 @@ export class AuthGuardService implements CanActivate { return false; } - const locked = await this.lockService.isLocked(); + const locked = await this.vaultTimeoutService.isLocked(); if (locked) { if (routerState != null) { this.messagingService.send('lockedUrl', { url: routerState.url }); diff --git a/src/services/constants.service.ts b/src/services/constants.service.ts index 648c85ff544..396ebffa3fa 100644 --- a/src/services/constants.service.ts +++ b/src/services/constants.service.ts @@ -7,7 +7,8 @@ export class ConstantsService { static readonly disableFaviconKey: string = 'disableFavicon'; static readonly disableAutoTotpCopyKey: string = 'disableAutoTotpCopy'; static readonly enableAutoFillOnPageLoadKey: string = 'enableAutoFillOnPageLoad'; - static readonly lockOptionKey: string = 'lockOption'; + static readonly vaultTimeoutKey: string = 'lockOption'; + static readonly vaultTimeoutActionKey: string = 'vaultTimeoutAction'; static readonly lastActiveKey: string = 'lastActive'; static readonly neverDomainsKey: string = 'neverDomains'; static readonly installedVersionKey: string = 'installedVersion'; @@ -30,7 +31,8 @@ export class ConstantsService { readonly disableFaviconKey: string = ConstantsService.disableFaviconKey; readonly disableAutoTotpCopyKey: string = ConstantsService.disableAutoTotpCopyKey; readonly enableAutoFillOnPageLoadKey: string = ConstantsService.enableAutoFillOnPageLoadKey; - readonly lockOptionKey: string = ConstantsService.lockOptionKey; + readonly vaultTimeoutKey: string = ConstantsService.vaultTimeoutKey; + readonly vaultTimeoutActionKey: string = ConstantsService.vaultTimeoutActionKey; readonly lastActiveKey: string = ConstantsService.lastActiveKey; readonly neverDomainsKey: string = ConstantsService.neverDomainsKey; readonly installedVersionKey: string = ConstantsService.installedVersionKey; diff --git a/src/services/crypto.service.ts b/src/services/crypto.service.ts index b0a38f6d232..5fa86444e3c 100644 --- a/src/services/crypto.service.ts +++ b/src/services/crypto.service.ts @@ -19,10 +19,10 @@ import { Utils } from '../misc/utils'; import { EEFLongWordList } from '../misc/wordlist'; const Keys = { - key: 'key', + key: 'key', // Master Key encOrgKeys: 'encOrgKeys', encPrivateKey: 'encPrivateKey', - encKey: 'encKey', + encKey: 'encKey', // Generated Symmetric Key keyHash: 'keyHash', }; @@ -41,7 +41,7 @@ export class CryptoService implements CryptoServiceAbstraction { async setKey(key: SymmetricCryptoKey): Promise { this.key = key; - const option = await this.storageService.get(ConstantsService.lockOptionKey); + const option = await this.storageService.get(ConstantsService.vaultTimeoutKey); if (option != null) { // if we have a lock option set, we do not store the key return; @@ -290,7 +290,7 @@ export class CryptoService implements CryptoServiceAbstraction { async toggleKey(): Promise { const key = await this.getKey(); - const option = await this.storageService.get(ConstantsService.lockOptionKey); + const option = await this.storageService.get(ConstantsService.vaultTimeoutKey); if (option != null || option === 0) { // if we have a lock option set, clear the key await this.clearKey(); diff --git a/src/services/index.ts b/src/services/index.ts index bff56b273c7..dc710996fcd 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -10,7 +10,6 @@ export { CryptoService } from './crypto.service'; export { EnvironmentService } from './environment.service'; export { FolderService } from './folder.service'; export { I18nService } from './i18n.service'; -export { LockService } from './lock.service'; export { PasswordGenerationService } from './passwordGeneration.service'; export { SettingsService } from './settings.service'; export { StateService } from './state.service'; @@ -18,3 +17,4 @@ export { SyncService } from './sync.service'; export { TokenService } from './token.service'; export { TotpService } from './totp.service'; export { UserService } from './user.service'; +export { VaultTimeoutService } from './vaultTimeout.service'; diff --git a/src/services/notifications.service.ts b/src/services/notifications.service.ts index c9f349e3267..5f5026ad6ee 100644 --- a/src/services/notifications.service.ts +++ b/src/services/notifications.service.ts @@ -6,10 +6,10 @@ import { NotificationType } from '../enums/notificationType'; import { ApiService } from '../abstractions/api.service'; import { AppIdService } from '../abstractions/appId.service'; import { EnvironmentService } from '../abstractions/environment.service'; -import { LockService } from '../abstractions/lock.service'; import { NotificationsService as NotificationsServiceAbstraction } from '../abstractions/notifications.service'; import { SyncService } from '../abstractions/sync.service'; import { UserService } from '../abstractions/user.service'; +import { VaultTimeoutService } from '../abstractions/vaultTimeout.service'; import { NotificationResponse, @@ -27,7 +27,7 @@ export class NotificationsService implements NotificationsServiceAbstraction { constructor(private userService: UserService, private syncService: SyncService, private appIdService: AppIdService, private apiService: ApiService, - private lockService: LockService, private logoutCallback: () => Promise) { } + private vaultTimeoutService: VaultTimeoutService, private logoutCallback: () => Promise) { } async init(environmentService: EnvironmentService): Promise { this.inited = false; @@ -190,7 +190,7 @@ export class NotificationsService implements NotificationsServiceAbstraction { private async isAuthedAndUnlocked() { if (await this.userService.isAuthenticated()) { - const locked = await this.lockService.isLocked(); + const locked = await this.vaultTimeoutService.isLocked(); return !locked; } return false; diff --git a/src/services/system.service.ts b/src/services/system.service.ts index aa77cb3d82c..1ec3a138d62 100644 --- a/src/services/system.service.ts +++ b/src/services/system.service.ts @@ -1,8 +1,8 @@ -import { LockService } from '../abstractions/lock.service'; import { MessagingService } from '../abstractions/messaging.service'; import { PlatformUtilsService } from '../abstractions/platformUtils.service'; import { StorageService } from '../abstractions/storage.service'; import { SystemService as SystemServiceAbstraction } from '../abstractions/system.service'; +import { VaultTimeoutService } from '../abstractions/vaultTimeout.service'; import { ConstantsService } from './constants.service'; @@ -13,13 +13,13 @@ export class SystemService implements SystemServiceAbstraction { private clearClipboardTimeout: any = null; private clearClipboardTimeoutFunction: () => Promise = null; - constructor(private storageService: StorageService, private lockService: LockService, + constructor(private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService, private messagingService: MessagingService, private platformUtilsService: PlatformUtilsService, private reloadCallback: () => Promise = null) { } startProcessReload(): void { - if (this.lockService.pinProtectedKey != null || this.reloadInterval != null) { + if (this.vaultTimeoutService.pinProtectedKey != null || this.reloadInterval != null) { return; } this.cancelProcessReload(); diff --git a/src/services/lock.service.ts b/src/services/vaultTimeout.service.ts similarity index 81% rename from src/services/lock.service.ts rename to src/services/vaultTimeout.service.ts index b82c87661e8..6131e4d734d 100644 --- a/src/services/lock.service.ts +++ b/src/services/vaultTimeout.service.ts @@ -4,16 +4,16 @@ import { CipherService } from '../abstractions/cipher.service'; import { CollectionService } from '../abstractions/collection.service'; import { CryptoService } from '../abstractions/crypto.service'; import { FolderService } from '../abstractions/folder.service'; -import { LockService as LockServiceAbstraction } from '../abstractions/lock.service'; import { MessagingService } from '../abstractions/messaging.service'; import { PlatformUtilsService } from '../abstractions/platformUtils.service'; import { SearchService } from '../abstractions/search.service'; import { StorageService } from '../abstractions/storage.service'; import { UserService } from '../abstractions/user.service'; +import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from '../abstractions/vaultTimeout.service'; import { CipherString } from '../models/domain/cipherString'; -export class LockService implements LockServiceAbstraction { +export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { pinProtectedKey: CipherString = null; private inited = false; @@ -32,8 +32,8 @@ export class LockService implements LockServiceAbstraction { this.inited = true; if (checkOnInterval) { - this.checkLock(); - setInterval(() => this.checkLock(), 10 * 1000); // check every 10 seconds + this.checkVaultTimeout(); + setInterval(() => this.checkVaultTimeout(), 10 * 1000); // check every 10 seconds } } @@ -42,12 +42,13 @@ export class LockService implements LockServiceAbstraction { return !hasKey; } - async checkLock(): Promise { + async checkVaultTimeout(): Promise { if (await this.platformUtilsService.isViewOpen()) { // Do not lock return; } + // "is logged out check" - similar to isLocked, below const authed = await this.userService.isAuthenticated(); if (!authed) { return; @@ -59,7 +60,7 @@ export class LockService implements LockServiceAbstraction { let lockOption = this.platformUtilsService.lockTimeout(); if (lockOption == null) { - lockOption = await this.storageService.get(ConstantsService.lockOptionKey); + lockOption = await this.storageService.get(ConstantsService.vaultTimeoutKey); } if (lockOption == null || lockOption < 0) { return; @@ -70,6 +71,7 @@ export class LockService implements LockServiceAbstraction { return; } + // TODO update with vault timeout name and pivot based on action saved const lockOptionSeconds = lockOption * 60; const diffSeconds = ((new Date()).getTime() - lastActive) / 1000; if (diffSeconds >= lockOptionSeconds) { @@ -101,8 +103,13 @@ export class LockService implements LockServiceAbstraction { } } - async setLockOption(lockOption: number): Promise { - await this.storageService.save(ConstantsService.lockOptionKey, lockOption); + async logout(): Promise { + // TODO Add logic for loggedOutCallback + } + + async setVaultTimeoutOptions(vaultTimeout: number, vaultTimeoutAction: string): Promise { + await this.storageService.save(ConstantsService.vaultTimeoutKey, vaultTimeout); + // TODO Add logic for vaultTimeoutAction await this.cryptoService.toggleKey(); }