1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-28 15:23:53 +00:00

Unlock with MP via sdk

This commit is contained in:
Bernd Schoolmann
2026-01-20 18:14:10 +01:00
parent 75d06d2e2a
commit 014a33373e
3 changed files with 67 additions and 41 deletions

View File

@@ -55,6 +55,7 @@ import {
} from "@bitwarden/key-management";
import { AccountCryptographicStateService } from "@bitwarden/common/key-management/account-cryptography/account-cryptographic-state.service";
import { UnlockService } from "@bitwarden/unlock";
import {
UnlockOption,
@@ -179,8 +180,7 @@ export class LockComponent implements OnInit, OnDestroy {
private lockComponentService: LockComponentService,
private anonLayoutWrapperDataService: AnonLayoutWrapperDataService,
private encryptedMigrator: EncryptedMigrator,
private registerSdkService: RegisterSdkService,
private accountCryptographicStateService: AccountCryptographicStateService,
private unlockService: UnlockService,
// desktop deps
private broadcasterService: BroadcasterService,
@@ -491,34 +491,8 @@ export class LockComponent implements OnInit, OnDestroy {
const MAX_INVALID_PIN_ENTRY_ATTEMPTS = 5;
try {
await firstValueFrom(
this.registerSdkService.registerClient$(this.activeAccount.id).pipe(
map(async (sdk) => {
if (!sdk) {
throw new Error("SDK not available");
}
using ref = sdk.take();
return ref.value.crypto().initialize_user_crypto({
userId: this.activeAccount.id,
kdfParams: {
pBKDF2: { iterations: 100000 }
},
email: "test@quexten.com",
accountCryptographicState: await firstValueFrom(this.accountCryptographicStateService.accountCryptographicState$(this.activeAccount.id)),
method: {
pinEnvelope: {
pin: pin,
pin_protected_user_key_envelope: await this.pinStateService.getPinProtectedUserKeyEnvelope(
this.activeAccount.id,
"PERSISTENT",
),
}
}
});
}),
)
);
//const userKey = await this.pinService.decryptUserKeyWithPin(pin, this.activeAccount.id);
this.unlockService.unlockWithPin(this.activeAccount.id, pin);
// Backward compatibility. The user-key is already set
const userKey = await firstValueFrom(this.keyService.userKey$(this.activeAccount.id));
if (userKey) {

View File

@@ -26,10 +26,11 @@ import {
IconButtonModule,
ToastService,
} from "@bitwarden/components";
import { BiometricsStatus } from "@bitwarden/key-management";
import { BiometricsStatus, KeyService } from "@bitwarden/key-management";
import { LogService } from "@bitwarden/logging";
import { CommandDefinition, MessageListener } from "@bitwarden/messaging";
import { UserId } from "@bitwarden/user-core";
import { UnlockService } from "@bitwarden/unlock";
import {
UnlockOption,
@@ -52,8 +53,9 @@ import {
],
})
export class MasterPasswordLockComponent implements OnInit, OnDestroy {
private readonly unlockService = inject(UnlockService);
private readonly keyService = inject(KeyService);
private readonly accountService = inject(AccountService);
private readonly masterPasswordUnlockService = inject(MasterPasswordUnlockService);
private readonly i18nService = inject(I18nService);
private readonly toastService = inject(ToastService);
private readonly logService = inject(LogService);
@@ -123,13 +125,12 @@ export class MasterPasswordLockComponent implements OnInit, OnDestroy {
private async unlockViaMasterPassword(
masterPassword: string,
activeUserId: UserId,
userId: UserId,
): Promise<void> {
try {
const userKey = await this.masterPasswordUnlockService.unlockWithMasterPassword(
masterPassword,
activeUserId,
);
await this.unlockService.unlockWithMasterPassword(userId, masterPassword);
// Backward compatibility, the user-key is already set
const userKey = await firstValueFrom(this.keyService.userKey$(userId));
this.successfulUnlock.emit({ userKey, masterPassword });
} catch (error) {
this.logService.error(

View File

@@ -1,6 +1,6 @@
import { UserId } from "@bitwarden/common/types/guid";
import { PinLockType } from "@bitwarden/common/key-management/pin/pin-lock-type";
import { DeviceKey } from "@bitwarden/common/types/key";
import { EncString, UnsignedSharedKey } from "@bitwarden/sdk-internal";
/**
* Service for unlocking a user's account with various methods.
@@ -11,9 +11,60 @@ export abstract class UnlockService {
*
* @param userId - The user's id
* @param pin - The user's PIN
* @param pinLockType - The type of PIN lock (PERSISTENT or EPHEMERAL)
* @throws If the SDK is not available
* @throws If the PIN is invalid or decryption fails
*/
abstract unlockWithPin(userId: UserId, pin: string, pinLockType: PinLockType): Promise<void>;
abstract unlockWithPin(userId: UserId, pin: string): Promise<void>;
/**
* Unlocks the user's account using their master password.
*
* @param userId - The user's id
* @param masterPassword - The user's master password
* @throws If the SDK is not available
* @throws If the master password is invalid or decryption fails
*/
abstract unlockWithMasterPassword(userId: UserId, masterPassword: string): Promise<void>;
/**
* Unlocks the user's account using a device key (trusted device encryption).
*
* @param userId - The user's id
* @param encryptedDevicePrivateKey - The encrypted device private key
* @param encryptedUserKey - The device-protected user key
* @param deviceKey - The device key
* @throws If the SDK is not available
* @throws If decryption fails
*/
abstract unlockWithDeviceKey(
userId: UserId,
encryptedDevicePrivateKey: EncString,
encryptedUserKey: UnsignedSharedKey,
deviceKey: DeviceKey,
): Promise<void>;
/**
* Unlocks the user's account using an auth request (passwordless login).
*
* @param userId - The user's id
* @param privateKey - The request private key
* @param protectedUserKey - The protected user key from the auth request
* @throws If the SDK is not available
* @throws If decryption fails
*/
abstract unlockWithAuthRequest(
userId: UserId,
privateKey: string,
protectedUserKey: UnsignedSharedKey,
): Promise<void>;
/**
* Unlocks the user's account using a key connector.
*
* @param userId - The user's id
* @param keyConnectorUrl - The URL of the key connector service
* @throws If the SDK is not available
* @throws If the key connector request fails or decryption fails
*/
abstract unlockWithKeyConnector(userId: UserId, keyConnectorUrl: string): Promise<void>;
}