1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-27515] Fix 2fa settings not working after KDF change (#17070)

* Always derive authentication data fresh for UV

* Cleanup

* Add tests

* Fix remote UV

* Fix test

* Fix test

* Address feedback

* Fix build

* Update libs/common/src/auth/types/verification.ts

Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com>

* Remove unused var

* Fix relative import

* Fix types

---------

Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com>
This commit is contained in:
Bernd Schoolmann
2025-11-07 18:36:02 +01:00
committed by GitHub
parent 40ec682b78
commit 4f9ae78598
6 changed files with 159 additions and 42 deletions

View File

@@ -27,7 +27,7 @@ export abstract class TwoFactorSetupMethodBaseComponent {
enabled = false;
authed = false;
protected hashedSecret: string | undefined;
protected secret: string | undefined;
protected verificationType: VerificationType | undefined;
protected componentName = "";
@@ -42,7 +42,7 @@ export abstract class TwoFactorSetupMethodBaseComponent {
) {}
protected auth(authResponse: AuthResponseBase) {
this.hashedSecret = authResponse.secret;
this.secret = authResponse.secret;
this.verificationType = authResponse.verificationType;
this.authed = true;
}
@@ -132,12 +132,12 @@ export abstract class TwoFactorSetupMethodBaseComponent {
protected async buildRequestModel<T extends SecretVerificationRequest>(
requestClass: new () => T,
) {
if (this.hashedSecret === undefined || this.verificationType === undefined) {
if (this.secret === undefined || this.verificationType === undefined) {
throw new Error("User verification data is missing");
}
return this.userVerificationService.buildRequest(
{
secret: this.hashedSecret,
secret: this.secret,
type: this.verificationType,
},
requestClass,

View File

@@ -1,15 +1,14 @@
import { Component, EventEmitter, Inject, Output } from "@angular/core";
import { Component, Inject } from "@angular/core";
import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
import { UserVerificationFormInputComponent } from "@bitwarden/auth/angular";
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
import { TwoFactorResponse } from "@bitwarden/common/auth/types/two-factor-response";
import { Verification } from "@bitwarden/common/auth/types/verification";
import { VerificationWithSecret } from "@bitwarden/common/auth/types/verification";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import {
@@ -45,14 +44,10 @@ type TwoFactorVerifyDialogData = {
export class TwoFactorVerifyComponent {
type: TwoFactorProviderType;
organizationId: string;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() onAuthed = new EventEmitter<AuthResponse<TwoFactorResponse>>();
formPromise: Promise<TwoFactorResponse> | undefined;
protected formGroup = new FormGroup({
secret: new FormControl<Verification | null>(null),
secret: new FormControl<VerificationWithSecret | null>(null),
});
invalidSecret: boolean = false;
@@ -69,24 +64,19 @@ export class TwoFactorVerifyComponent {
submit = async () => {
try {
let hashedSecret = "";
if (!this.formGroup.value.secret) {
throw new Error("Secret is required");
}
const secret = this.formGroup.value.secret!;
this.formPromise = this.userVerificationService.buildRequest(secret).then((request) => {
hashedSecret =
secret.type === VerificationType.MasterPassword
? request.masterPasswordHash
: request.otp;
return this.apiCall(request);
});
const response = await this.formPromise;
this.dialogRef.close({
response: response,
secret: hashedSecret,
secret: secret.secret,
verificationType: secret.type,
});
} catch (e) {