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
This commit is contained in:
Oscar Hinton 2020-11-18 22:10:57 +01:00 committed by GitHub
parent f44e99d74d
commit 9e4d000b4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 19 additions and 6 deletions

View File

@ -34,4 +34,5 @@ export abstract class PlatformUtilsService {
readFromClipboard: (options?: any) => Promise<string>;
supportsBiometric: () => Promise<boolean>;
authenticateBiometric: () => Promise<boolean>;
supportsSecureStorage: () => boolean;
}

View File

@ -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();
}

View File

@ -145,4 +145,8 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
authenticateBiometric(): Promise<boolean> {
return Promise.resolve(false);
}
supportsSecureStorage(): boolean {
return false;
}
}

View File

@ -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';
}

View File

@ -219,4 +219,8 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
resolve(val);
});
}
supportsSecureStorage(): boolean {
return true;
}
}

View File

@ -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;
}

View File

@ -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<string, SymmetricCryptoKey>;
constructor(private storageService: StorageService, private secureStorageService: StorageService,
private cryptoFunctionService: CryptoFunctionService) { }
private cryptoFunctionService: CryptoFunctionService, private platformUtilService: PlatformUtilsService) { }
async setKey(key: SymmetricCryptoKey): Promise<any> {
this.key = key;
const option = await this.storageService.get<number>(ConstantsService.vaultTimeoutKey);
const biometric = await this.storageService.get<boolean>(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;

View File

@ -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();