1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00
Files
browser/libs/common/src/key-management/kdf/change-kdf-service.ts
Bernd Schoolmann 4b73198ce5 [PM-23230] Implement KDF Change Service (#15748)
* Add new mp service api

* Fix tests

* Add test coverage

* Add newline

* Fix type

* Rename to "unwrapUserKeyFromMasterPasswordUnlockData"

* Fix build

* Fix build on cli

* Fix linting

* Re-sort spec

* Add tests

* Fix test and build issues

* Fix build

* Clean up

* Remove introduced function

* Clean up comments

* Fix abstract class types

* Fix comments

* Cleanup

* Cleanup

* Update libs/common/src/key-management/master-password/types/master-password.types.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/services/master-password.service.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/types/master-password.types.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Add comments

* Fix build

* Add arg null check

* Cleanup

* Fix build

* Fix build on browser

* Implement KDF change service

* Deprecate encryptUserKeyWithMasterKey

* Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Add tests for null params

* Fix builds

* Cleanup and deprecate more functions

* Fix formatting

* Prettier

* Clean up

* Update libs/key-management/src/abstractions/key.service.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Make emailToSalt private and expose abstract saltForUser

* Add tests

* Add docs

* Fix build

* Fix tests

* Fix tests

* Address feedback and fix primitive obsession

* Consolidate active account checks in change kdf confirmation component

* Update libs/common/src/key-management/kdf/services/change-kdf-service.spec.ts

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>

* Add defensive parameter checks

* Add tests

* Add comment for follow-up epic

* Move change kdf service, remove abstraction and add api service

* Fix test

* Drop redundant null check

* Address feedback

* Add throw on empty password

* Fix tests

* Mark change kdf service as internal

* Add abstract classes

* Switch to abstraction

* use sdk EncString in MasterPasswordUnlockData

* fix remaining tests

---------

Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com>
Co-authored-by: Jake Fink <jfink@bitwarden.com>
2025-09-23 16:10:54 -04:00

60 lines
2.2 KiB
TypeScript

import { assertNonNullish } from "@bitwarden/common/auth/utils";
import { KdfRequest } from "@bitwarden/common/models/request/kdf.request";
import { UserId } from "@bitwarden/common/types/guid";
// eslint-disable-next-line no-restricted-imports
import { KdfConfig, KdfConfigService, KeyService } from "@bitwarden/key-management";
import { MasterPasswordServiceAbstraction } from "../master-password/abstractions/master-password.service.abstraction";
import { firstValueFromOrThrow } from "../utils";
import { ChangeKdfApiService } from "./change-kdf-api.service.abstraction";
import { ChangeKdfService } from "./change-kdf-service.abstraction";
export class DefaultChangeKdfService implements ChangeKdfService {
constructor(
private masterPasswordService: MasterPasswordServiceAbstraction,
private keyService: KeyService,
private kdfConfigService: KdfConfigService,
private changeKdfApiService: ChangeKdfApiService,
) {}
async updateUserKdfParams(masterPassword: string, kdf: KdfConfig, userId: UserId): Promise<void> {
assertNonNullish(masterPassword, "masterPassword");
assertNonNullish(kdf, "kdf");
assertNonNullish(userId, "userId");
const userKey = await firstValueFromOrThrow(this.keyService.userKey$(userId), "userKey");
const salt = await firstValueFromOrThrow(
this.masterPasswordService.saltForUser$(userId),
"salt",
);
const oldKdfConfig = await firstValueFromOrThrow(
this.kdfConfigService.getKdfConfig$(userId),
"oldKdfConfig",
);
const oldAuthenticationData =
await this.masterPasswordService.makeMasterPasswordAuthenticationData(
masterPassword,
oldKdfConfig,
salt,
);
const authenticationData =
await this.masterPasswordService.makeMasterPasswordAuthenticationData(
masterPassword,
kdf,
salt,
);
const unlockData = await this.masterPasswordService.makeMasterPasswordUnlockData(
masterPassword,
kdf,
salt,
userKey,
);
const request = new KdfRequest(authenticationData, unlockData);
request.authenticateWith(oldAuthenticationData);
await this.changeKdfApiService.updateUserKdfParams(request);
}
}