mirror of
https://github.com/bitwarden/clients.git
synced 2026-02-09 18:34:13 +08:00
* migrate auth toasts to CL toastService * fix component args * fix component args * fix specs * fix toastService args
134 lines
4.1 KiB
TypeScript
134 lines
4.1 KiB
TypeScript
import { DialogModule } from "@angular/cdk/dialog";
|
|
import { CommonModule } from "@angular/common";
|
|
import { Component, EventEmitter, Inject, OnDestroy, OnInit, Output } from "@angular/core";
|
|
import { ReactiveFormsModule, FormsModule } from "@angular/forms";
|
|
import { ActivatedRoute } from "@angular/router";
|
|
import { firstValueFrom } from "rxjs";
|
|
|
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
|
import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe";
|
|
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
|
import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe";
|
|
import { ClientType } from "@bitwarden/common/enums";
|
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
import {
|
|
ButtonModule,
|
|
LinkModule,
|
|
TypographyModule,
|
|
FormFieldModule,
|
|
AsyncActionsModule,
|
|
ToastService,
|
|
} from "@bitwarden/components";
|
|
|
|
@Component({
|
|
standalone: true,
|
|
selector: "app-two-factor-auth-webauthn",
|
|
templateUrl: "two-factor-auth-webauthn.component.html",
|
|
imports: [
|
|
CommonModule,
|
|
JslibModule,
|
|
DialogModule,
|
|
ButtonModule,
|
|
LinkModule,
|
|
TypographyModule,
|
|
ReactiveFormsModule,
|
|
FormFieldModule,
|
|
AsyncActionsModule,
|
|
FormsModule,
|
|
],
|
|
providers: [I18nPipe],
|
|
})
|
|
export class TwoFactorAuthWebAuthnComponent implements OnInit, OnDestroy {
|
|
@Output() token = new EventEmitter<string>();
|
|
|
|
webAuthnReady = false;
|
|
webAuthnNewTab = false;
|
|
webAuthnSupported = false;
|
|
webAuthn: WebAuthnIFrame = null;
|
|
|
|
constructor(
|
|
protected i18nService: I18nService,
|
|
protected platformUtilsService: PlatformUtilsService,
|
|
@Inject(WINDOW) protected win: Window,
|
|
protected environmentService: EnvironmentService,
|
|
protected twoFactorService: TwoFactorService,
|
|
protected route: ActivatedRoute,
|
|
private toastService: ToastService,
|
|
) {
|
|
this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win);
|
|
|
|
if (this.platformUtilsService.getClientType() == ClientType.Browser) {
|
|
// FIXME: Chromium 110 has broken WebAuthn support in extensions via an iframe
|
|
this.webAuthnNewTab = true;
|
|
}
|
|
}
|
|
|
|
async ngOnInit(): Promise<void> {
|
|
if (this.route.snapshot.paramMap.has("webAuthnResponse")) {
|
|
this.token.emit(this.route.snapshot.paramMap.get("webAuthnResponse"));
|
|
}
|
|
|
|
this.cleanupWebAuthn();
|
|
|
|
if (this.win != null && this.webAuthnSupported) {
|
|
const env = await firstValueFrom(this.environmentService.environment$);
|
|
const webVaultUrl = env.getWebVaultUrl();
|
|
this.webAuthn = new WebAuthnIFrame(
|
|
this.win,
|
|
webVaultUrl,
|
|
this.webAuthnNewTab,
|
|
this.platformUtilsService,
|
|
this.i18nService,
|
|
(token: string) => {
|
|
this.token.emit(token);
|
|
},
|
|
(error: string) => {
|
|
this.toastService.showToast({
|
|
variant: "error",
|
|
title: this.i18nService.t("errorOccurred"),
|
|
message: this.i18nService.t("webauthnCancelOrTimeout"),
|
|
});
|
|
},
|
|
(info: string) => {
|
|
if (info === "ready") {
|
|
this.webAuthnReady = true;
|
|
}
|
|
},
|
|
);
|
|
|
|
if (!this.webAuthnNewTab) {
|
|
setTimeout(async () => {
|
|
await this.authWebAuthn();
|
|
}, 500);
|
|
}
|
|
}
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.cleanupWebAuthn();
|
|
}
|
|
|
|
async authWebAuthn() {
|
|
const providerData = (await this.twoFactorService.getProviders()).get(
|
|
TwoFactorProviderType.WebAuthn,
|
|
);
|
|
|
|
if (!this.webAuthnSupported || this.webAuthn == null) {
|
|
return;
|
|
}
|
|
|
|
this.webAuthn.init(providerData);
|
|
}
|
|
|
|
private cleanupWebAuthn() {
|
|
if (this.webAuthn != null) {
|
|
this.webAuthn.stop();
|
|
this.webAuthn.cleanup();
|
|
}
|
|
}
|
|
}
|