1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-08 20:50:28 +00:00

PM-13632: Enable sign in with passkeys in the browser extension for chromium browsers (#16385)

* PM-13632: Enable sign in with passkeys in the browser extension

* Refactor component + Icon fix

This commit refactors the login-via-webauthn commit as per @JaredSnider-Bitwarden suggestions. It also fixes an existing issue where Icons are not displayed properly on the web vault.

Remove old one.

Rename the file

Working refactor

Removed the icon from the component

Fixed icons not showing. Changed layout to be 'embedded'

* Add tracking links

* Update app.module.ts

* Remove default Icons on load

* Remove login.module.ts

* Add env changer to the passkey component

* Remove leftover dependencies

* use .isChromium()
This commit is contained in:
Anders Åberg
2025-10-06 15:25:51 +02:00
committed by GitHub
parent 525a6003bc
commit 6cbdecef43
11 changed files with 162 additions and 102 deletions

View File

@@ -1,85 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Directive, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { firstValueFrom } from "rxjs";
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports
import { LoginSuccessHandlerService } from "@bitwarden/auth/common";
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
import { WebAuthnLoginCredentialAssertionView } from "@bitwarden/common/auth/models/view/webauthn-login/webauthn-login-credential-assertion.view";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
import { KeyService } from "@bitwarden/key-management";
export type State = "assert" | "assertFailed";
@Directive()
export class BaseLoginViaWebAuthnComponent implements OnInit {
protected currentState: State = "assert";
protected successRoute = "/vault";
constructor(
private webAuthnLoginService: WebAuthnLoginServiceAbstraction,
private router: Router,
private logService: LogService,
private validationService: ValidationService,
private i18nService: I18nService,
private loginSuccessHandlerService: LoginSuccessHandlerService,
private keyService: KeyService,
) {}
ngOnInit(): void {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.authenticate();
}
protected retry() {
this.currentState = "assert";
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.authenticate();
}
private async authenticate() {
let assertion: WebAuthnLoginCredentialAssertionView;
try {
const options = await this.webAuthnLoginService.getCredentialAssertionOptions();
assertion = await this.webAuthnLoginService.assertCredential(options);
} catch (error) {
this.validationService.showError(error);
this.currentState = "assertFailed";
return;
}
try {
const authResult = await this.webAuthnLoginService.logIn(assertion);
if (authResult.requiresTwoFactor) {
this.validationService.showError(
this.i18nService.t("twoFactorForPasskeysNotSupportedOnClientUpdateToLogIn"),
);
this.currentState = "assertFailed";
return;
}
// Only run loginSuccessHandlerService if webAuthn is used for vault decryption.
const userKey = await firstValueFrom(this.keyService.userKey$(authResult.userId));
if (userKey) {
await this.loginSuccessHandlerService.run(authResult.userId);
}
await this.router.navigate([this.successRoute]);
} catch (error) {
if (error instanceof ErrorResponse) {
this.validationService.showError(this.i18nService.t("invalidPasskeyPleaseTryAgain"));
}
this.logService.error(error);
this.currentState = "assertFailed";
}
}
}