1
0
mirror of https://github.com/bitwarden/jslib synced 2025-12-26 13:13:29 +00:00

[bug] Ensure vault locking logic can operate over non-active accounts

This commit is contained in:
addison
2021-11-03 19:47:01 -04:00
parent 90f8318592
commit a32bfa15b7
3 changed files with 31 additions and 25 deletions

View File

@@ -31,16 +31,8 @@ export class CryptoService implements CryptoServiceAbstraction {
}
async setKey(key: SymmetricCryptoKey, userId?: string): Promise<any> {
const storageOptions = userId ?
{ userId, storageLocation: StorageLocation.Memory } :
null;
await this.stateService.setCryptoMasterKey(key, storageOptions);
const suffix = await this.getSuffix();
if (suffix != null) {
await this.stateService.setCryptoMasterKeyB64(key.keyB64, { keySuffix: suffix, userId });
} else {
await this.clearSecretKeyStore();
}
await this.stateService.setCryptoMasterKey(key, { userId });
await this.storeKey(key, userId);
}
async setKeyHash(keyHash: string): Promise<void> {
@@ -711,13 +703,13 @@ export class CryptoService implements CryptoServiceAbstraction {
// Helpers
protected async shouldStoreKey(keySuffix: KeySuffixOptions) {
protected async shouldStoreKey(keySuffix: KeySuffixOptions, userId?: string) {
let shouldStoreKey = false;
if (keySuffix === KeySuffixOptions.Auto) {
const vaultTimeout = await this.stateService.getVaultTimeout();
const vaultTimeout = await this.stateService.getVaultTimeout({ userId });
shouldStoreKey = vaultTimeout == null;
} else if (keySuffix === KeySuffixOptions.Biometric) {
const biometricUnlock = await this.stateService.getBiometricUnlock();
const biometricUnlock = await this.stateService.getBiometricUnlock({ userId });
shouldStoreKey = biometricUnlock && this.platformUtilService.supportsSecureStorage();
}
return shouldStoreKey;
@@ -875,10 +867,10 @@ export class CryptoService implements CryptoServiceAbstraction {
return [new SymmetricCryptoKey(encKey), encKeyEnc];
}
private async getSuffix(): Promise<KeySuffixOptions> {
return await this.shouldStoreKey(KeySuffixOptions.Auto) ?
private async getSuffix(userId?: string): Promise<KeySuffixOptions> {
return await this.shouldStoreKey(KeySuffixOptions.Auto, userId) ?
KeySuffixOptions.Auto :
await this.shouldStoreKey(KeySuffixOptions.Biometric) ?
await this.shouldStoreKey(KeySuffixOptions.Biometric, userId) ?
KeySuffixOptions.Biometric :
null;
}
@@ -887,4 +879,13 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.stateService.setCryptoMasterKeyB64(null, { keySuffix: KeySuffixOptions.Auto, userId });
await this.stateService.setCryptoMasterKeyB64(null, { keySuffix: KeySuffixOptions.Biometric, userId });
}
private async storeKey(key: SymmetricCryptoKey, userId?: string) {
const shouldStoreAuto = await this.shouldStoreKey(KeySuffixOptions.Auto, userId);
await this.stateService.setCryptoMasterKeyB64(shouldStoreAuto ? key.keyB64 : null, { userId, keySuffix: KeySuffixOptions.Auto});
const shouldStoreBiometric = await this.shouldStoreKey(KeySuffixOptions.Biometric, userId);
await this.stateService.setCryptoMasterKeyB64(shouldStoreBiometric ? key.keyB64 : null, { userId, keySuffix: KeySuffixOptions.Biometric });
}
}

View File

@@ -607,7 +607,6 @@ export class StateService implements StateServiceAbstraction {
}
async setCryptoMasterKey(value: SymmetricCryptoKey, options?: StorageOptions): Promise<void> {
options = this.reconcileOptions(options, this.defaultInMemoryOptions);
const account = await this.getAccount(this.reconcileOptions(options, this.defaultInMemoryOptions));
account.cryptoMasterKey = value;
await this.saveAccount(account, this.reconcileOptions(options, this.defaultInMemoryOptions));
@@ -621,7 +620,7 @@ export class StateService implements StateServiceAbstraction {
const account = await this.getAccount(this.reconcileOptions(options, this.defaultSecureStorageOptions));
if (account != null) {
account.cryptoMasterKeyB64 = value;
await this.saveAccount(account, options);
await this.saveAccount(account, this.reconcileOptions(options, this.defaultSecureStorageOptions));
}
} catch (e) {
this.logService.error(e);
@@ -1234,7 +1233,9 @@ export class StateService implements StateServiceAbstraction {
}
private getUserIdFromMemory(options: StorageOptions): string {
return this.state.accounts[options.userId ?? this.state.activeUserId]?.userId;
return options?.userId != null ?
this.state.accounts[options.userId].userId :
this.state.activeUserId;
}
private async getAccountFromDisk(options: StorageOptions): Promise<Account> {
@@ -1273,6 +1274,7 @@ export class StateService implements StateServiceAbstraction {
} else {
await this.storageService.save(account.userId, account);
}
await this.pushAccounts();
}
private async saveAccountToMemory(account: Account): Promise<void> {
@@ -1323,7 +1325,7 @@ export class StateService implements StateServiceAbstraction {
}
private reconcileOptions(requestedOptions: StorageOptions, defaultOptions: StorageOptions): StorageOptions {
if (requestedOptions === null) {
if (requestedOptions == null) {
return defaultOptions;
}
requestedOptions.userId = requestedOptions?.userId ?? defaultOptions.userId;

View File

@@ -94,17 +94,20 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
return;
}
await this.stateService.setBiometricLocked(true, { userId: userId });
if (userId == null || userId === await this.stateService.getUserId()) {
this.searchService.clearIndex();
}
await this.folderService.clearCache(userId);
await this.cipherService.clearCache(userId);
await this.collectionService.clearCache(userId);
await this.stateService.setEverBeenUnlocked(true, { userId: userId });
await this.cryptoService.clearKey(false, userId);
await this.cryptoService.clearOrgKeys(true, userId);
await this.cryptoService.clearKeyPair(true, userId);
await this.cryptoService.clearEncKey(true, userId);
await this.stateService.setBiometricLocked(true, { userId });
await this.folderService.clearCache(userId);
await this.cipherService.clearCache(userId);
await this.collectionService.clearCache(userId);
this.searchService.clearIndex();
this.messagingService.send('locked', { userId });
if (this.lockedCallback != null) {
await this.lockedCallback();