From f999e2cea96695df8458460a91a88b0dc8f53594 Mon Sep 17 00:00:00 2001 From: Will Martin Date: Mon, 11 Sep 2023 14:54:23 -0400 Subject: [PATCH] [PM-3763] remove Sweet Alert from desktop and browser (#6138) * update desktop and browser swal references to use CL * rename bit-dialog-close * share fingerprint dialog between desktop and browser * apply code review * format fingerprint in template * apply code review * fix button color * fix button types * update var names * close awaitDesktop dialog on success AND error * add DialogService to NativeMessageHandlerService deps * wrap browser message dialogs in ngZone.run * wrap native messaging handler in ngzone.run * apply code review * fix async ngzone --------- Co-authored-by: Daniel James Smith --- .../background/nativeMessaging.background.ts | 7 +-- apps/browser/src/popup/app.component.ts | 24 +++------ ...op-sync-verification-dialog.component.html | 18 +++++++ ...ktop-sync-verification-dialog.component.ts | 24 +++++++++ .../await-desktop-dialog.component.html | 11 ++++ .../await-desktop-dialog.component.ts | 17 ++++++ .../src/popup/settings/settings.component.ts | 47 +++++------------ apps/desktop/src/app/app.component.ts | 15 ++---- ...er-sync-verification-dialog.component.html | 19 +++++++ ...wser-sync-verification-dialog.component.ts | 25 +++++++++ ...ify-native-messaging-dialog.component.html | 18 +++++++ ...erify-native-messaging-dialog.component.ts | 24 +++++++++ .../src/app/services/services.module.ts | 1 + .../native-message-handler.service.ts | 26 ++++------ .../src/services/native-messaging.service.ts | 52 +++++++++---------- .../manage/group-add-edit.component.html | 8 +-- .../fingerprint-dialog.component.html | 23 ++++++++ .../fingerprint-dialog.component.ts | 22 ++++++++ libs/auth/src/index.ts | 1 + .../directives/dialog-close.directive.ts | 4 +- 20 files changed, 268 insertions(+), 118 deletions(-) create mode 100644 apps/browser/src/popup/components/desktop-sync-verification-dialog.component.html create mode 100644 apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts create mode 100644 apps/browser/src/popup/settings/await-desktop-dialog.component.html create mode 100644 apps/browser/src/popup/settings/await-desktop-dialog.component.ts create mode 100644 apps/desktop/src/app/components/browser-sync-verification-dialog.component.html create mode 100644 apps/desktop/src/app/components/browser-sync-verification-dialog.component.ts create mode 100644 apps/desktop/src/app/components/verify-native-messaging-dialog.component.html create mode 100644 apps/desktop/src/app/components/verify-native-messaging-dialog.component.ts create mode 100644 libs/auth/src/components/fingerprint-dialog.component.html create mode 100644 libs/auth/src/components/fingerprint-dialog.component.ts diff --git a/apps/browser/src/background/nativeMessaging.background.ts b/apps/browser/src/background/nativeMessaging.background.ts index d393022b7b..88fd81a3a7 100644 --- a/apps/browser/src/background/nativeMessaging.background.ts +++ b/apps/browser/src/background/nativeMessaging.background.ts @@ -422,9 +422,10 @@ export class NativeMessagingBackground { } private async showFingerprintDialog() { - const fingerprint = ( - await this.cryptoService.getFingerprint(await this.stateService.getUserId(), this.publicKey) - ).join(" "); + const fingerprint = await this.cryptoService.getFingerprint( + await this.stateService.getUserId(), + this.publicKey + ); this.messagingService.send("showNativeMessagingFinterprintDialog", { fingerprint: fingerprint, diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 815109c549..4af5b49b52 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -9,8 +9,7 @@ import { import { DomSanitizer } from "@angular/platform-browser"; import { NavigationEnd, Router, RouterOutlet } from "@angular/router"; import { IndividualConfig, ToastrService } from "ngx-toastr"; -import { filter, concatMap, Subject, takeUntil } from "rxjs"; -import Swal from "sweetalert2"; +import { filter, concatMap, Subject, takeUntil, firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; @@ -23,6 +22,7 @@ import { BrowserApi } from "../platform/browser/browser-api"; import { BrowserStateService } from "../platform/services/abstractions/browser-state.service"; import { routerTransition } from "./app-routing.animations"; +import { DesktopSyncVerificationDialogComponent } from "./components/desktop-sync-verification-dialog.component"; @Component({ selector: "app-root", @@ -113,10 +113,10 @@ export class AppComponent implements OnInit, OnDestroy { }); } } else if (msg.command === "showDialog") { - await this.showDialog(msg); + await this.ngZone.run(() => this.showDialog(msg)); } else if (msg.command === "showNativeMessagingFinterprintDialog") { // TODO: Should be refactored to live in another service. - await this.showNativeMessagingFingerprintDialog(msg); + await this.ngZone.run(() => this.showNativeMessagingFingerprintDialog(msg)); } else if (msg.command === "showToast") { this.ngZone.run(() => { this.showToast(msg); @@ -242,19 +242,11 @@ export class AppComponent implements OnInit, OnDestroy { } private async showNativeMessagingFingerprintDialog(msg: any) { - await Swal.fire({ - heightAuto: false, - buttonsStyling: false, - icon: "warning", - iconHtml: '', - html: `${this.i18nService.t("desktopIntegrationVerificationText")}

${ - msg.fingerprint - }`, - titleText: this.i18nService.t("desktopSyncVerificationTitle"), - showConfirmButton: true, - confirmButtonText: this.i18nService.t("ok"), - timer: 300000, + const dialogRef = DesktopSyncVerificationDialogComponent.open(this.dialogService, { + fingerprint: msg.fingerprint, }); + + return firstValueFrom(dialogRef.closed); } private async clearComponentStates() { diff --git a/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.html b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.html new file mode 100644 index 0000000000..a2a2cd9780 --- /dev/null +++ b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.html @@ -0,0 +1,18 @@ + + + {{ "desktopSyncVerificationTitle" | i18n }} + + +

+ {{ "desktopIntegrationVerificationText" | i18n }} +

+

+ {{ params.fingerprint.join("-") }} +

+
+ + + +
diff --git a/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts new file mode 100644 index 0000000000..c860ef1e34 --- /dev/null +++ b/apps/browser/src/popup/components/desktop-sync-verification-dialog.component.ts @@ -0,0 +1,24 @@ +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components"; + +export type DesktopSyncVerificationDialogParams = { + fingerprint: string[]; +}; + +@Component({ + templateUrl: "desktop-sync-verification-dialog.component.html", + standalone: true, + imports: [JslibModule, ButtonModule, DialogModule], +}) +export class DesktopSyncVerificationDialogComponent { + constructor(@Inject(DIALOG_DATA) protected params: DesktopSyncVerificationDialogParams) {} + + static open(dialogService: DialogService, data: DesktopSyncVerificationDialogParams) { + return dialogService.open(DesktopSyncVerificationDialogComponent, { + data, + }); + } +} diff --git a/apps/browser/src/popup/settings/await-desktop-dialog.component.html b/apps/browser/src/popup/settings/await-desktop-dialog.component.html new file mode 100644 index 0000000000..688071a15d --- /dev/null +++ b/apps/browser/src/popup/settings/await-desktop-dialog.component.html @@ -0,0 +1,11 @@ + + {{ "awaitDesktop" | i18n }} + + {{ "awaitDesktopDesc" | i18n }} + + + + + diff --git a/apps/browser/src/popup/settings/await-desktop-dialog.component.ts b/apps/browser/src/popup/settings/await-desktop-dialog.component.ts new file mode 100644 index 0000000000..9ed6efe036 --- /dev/null +++ b/apps/browser/src/popup/settings/await-desktop-dialog.component.ts @@ -0,0 +1,17 @@ +import { Component } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components"; + +@Component({ + templateUrl: "await-desktop-dialog.component.html", + standalone: true, + imports: [JslibModule, ButtonModule, DialogModule], +}) +export class AwaitDesktopDialogComponent { + static open(dialogService: DialogService) { + return dialogService.open(AwaitDesktopDialogComponent, { + disableClose: true, + }); + } +} diff --git a/apps/browser/src/popup/settings/settings.component.ts b/apps/browser/src/popup/settings/settings.component.ts index 30a1f03eac..efeb6aba6d 100644 --- a/apps/browser/src/popup/settings/settings.component.ts +++ b/apps/browser/src/popup/settings/settings.component.ts @@ -15,9 +15,9 @@ import { switchMap, takeUntil, } from "rxjs"; -import Swal from "sweetalert2"; import { ModalService } from "@bitwarden/angular/services/modal.service"; +import { FingerprintDialogComponent } from "@bitwarden/auth"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -39,6 +39,7 @@ import { SetPinComponent } from "../components/set-pin.component"; import { PopupUtilsService } from "../services/popup-utils.service"; import { AboutComponent } from "./about.component"; +import { AwaitDesktopDialogComponent } from "./await-desktop-dialog.component"; const RateUrls = { [DeviceType.ChromeExtension]: @@ -361,25 +362,15 @@ export class SettingsComponent implements OnInit { return; } - const submitted = Swal.fire({ - heightAuto: false, - buttonsStyling: false, - titleText: this.i18nService.t("awaitDesktop"), - text: this.i18nService.t("awaitDesktopDesc"), - icon: "info", - iconHtml: '', - showCancelButton: true, - cancelButtonText: this.i18nService.t("cancel"), - showConfirmButton: false, - allowOutsideClick: false, - }); + const awaitDesktopDialogRef = AwaitDesktopDialogComponent.open(this.dialogService); + const awaitDesktopDialogClosed = firstValueFrom(awaitDesktopDialogRef.closed); await this.stateService.setBiometricAwaitingAcceptance(true); await this.cryptoService.refreshAdditionalKeys(); await Promise.race([ - submitted.then(async (result) => { - if (result.dismiss === Swal.DismissReason.cancel) { + awaitDesktopDialogClosed.then(async (result) => { + if (result) { this.form.controls.biometric.setValue(false); await this.stateService.setBiometricAwaitingAcceptance(null); } @@ -388,8 +379,6 @@ export class SettingsComponent implements OnInit { .authenticateBiometric() .then((result) => { this.form.controls.biometric.setValue(result); - - Swal.close(); if (!result) { this.platformUtilsService.showToast( "error", @@ -411,6 +400,9 @@ export class SettingsComponent implements OnInit { cancelButtonText: null, type: "danger", }); + }) + .finally(() => { + awaitDesktopDialogRef.close(false); }), ]); } else { @@ -497,27 +489,12 @@ export class SettingsComponent implements OnInit { const fingerprint = await this.cryptoService.getFingerprint( await this.stateService.getUserId() ); - const p = document.createElement("p"); - p.innerText = this.i18nService.t("yourAccountsFingerprint") + ":"; - const p2 = document.createElement("p"); - p2.innerText = fingerprint.join("-"); - const div = document.createElement("div"); - div.appendChild(p); - div.appendChild(p2); - const result = await Swal.fire({ - heightAuto: false, - buttonsStyling: false, - html: div, - showCancelButton: true, - cancelButtonText: this.i18nService.t("close"), - showConfirmButton: true, - confirmButtonText: this.i18nService.t("learnMore"), + const dialogRef = FingerprintDialogComponent.open(this.dialogService, { + fingerprint, }); - if (result.value) { - this.platformUtilsService.launchUri("https://bitwarden.com/help/fingerprint-phrase/"); - } + return firstValueFrom(dialogRef.closed); } rate() { diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index 39e2d2f8b1..34262c3a30 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -16,6 +16,7 @@ import { firstValueFrom, Subject, takeUntil } from "rxjs"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; import { ModalService } from "@bitwarden/angular/services/modal.service"; +import { FingerprintDialogComponent } from "@bitwarden/auth"; import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service"; import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; @@ -244,18 +245,8 @@ export class AppComponent implements OnInit, OnDestroy { const fingerprint = await this.cryptoService.getFingerprint( await this.stateService.getUserId() ); - const result = await this.dialogService.openSimpleDialog({ - title: { key: "fingerprintPhrase" }, - content: - this.i18nService.t("yourAccountsFingerprint") + ":\n" + fingerprint.join("-"), - acceptButtonText: { key: "learnMore" }, - cancelButtonText: { key: "close" }, - type: "info", - }); - - if (result) { - this.platformUtilsService.launchUri("https://bitwarden.com/help/fingerprint-phrase/"); - } + const dialogRef = FingerprintDialogComponent.open(this.dialogService, { fingerprint }); + await firstValueFrom(dialogRef.closed); break; } case "deleteAccount": diff --git a/apps/desktop/src/app/components/browser-sync-verification-dialog.component.html b/apps/desktop/src/app/components/browser-sync-verification-dialog.component.html new file mode 100644 index 0000000000..63bffe9c4e --- /dev/null +++ b/apps/desktop/src/app/components/browser-sync-verification-dialog.component.html @@ -0,0 +1,19 @@ + + + {{ "verifyBrowserTitle" | i18n }} + + +

{{ "verifyBrowserDesc" | i18n }}

+

+ {{ params.fingerprint.join("-") }} +

+
+ + + + +
diff --git a/apps/desktop/src/app/components/browser-sync-verification-dialog.component.ts b/apps/desktop/src/app/components/browser-sync-verification-dialog.component.ts new file mode 100644 index 0000000000..aefa5672a9 --- /dev/null +++ b/apps/desktop/src/app/components/browser-sync-verification-dialog.component.ts @@ -0,0 +1,25 @@ +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components"; + +export type BrowserSyncVerificationDialogParams = { + fingerprint: string[]; +}; + +@Component({ + templateUrl: "browser-sync-verification-dialog.component.html", + standalone: true, + imports: [JslibModule, ButtonModule, DialogModule], +}) +export class BrowserSyncVerificationDialogComponent { + constructor(@Inject(DIALOG_DATA) protected params: BrowserSyncVerificationDialogParams) {} + + static open(dialogService: DialogService, data: BrowserSyncVerificationDialogParams) { + return dialogService.open(BrowserSyncVerificationDialogComponent, { + data, + disableClose: true, + }); + } +} diff --git a/apps/desktop/src/app/components/verify-native-messaging-dialog.component.html b/apps/desktop/src/app/components/verify-native-messaging-dialog.component.html new file mode 100644 index 0000000000..0334857962 --- /dev/null +++ b/apps/desktop/src/app/components/verify-native-messaging-dialog.component.html @@ -0,0 +1,18 @@ + + + {{ "verifyNativeMessagingConnectionTitle" | i18n : data.applicationName }}: + + + {{ "verifyNativeMessagingConnectionDesc" | i18n }} +
+ {{ "verifyNativeMessagingConnectionWarning" | i18n }} +
+ + + + +
diff --git a/apps/desktop/src/app/components/verify-native-messaging-dialog.component.ts b/apps/desktop/src/app/components/verify-native-messaging-dialog.component.ts new file mode 100644 index 0000000000..507d566336 --- /dev/null +++ b/apps/desktop/src/app/components/verify-native-messaging-dialog.component.ts @@ -0,0 +1,24 @@ +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components"; + +export type VerifyNativeMessagingDialogData = { + applicationName: string; +}; + +@Component({ + templateUrl: "verify-native-messaging-dialog.component.html", + standalone: true, + imports: [JslibModule, ButtonModule, DialogModule], +}) +export class VerifyNativeMessagingDialogComponent { + constructor(@Inject(DIALOG_DATA) protected data: VerifyNativeMessagingDialogData) {} + + static open(dialogService: DialogService, data: VerifyNativeMessagingDialogData) { + return dialogService.open(VerifyNativeMessagingDialogComponent, { + data, + }); + } +} diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 42208077c3..87fb1eecfc 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -169,6 +169,7 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK"); MessagingServiceAbstraction, I18nServiceAbstraction, EncryptedMessageHandlerService, + DialogService, ], }, { diff --git a/apps/desktop/src/services/native-message-handler.service.ts b/apps/desktop/src/services/native-message-handler.service.ts index 9f5f1d460d..6779195c3f 100644 --- a/apps/desktop/src/services/native-message-handler.service.ts +++ b/apps/desktop/src/services/native-message-handler.service.ts @@ -1,6 +1,6 @@ import { Injectable } from "@angular/core"; import { ipcRenderer } from "electron"; -import Swal from "sweetalert2"; +import { firstValueFrom } from "rxjs"; import { NativeMessagingVersion } from "@bitwarden/common/enums"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; @@ -11,7 +11,9 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { StateService } from "@bitwarden/common/platform/services/state.service"; +import { DialogService } from "@bitwarden/components"; +import { VerifyNativeMessagingDialogComponent } from "../app/components/verify-native-messaging-dialog.component"; import { DecryptedCommandData } from "../models/native-messaging/decrypted-command-data"; import { EncryptedMessage } from "../models/native-messaging/encrypted-message"; import { EncryptedMessageResponse } from "../models/native-messaging/encrypted-message-response"; @@ -33,7 +35,8 @@ export class NativeMessageHandlerService { private cryptoFunctionService: CryptoFunctionService, private messagingService: MessagingService, private i18nService: I18nService, - private encryptedMessageHandlerService: EncryptedMessageHandlerService + private encryptedMessageHandlerService: EncryptedMessageHandlerService, + private dialogService: DialogService ) {} async handleMessage(message: Message) { @@ -87,21 +90,12 @@ export class NativeMessageHandlerService { // Ask for confirmation from user this.messagingService.send("setFocus"); - const submitted = await Swal.fire({ - heightAuto: false, - titleText: this.i18nService.t("verifyNativeMessagingConnectionTitle", applicationName), - html: `${this.i18nService.t("verifyNativeMessagingConnectionDesc")}
${this.i18nService.t( - "verifyNativeMessagingConnectionWarning" - )}`, - showCancelButton: true, - cancelButtonText: this.i18nService.t("no"), - showConfirmButton: true, - confirmButtonText: this.i18nService.t("yes"), - allowOutsideClick: false, - focusCancel: true, - }); - if (submitted.value !== true) { + const nativeMessagingVerified = await firstValueFrom( + VerifyNativeMessagingDialogComponent.open(this.dialogService, { applicationName }).closed + ); + + if (nativeMessagingVerified !== true) { this.sendResponse({ messageId: messageId, version: NativeMessagingVersion.Latest, diff --git a/apps/desktop/src/services/native-messaging.service.ts b/apps/desktop/src/services/native-messaging.service.ts index 3928778f31..c18a67e6b4 100644 --- a/apps/desktop/src/services/native-messaging.service.ts +++ b/apps/desktop/src/services/native-messaging.service.ts @@ -1,7 +1,6 @@ -import { Injectable } from "@angular/core"; +import { Injectable, NgZone } from "@angular/core"; import { ipcRenderer } from "electron"; import { firstValueFrom } from "rxjs"; -import Swal from "sweetalert2"; import { KeySuffixOptions } from "@bitwarden/common/enums"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; @@ -14,7 +13,9 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { DialogService } from "@bitwarden/components"; +import { BrowserSyncVerificationDialogComponent } from "../app/components/browser-sync-verification-dialog.component"; import { LegacyMessage } from "../models/native-messaging/legacy-message"; import { LegacyMessageWrapper } from "../models/native-messaging/legacy-message-wrapper"; import { Message } from "../models/native-messaging/message"; @@ -36,7 +37,9 @@ export class NativeMessagingService { private i18nService: I18nService, private messagingService: MessagingService, private stateService: StateService, - private nativeMessageHandler: NativeMessageHandlerService + private nativeMessageHandler: NativeMessageHandlerService, + private dialogService: DialogService, + private ngZone: NgZone ) {} init() { @@ -69,27 +72,20 @@ export class NativeMessagingService { if (await this.stateService.getEnableBrowserIntegrationFingerprint()) { ipcRenderer.send("nativeMessagingReply", { command: "verifyFingerprint", appId: appId }); - const fingerprint = ( - await this.cryptoService.getFingerprint( - await this.stateService.getUserId(), - remotePublicKey - ) - ).join(" "); + const fingerprint = await this.cryptoService.getFingerprint( + await this.stateService.getUserId(), + remotePublicKey + ); this.messagingService.send("setFocus"); - // Await confirmation that fingerprint is correct - const submitted = await Swal.fire({ - titleText: this.i18nService.t("verifyBrowserTitle"), - html: `${this.i18nService.t("verifyBrowserDesc")}

${fingerprint}`, - showCancelButton: true, - cancelButtonText: this.i18nService.t("cancel"), - showConfirmButton: true, - confirmButtonText: this.i18nService.t("approve"), - allowOutsideClick: false, - }); + const dialogRef = this.ngZone.run(() => + BrowserSyncVerificationDialogComponent.open(this.dialogService, { fingerprint }) + ); - if (submitted.value !== true) { + const browserSyncVerified = await firstValueFrom(dialogRef.closed); + + if (browserSyncVerified !== true) { return; } } @@ -127,13 +123,15 @@ export class NativeMessagingService { if (!(await this.stateService.getBiometricUnlock({ userId: message.userId }))) { this.send({ command: "biometricUnlock", response: "not enabled" }, appId); - return await Swal.fire({ - title: this.i18nService.t("biometricsNotEnabledTitle"), - text: this.i18nService.t("biometricsNotEnabledDesc"), - showCancelButton: true, - cancelButtonText: this.i18nService.t("cancel"), - showConfirmButton: false, - }); + return this.ngZone.run(() => + this.dialogService.openSimpleDialog({ + type: "warning", + title: { key: "biometricsNotEnabledTitle" }, + content: { key: "biometricsNotEnabledDesc" }, + cancelButtonText: null, + acceptButtonText: { key: "cancel" }, + }) + ); } const userKey = await this.cryptoService.getUserKeyFromStorage( diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html index 4978842fb4..b6175d8029 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.html @@ -69,13 +69,7 @@ - + + diff --git a/libs/auth/src/components/fingerprint-dialog.component.ts b/libs/auth/src/components/fingerprint-dialog.component.ts new file mode 100644 index 0000000000..2a7b3e1099 --- /dev/null +++ b/libs/auth/src/components/fingerprint-dialog.component.ts @@ -0,0 +1,22 @@ +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, DialogService } from "@bitwarden/components"; + +export type FingerprintDialogData = { + fingerprint: string[]; +}; + +@Component({ + templateUrl: "fingerprint-dialog.component.html", + standalone: true, + imports: [JslibModule, ButtonModule, DialogModule], +}) +export class FingerprintDialogComponent { + constructor(@Inject(DIALOG_DATA) protected data: FingerprintDialogData) {} + + static open(dialogService: DialogService, data: FingerprintDialogData) { + return dialogService.open(FingerprintDialogComponent, { data }); + } +} diff --git a/libs/auth/src/index.ts b/libs/auth/src/index.ts index e69de29bb2..0b4f07fc29 100644 --- a/libs/auth/src/index.ts +++ b/libs/auth/src/index.ts @@ -0,0 +1 @@ +export * from "./components/fingerprint-dialog.component"; diff --git a/libs/components/src/dialog/directives/dialog-close.directive.ts b/libs/components/src/dialog/directives/dialog-close.directive.ts index a45991bb5e..543c37715d 100644 --- a/libs/components/src/dialog/directives/dialog-close.directive.ts +++ b/libs/components/src/dialog/directives/dialog-close.directive.ts @@ -5,9 +5,9 @@ import { Directive, HostListener, Input, Optional } from "@angular/core"; selector: "[bitDialogClose]", }) export class DialogCloseDirective { - @Input("bit-dialog-close") dialogResult: any; + @Input("bitDialogClose") dialogResult: any; - constructor(@Optional() public dialogRef: DialogRef) {} + constructor(@Optional() public dialogRef: DialogRef) {} @HostListener("click") close(): void { this.dialogRef.close(this.dialogResult);