1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 07:43:35 +00:00

[PM-5362] Add MP Service (attempt #2) (#8619)

* create mp and kdf service

* update mp service interface to not rely on active user

* rename observable methods

* update crypto service with new MP service

* add master password service to login strategies
- make fake service for easier testing
- fix crypto service tests

* update auth service and finish strategies

* auth request refactors

* more service refactors and constructor updates

* setMasterKey refactors

* remove master key methods from crypto service

* remove master key and hash from state service

* missed fixes

* create migrations and fix references

* fix master key imports

* default force set password reason to none

* add password reset reason observable factory to service

* remove kdf changes and migrate only disk data

* update migration number

* fix sync service deps

* use disk for force set password state

* fix desktop migration

* fix sso test

* fix tests

* fix more tests

* fix even more tests

* fix even more tests

* fix cli

* remove kdf service abstraction

* add missing deps for browser

* fix merge conflicts

* clear reset password reason on lock or logout

* fix tests

* fix other tests

* add jsdocs to abstraction

* use state provider in crypto service

* inverse master password service factory

* add clearOn to master password service

* add parameter validation to master password service

* add component level userId

* add missed userId

* migrate key hash

* fix login strategy service

* delete crypto master key from account

* migrate master key encrypted user key

* rename key hash to master key hash

* use mp service for getMasterKeyEncryptedUserKey

* fix tests

* fix user key decryption logic

* add clear methods to mp service

* fix circular dep and encryption issue

* fix test

* remove extra account service call

* use EncString in state provider

* fix tests

* return to using encrypted string for serialization
This commit is contained in:
Jake Fink
2024-04-09 20:50:20 -04:00
committed by GitHub
parent c02723d6a6
commit 9d10825dbd
79 changed files with 1373 additions and 501 deletions

View File

@@ -5,14 +5,12 @@ import { AccountService } from "../../auth/abstractions/account.service";
import { TokenService } from "../../auth/abstractions/token.service";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { AdminAuthRequestStorable } from "../../auth/models/domain/admin-auth-req-storable";
import { ForceSetPasswordReason } from "../../auth/models/domain/force-set-password-reason";
import { KdfConfig } from "../../auth/models/domain/kdf-config";
import { BiometricKey } from "../../auth/types/biometric-key";
import { GeneratorOptions } from "../../tools/generator/generator-options";
import { GeneratedPasswordHistory, PasswordGeneratorOptions } from "../../tools/generator/password";
import { UsernameGeneratorOptions } from "../../tools/generator/username";
import { UserId } from "../../types/guid";
import { MasterKey } from "../../types/key";
import { CipherData } from "../../vault/models/data/cipher.data";
import { LocalData } from "../../vault/models/data/local.data";
import { CipherView } from "../../vault/models/view/cipher.view";
@@ -35,7 +33,6 @@ import { EncString } from "../models/domain/enc-string";
import { GlobalState } from "../models/domain/global-state";
import { State } from "../models/domain/state";
import { StorageOptions } from "../models/domain/storage-options";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
import { MigrationRunner } from "./migration-runner";
@@ -273,65 +270,6 @@ export class StateService<
);
}
/**
* @deprecated Do not save the Master Key. Use the User Symmetric Key instead
*/
async getCryptoMasterKey(options?: StorageOptions): Promise<SymmetricCryptoKey> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
);
return account?.keys?.cryptoMasterKey;
}
/**
* User's master key derived from MP, saved only if we decrypted with MP
*/
async getMasterKey(options?: StorageOptions): Promise<MasterKey> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
);
return account?.keys?.masterKey;
}
/**
* User's master key derived from MP, saved only if we decrypted with MP
*/
async setMasterKey(value: MasterKey, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
);
account.keys.masterKey = value;
await this.saveAccount(
account,
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
);
}
/**
* The master key encrypted User symmetric key, saved on every auth
* so we can unlock with MP offline
*/
async getMasterKeyEncryptedUserKey(options?: StorageOptions): Promise<string> {
return (
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
)?.keys.masterKeyEncryptedUserKey;
}
/**
* The master key encrypted User symmetric key, saved on every auth
* so we can unlock with MP offline
*/
async setMasterKeyEncryptedUserKey(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
);
account.keys.masterKeyEncryptedUserKey = value;
await this.saveAccount(
account,
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
);
}
/**
* user key when using the "never" option of vault timeout
*/
@@ -823,30 +761,6 @@ export class StateService<
);
}
async getForceSetPasswordReason(options?: StorageOptions): Promise<ForceSetPasswordReason> {
return (
(
await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()),
)
)?.profile?.forceSetPasswordReason ?? ForceSetPasswordReason.None
);
}
async setForceSetPasswordReason(
value: ForceSetPasswordReason,
options?: StorageOptions,
): Promise<void> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()),
);
account.profile.forceSetPasswordReason = value;
await this.saveAccount(
account,
this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()),
);
}
async getIsAuthenticated(options?: StorageOptions): Promise<boolean> {
return (
(await this.tokenService.getAccessToken(options?.userId as UserId)) != null &&
@@ -897,23 +811,6 @@ export class StateService<
);
}
async getKeyHash(options?: StorageOptions): Promise<string> {
return (
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
)?.profile?.keyHash;
}
async setKeyHash(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
);
account.profile.keyHash = value;
await this.saveAccount(
account,
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
);
}
async getLastActive(options?: StorageOptions): Promise<number> {
options = this.reconcileOptions(options, await this.defaultOnDiskOptions());