diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 08bcaa2165c..bb3e2f50242 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -168,6 +168,7 @@ import { MasterPasswordServiceAbstraction, } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { MasterPasswordService } from "@bitwarden/common/key-management/master-password/services/master-password.service"; +import { SendPasswordService } from "@bitwarden/common/key-management/sends/send-password.service"; import { DefaultVaultTimeoutService, DefaultVaultTimeoutSettingsService, @@ -1433,6 +1434,11 @@ const safeProviders: SafeProvider[] = [ useExisting: NoopViewCacheService, deps: [], }), + safeProvider({ + provide: SendPasswordService, + useClass: SendPasswordService, + deps: [CryptoFunctionServiceAbstraction], + }), safeProvider({ provide: LoginComponentService, useClass: DefaultLoginComponentService, diff --git a/libs/common/src/key-management/sends/send-password.service.ts b/libs/common/src/key-management/sends/send-password.service.ts new file mode 100644 index 00000000000..e21e8022f55 --- /dev/null +++ b/libs/common/src/key-management/sends/send-password.service.ts @@ -0,0 +1,41 @@ +import { Opaque } from "type-fest"; + +import { Utils } from "../../platform/misc/utils"; +import { SEND_KDF_ITERATIONS } from "../../tools/send/send-kdf"; +import { CryptoFunctionService } from "../crypto/abstractions/crypto-function.service"; + +// TODO: remove this comment: +// Code taken from send access.component.ts load method. + +// TODO: add test file for this service. +/** + * Represents an opaque hashed send password as a base64 encoded string. + */ +export type SendHashedPassword = Opaque; + +/** + * Service for managing passwords for sends. + */ +export class SendPasswordService { + constructor(private cryptoFunctionService: CryptoFunctionService) {} + + async hashPassword(password: string, keyMaterialUrlB64: string): Promise { + if (!password || !keyMaterialUrlB64) { + throw new Error("Password and key material URL base64 string are required."); + } + + // Convert the key material URL base64 string to an array. + const keyMaterialArray = Utils.fromUrlB64ToArray(keyMaterialUrlB64); + + // Derive a password hash using the key material. + const passwordHash = await this.cryptoFunctionService.pbkdf2( + password, + keyMaterialArray, + "sha256", + SEND_KDF_ITERATIONS, + ); + + // Convert the password hash to a base64 string and return as proper type + return Utils.fromBufferToB64(passwordHash) as SendHashedPassword; + } +}