From 9e4d000b4d02109f8ad3a870327b8dcbb12eb176 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Wed, 18 Nov 2020 22:10:57 +0100 Subject: [PATCH] Browser <-> desktop communication (#185) * Add electron constant for browser integration * Add constant for browser biometrics. Ensure biometry is locked on lock. * Avoid saving keys outside desktop * Fix eslint warning * Add supportsSecureStorage helper to platformUtils to improve readability --- src/abstractions/platformUtils.service.ts | 1 + src/angular/components/lock.component.ts | 3 +-- src/cli/services/cliPlatformUtils.service.ts | 4 ++++ src/electron/electronConstants.ts | 1 + src/electron/services/electronPlatformUtils.service.ts | 4 ++++ src/services/constants.service.ts | 2 ++ src/services/crypto.service.ts | 7 ++++--- src/services/vaultTimeout.service.ts | 3 ++- 8 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/abstractions/platformUtils.service.ts b/src/abstractions/platformUtils.service.ts index f40e07504f..c717b8962b 100644 --- a/src/abstractions/platformUtils.service.ts +++ b/src/abstractions/platformUtils.service.ts @@ -34,4 +34,5 @@ export abstract class PlatformUtilsService { readFromClipboard: (options?: any) => Promise; supportsBiometric: () => Promise; authenticateBiometric: () => Promise; + supportsSecureStorage: () => boolean; } diff --git a/src/angular/components/lock.component.ts b/src/angular/components/lock.component.ts index 423476d891..d14901e713 100644 --- a/src/angular/components/lock.component.ts +++ b/src/angular/components/lock.component.ts @@ -50,7 +50,7 @@ export class LockComponent implements OnInit { this.pinSet = await this.vaultTimeoutService.isPinLockSet(); this.pinLock = (this.pinSet[0] && this.vaultTimeoutService.pinProtectedKey != null) || this.pinSet[1]; this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); - this.biometricLock = await this.vaultTimeoutService.isBiometricLockSet() && await this.cryptoService.hasKey(); + this.biometricLock = await this.vaultTimeoutService.isBiometricLockSet() && (await this.cryptoService.hasKey() || !this.platformUtilsService.supportsSecureStorage()); this.biometricText = await this.storageService.get(ConstantsService.biometricText); this.email = await this.userService.getEmail(); let vaultUrl = this.environmentService.getWebVaultUrl(); @@ -158,7 +158,6 @@ export class LockComponent implements OnInit { } const success = await this.platformUtilsService.authenticateBiometric(); - this.vaultTimeoutService.biometricLocked = !success; if (success) { await this.doContinue(); } diff --git a/src/cli/services/cliPlatformUtils.service.ts b/src/cli/services/cliPlatformUtils.service.ts index f86adfeeac..934ee8a7b0 100644 --- a/src/cli/services/cliPlatformUtils.service.ts +++ b/src/cli/services/cliPlatformUtils.service.ts @@ -145,4 +145,8 @@ export class CliPlatformUtilsService implements PlatformUtilsService { authenticateBiometric(): Promise { return Promise.resolve(false); } + + supportsSecureStorage(): boolean { + return false; + } } diff --git a/src/electron/electronConstants.ts b/src/electron/electronConstants.ts index 8d88ef6b52..849cd7722e 100644 --- a/src/electron/electronConstants.ts +++ b/src/electron/electronConstants.ts @@ -6,4 +6,5 @@ export class ElectronConstants { static readonly enableAlwaysOnTopKey: string = 'enableAlwaysOnTopKey'; static readonly minimizeOnCopyToClipboardKey: string = 'minimizeOnCopyToClipboardKey'; static readonly enableBiometric: string = 'enabledBiometric'; + static readonly enableBrowserIntegration: string = 'enableBrowserIntegration'; } diff --git a/src/electron/services/electronPlatformUtils.service.ts b/src/electron/services/electronPlatformUtils.service.ts index dcefdc8883..f4dfacf980 100644 --- a/src/electron/services/electronPlatformUtils.service.ts +++ b/src/electron/services/electronPlatformUtils.service.ts @@ -219,4 +219,8 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService { resolve(val); }); } + + supportsSecureStorage(): boolean { + return true; + } } diff --git a/src/services/constants.service.ts b/src/services/constants.service.ts index 7e077933d4..d3cca66aec 100644 --- a/src/services/constants.service.ts +++ b/src/services/constants.service.ts @@ -27,6 +27,7 @@ export class ConstantsService { static readonly ssoStateKey: string = 'ssoState'; static readonly biometricUnlockKey: string = 'biometric'; static readonly biometricText: string = 'biometricText'; + static readonly biometricAwaitingAcceptance: string = 'biometricAwaitingAcceptance'; readonly environmentUrlsKey: string = ConstantsService.environmentUrlsKey; readonly disableGaKey: string = ConstantsService.disableGaKey; @@ -55,4 +56,5 @@ export class ConstantsService { readonly ssoStateKey: string = ConstantsService.ssoStateKey; readonly biometricUnlockKey: string = ConstantsService.biometricUnlockKey; readonly biometricText: string = ConstantsService.biometricText; + readonly biometricAwaitingAcceptance: string = ConstantsService.biometricAwaitingAcceptance; } diff --git a/src/services/crypto.service.ts b/src/services/crypto.service.ts index a65402b322..edc63862df 100644 --- a/src/services/crypto.service.ts +++ b/src/services/crypto.service.ts @@ -10,6 +10,7 @@ import { ProfileOrganizationResponse } from '../models/response/profileOrganizat import { CryptoService as CryptoServiceAbstraction } from '../abstractions/crypto.service'; import { CryptoFunctionService } from '../abstractions/cryptoFunction.service'; +import { PlatformUtilsService } from '../abstractions/platformUtils.service'; import { StorageService } from '../abstractions/storage.service'; import { ConstantsService } from './constants.service'; @@ -36,14 +37,14 @@ export class CryptoService implements CryptoServiceAbstraction { private orgKeys: Map; constructor(private storageService: StorageService, private secureStorageService: StorageService, - private cryptoFunctionService: CryptoFunctionService) { } + private cryptoFunctionService: CryptoFunctionService, private platformUtilService: PlatformUtilsService) { } async setKey(key: SymmetricCryptoKey): Promise { this.key = key; const option = await this.storageService.get(ConstantsService.vaultTimeoutKey); const biometric = await this.storageService.get(ConstantsService.biometricUnlockKey); - if (option != null && !biometric) { + if (option != null && !(biometric && this.platformUtilService.supportsSecureStorage())) { // if we have a lock option set, we do not store the key return; } @@ -293,7 +294,7 @@ export class CryptoService implements CryptoServiceAbstraction { const key = await this.getKey(); const option = await this.storageService.get(ConstantsService.vaultTimeoutKey); const biometric = await this.storageService.get(ConstantsService.biometricUnlockKey); - if (!biometric && (option != null || option === 0)) { + if ((!biometric && this.platformUtilService.supportsSecureStorage()) && (option != null || option === 0)) { // if we have a lock option set, clear the key await this.clearKey(); this.key = key; diff --git a/src/services/vaultTimeout.service.ts b/src/services/vaultTimeout.service.ts index f801b554b8..98e5c02f26 100644 --- a/src/services/vaultTimeout.service.ts +++ b/src/services/vaultTimeout.service.ts @@ -97,9 +97,10 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { return; } + this.biometricLocked = true; if (allowSoftLock) { const biometricLocked = await this.isBiometricLockSet(); - if (biometricLocked) { + if (biometricLocked && this.platformUtilsService.supportsSecureStorage()) { this.messagingService.send('locked'); if (this.lockedCallback != null) { await this.lockedCallback();