From 9041a4cd4cd44a3f1741f45c357df4e4efca6002 Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:33:58 -0700 Subject: [PATCH] [PM-6564] migrate auth toasts to CL toastService (#10665) * migrate auth toasts to CL toastService * fix component args * fix component args * fix specs * fix toastService args --- .../src/auth/popup/environment.component.ts | 4 +- apps/browser/src/auth/popup/hint.component.ts | 12 ++- apps/browser/src/auth/popup/home.component.ts | 12 +-- apps/browser/src/auth/popup/lock.component.ts | 4 +- .../popup/login-via-auth-request.component.ts | 3 + .../browser/src/auth/popup/login.component.ts | 3 + .../src/auth/popup/register.component.ts | 4 +- .../settings/account-security.component.ts | 33 ++++---- apps/browser/src/auth/popup/sso.component.ts | 3 + .../auth/popup/two-factor-auth.component.ts | 3 + .../auth/accessibility-cookie.component.ts | 32 +++---- .../src/auth/delete-account.component.ts | 12 +-- .../desktop/src/auth/environment.component.ts | 4 +- apps/desktop/src/auth/hint.component.ts | 12 ++- apps/desktop/src/auth/lock.component.spec.ts | 8 +- apps/desktop/src/auth/lock.component.ts | 4 +- .../auth/login/login-approval.component.ts | 42 +++++----- .../login/login-via-auth-request.component.ts | 3 + .../desktop/src/auth/login/login.component.ts | 13 +-- apps/desktop/src/auth/register.component.ts | 4 +- .../src/auth/set-password.component.ts | 4 +- apps/desktop/src/auth/sso.component.ts | 3 + apps/web/src/app/auth/hint.component.ts | 12 ++- .../web/src/app/auth/login/login.component.ts | 3 + .../migrate-legacy-encryption.component.ts | 14 ++-- .../src/app/auth/recover-delete.component.ts | 12 +-- .../app/auth/recover-two-factor.component.ts | 12 +-- .../register-form/register-form.component.ts | 14 ++-- .../account/change-avatar-dialog.component.ts | 15 +++- .../account/change-email.component.ts | 12 +-- .../account/deauthorize-sessions.component.ts | 12 +-- .../delete-account-dialog.component.ts | 13 +-- .../settings/account/profile.component.ts | 9 +- .../settings/change-password.component.ts | 50 ++++++----- .../emergency-access-add-edit.component.ts | 16 ++-- .../emergency-access.component.ts | 83 ++++++++++--------- .../emergency-access-takeover.component.ts | 14 ++-- .../change-kdf-confirmation.component.ts | 12 +-- .../two-factor-authenticator.component.ts | 10 ++- .../settings/two-factor-base.component.ts | 15 +++- .../auth/settings/two-factor-duo.component.ts | 4 +- .../settings/two-factor-email.component.ts | 4 +- .../settings/two-factor-webauthn.component.ts | 4 +- .../settings/two-factor-yubikey.component.ts | 3 +- .../auth/settings/verify-email.component.ts | 25 ++++-- .../create-credential-dialog.component.ts | 33 ++++---- .../delete-credential-dialog.component.ts | 19 +++-- .../user-verification-prompt.component.ts | 13 ++- apps/web/src/app/auth/sso.component.ts | 3 + .../src/app/auth/two-factor-auth.component.ts | 10 ++- .../app/auth/verify-email-token.component.ts | 14 +++- .../auth/verify-recover-delete.component.ts | 12 +-- .../bit-web/src/app/auth/sso/sso.component.ts | 10 ++- ...base-login-decryption-options.component.ts | 12 +-- .../components/captcha-protected.component.ts | 14 +++- .../components/change-password.component.ts | 43 +++++----- .../auth/components/environment.component.ts | 8 +- .../src/auth/components/hint.component.ts | 28 ++++--- .../src/auth/components/lock.component.ts | 63 +++++++------- .../login-via-auth-request.component.ts | 28 +++++-- .../src/auth/components/login.component.ts | 20 +++-- .../src/auth/components/register.component.ts | 41 +++++---- .../components/remove-password.component.ts | 31 +++++-- .../auth/components/set-password.component.ts | 16 +++- .../src/auth/components/sso.component.spec.ts | 22 +++-- .../src/auth/components/sso.component.ts | 22 ++--- .../two-factor-auth-email.component.ts | 22 ++--- .../two-factor-auth-webauthn.component.ts | 12 +-- .../two-factor-auth.component.spec.ts | 5 +- .../two-factor-auth.component.ts | 24 +++--- .../auth/components/two-factor.component.ts | 48 ++++++----- .../components/update-password.component.ts | 30 ++++--- .../update-temp-password.component.ts | 14 ++-- .../user-verification-prompt.component.ts | 8 +- .../user-verification-dialog.component.ts | 24 ++++-- 75 files changed, 782 insertions(+), 457 deletions(-) diff --git a/apps/browser/src/auth/popup/environment.component.ts b/apps/browser/src/auth/popup/environment.component.ts index ed348e563b..b84f03b5fd 100644 --- a/apps/browser/src/auth/popup/environment.component.ts +++ b/apps/browser/src/auth/popup/environment.component.ts @@ -5,6 +5,7 @@ import { EnvironmentComponent as BaseEnvironmentComponent } from "@bitwarden/ang import { ModalService } from "@bitwarden/angular/services/modal.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; import { BrowserEnvironmentService } from "../../platform/services/browser-environment.service"; @@ -21,8 +22,9 @@ export class EnvironmentComponent extends BaseEnvironmentComponent implements On i18nService: I18nService, private router: Router, modalService: ModalService, + toastService: ToastService, ) { - super(platformUtilsService, environmentService, i18nService, modalService); + super(platformUtilsService, environmentService, i18nService, modalService, toastService); this.showCustom = true; } diff --git a/apps/browser/src/auth/popup/hint.component.ts b/apps/browser/src/auth/popup/hint.component.ts index 214a43efb7..bc1f68f4c4 100644 --- a/apps/browser/src/auth/popup/hint.component.ts +++ b/apps/browser/src/auth/popup/hint.component.ts @@ -7,6 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-hint", @@ -21,8 +22,17 @@ export class HintComponent extends BaseHintComponent { logService: LogService, private route: ActivatedRoute, loginEmailService: LoginEmailServiceAbstraction, + toastService: ToastService, ) { - super(router, i18nService, apiService, platformUtilsService, logService, loginEmailService); + super( + router, + i18nService, + apiService, + platformUtilsService, + logService, + loginEmailService, + toastService, + ); super.onSuccessfulSubmit = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. diff --git a/apps/browser/src/auth/popup/home.component.ts b/apps/browser/src/auth/popup/home.component.ts index 43f8f3dcf4..505931ad0f 100644 --- a/apps/browser/src/auth/popup/home.component.ts +++ b/apps/browser/src/auth/popup/home.component.ts @@ -7,6 +7,7 @@ import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components import { LoginEmailServiceAbstraction, RegisterRouteService } from "@bitwarden/auth/common"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; import { AccountSwitcherService } from "./account-switching/services/account-switcher.service"; @@ -36,6 +37,7 @@ export class HomeComponent implements OnInit, OnDestroy { private loginEmailService: LoginEmailServiceAbstraction, private accountSwitcherService: AccountSwitcherService, private registerRouteService: RegisterRouteService, + private toastService: ToastService, ) {} async ngOnInit(): Promise { @@ -76,11 +78,11 @@ export class HomeComponent implements OnInit, OnDestroy { this.formGroup.markAllAsTouched(); if (this.formGroup.invalid) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccured"), - this.i18nService.t("invalidEmail"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccured"), + message: this.i18nService.t("invalidEmail"), + }); return; } diff --git a/apps/browser/src/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index a6da98fe99..f5413e4bea 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -27,7 +27,7 @@ import { BiometricStateService } from "@bitwarden/common/platform/biometrics/bio import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { BiometricErrors, BiometricErrorTypes } from "../../models/biometricErrors"; import { BrowserRouterService } from "../../platform/popup/services/browser-router.service"; @@ -72,6 +72,7 @@ export class LockComponent extends BaseLockComponent implements OnInit { accountService: AccountService, kdfConfigService: KdfConfigService, syncService: SyncService, + toastService: ToastService, ) { super( masterPasswordService, @@ -100,6 +101,7 @@ export class LockComponent extends BaseLockComponent implements OnInit { authService, kdfConfigService, syncService, + toastService, ); this.successRoute = "/tabs/current"; this.isInitialLockScreen = (window as any).previousPopupUrl == null; diff --git a/apps/browser/src/auth/popup/login-via-auth-request.component.ts b/apps/browser/src/auth/popup/login-via-auth-request.component.ts index f83062e6c9..53f29badee 100644 --- a/apps/browser/src/auth/popup/login-via-auth-request.component.ts +++ b/apps/browser/src/auth/popup/login-via-auth-request.component.ts @@ -22,6 +22,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ @@ -50,6 +51,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { loginStrategyService: LoginStrategyServiceAbstraction, accountService: AccountService, private location: Location, + toastService: ToastService, ) { super( router, @@ -70,6 +72,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { deviceTrustService, authRequestService, loginStrategyService, + toastService, ); super.onSuccessfulLogin = async () => { await syncService.fullSync(true); diff --git a/apps/browser/src/auth/popup/login.component.ts b/apps/browser/src/auth/popup/login.component.ts index 79a02ede85..6e73199969 100644 --- a/apps/browser/src/auth/popup/login.component.ts +++ b/apps/browser/src/auth/popup/login.component.ts @@ -22,6 +22,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { flagEnabled } from "../../platform/flags"; @@ -53,6 +54,7 @@ export class LoginComponent extends BaseLoginComponent { ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, registerRouteService: RegisterRouteService, + toastService: ToastService, ) { super( devicesApiService, @@ -74,6 +76,7 @@ export class LoginComponent extends BaseLoginComponent { ssoLoginService, webAuthnLoginService, registerRouteService, + toastService, ); super.onSuccessfulLogin = async () => { await syncService.fullSync(true); diff --git a/apps/browser/src/auth/popup/register.component.ts b/apps/browser/src/auth/popup/register.component.ts index 61e007ac52..dab1e62f85 100644 --- a/apps/browser/src/auth/popup/register.component.ts +++ b/apps/browser/src/auth/popup/register.component.ts @@ -13,7 +13,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ @@ -39,6 +39,7 @@ export class RegisterComponent extends BaseRegisterComponent { logService: LogService, auditService: AuditService, dialogService: DialogService, + toastService: ToastService, ) { super( formValidationErrorService, @@ -55,6 +56,7 @@ export class RegisterComponent extends BaseRegisterComponent { logService, auditService, dialogService, + toastService, ); } } diff --git a/apps/browser/src/auth/popup/settings/account-security.component.ts b/apps/browser/src/auth/popup/settings/account-security.component.ts index 7bced79a0a..25401f06f3 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.ts @@ -39,7 +39,7 @@ import { VaultTimeoutOption, VaultTimeoutStringType, } from "@bitwarden/common/types/vault-timeout.type"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; import { BrowserApi } from "../../../platform/browser/browser-api"; @@ -95,6 +95,7 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { private dialogService: DialogService, private changeDetectorRef: ChangeDetectorRef, private biometricStateService: BiometricStateService, + private toastService: ToastService, private biometricsService: BiometricsService, ) { this.accountSwitcherEnabled = enableAccountSwitching(); @@ -274,11 +275,11 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { // The minTimeoutError does not apply to browser because it supports Immediately // So only check for the policyError if (this.form.controls.vaultTimeout.hasError("policyError")) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("vaultTimeoutTooLarge"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("vaultTimeoutTooLarge"), + }); return; } @@ -315,11 +316,11 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { } if (this.form.controls.vaultTimeout.hasError("policyError")) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("vaultTimeoutTooLarge"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("vaultTimeoutTooLarge"), + }); return; } @@ -417,11 +418,11 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { this.form.controls.biometric.setValue(result); if (!result) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorEnableBiometricTitle"), - this.i18nService.t("errorEnableBiometricDesc"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorEnableBiometricTitle"), + message: this.i18nService.t("errorEnableBiometricDesc"), + }); } } catch (e) { // prevent duplicate dialog diff --git a/apps/browser/src/auth/popup/sso.component.ts b/apps/browser/src/auth/popup/sso.component.ts index 33284717ab..42222c42b9 100644 --- a/apps/browser/src/auth/popup/sso.component.ts +++ b/apps/browser/src/auth/popup/sso.component.ts @@ -22,6 +22,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { BrowserApi } from "../../platform/browser/browser-api"; @@ -51,6 +52,7 @@ export class SsoComponent extends BaseSsoComponent { accountService: AccountService, private authService: AuthService, @Inject(WINDOW) private win: Window, + toastService: ToastService, ) { super( ssoLoginService, @@ -69,6 +71,7 @@ export class SsoComponent extends BaseSsoComponent { configService, masterPasswordService, accountService, + toastService, ); environmentService.environment$.pipe(takeUntilDestroyed()).subscribe((env) => { diff --git a/apps/browser/src/auth/popup/two-factor-auth.component.ts b/apps/browser/src/auth/popup/two-factor-auth.component.ts index ea0d4a48e5..27c9532110 100644 --- a/apps/browser/src/auth/popup/two-factor-auth.component.ts +++ b/apps/browser/src/auth/popup/two-factor-auth.component.ts @@ -32,6 +32,7 @@ import { LinkModule, TypographyModule, DialogService, + ToastService, } from "@bitwarden/components"; import { @@ -95,6 +96,7 @@ export class TwoFactorAuthComponent @Inject(WINDOW) protected win: Window, private syncService: SyncService, private messagingService: MessagingService, + toastService: ToastService, ) { super( loginStrategyService, @@ -114,6 +116,7 @@ export class TwoFactorAuthComponent accountService, formBuilder, win, + toastService, ); super.onSuccessfulLoginTdeNavigate = async () => { this.win.close(); diff --git a/apps/desktop/src/auth/accessibility-cookie.component.ts b/apps/desktop/src/auth/accessibility-cookie.component.ts index fc72b1a9d7..697bbcc88e 100644 --- a/apps/desktop/src/auth/accessibility-cookie.component.ts +++ b/apps/desktop/src/auth/accessibility-cookie.component.ts @@ -6,6 +6,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-accessibility-cookie", @@ -25,6 +26,7 @@ export class AccessibilityCookieComponent { protected environmentService: EnvironmentService, protected i18nService: I18nService, protected ngZone: NgZone, + private toastService: ToastService, ) {} registerhCaptcha() { @@ -42,28 +44,28 @@ export class AccessibilityCookieComponent { } onCookieSavedSuccess() { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("accessibilityCookieSaved"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("accessibilityCookieSaved"), + }); } onCookieSavedFailure() { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("noAccessibilityCookieSaved"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("noAccessibilityCookieSaved"), + }); } async submit() { if (Utils.getHostname(this.accessibilityForm.value.link) !== "accounts.hcaptcha.com") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("invalidUrl"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidUrl"), + }); return; } this.listenForCookie = true; diff --git a/apps/desktop/src/auth/delete-account.component.ts b/apps/desktop/src/auth/delete-account.component.ts index a473310d38..0cb2bdd79e 100644 --- a/apps/desktop/src/auth/delete-account.component.ts +++ b/apps/desktop/src/auth/delete-account.component.ts @@ -13,6 +13,7 @@ import { CalloutModule, DialogModule, DialogService, + ToastService, } from "@bitwarden/components"; import { UserVerificationComponent } from "../app/components/user-verification.component"; @@ -41,6 +42,7 @@ export class DeleteAccountComponent { private platformUtilsService: PlatformUtilsService, private formBuilder: FormBuilder, private accountApiService: AccountApiService, + private toastService: ToastService, ) {} static open(dialogService: DialogService): DialogRef { @@ -54,10 +56,10 @@ export class DeleteAccountComponent { submit = async () => { const verification = this.deleteForm.get("verification").value; await this.accountApiService.deleteAccount(verification); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("accountDeleted"), - this.i18nService.t("accountDeletedDesc"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("accountDeleted"), + message: this.i18nService.t("accountDeletedDesc"), + }); }; } diff --git a/apps/desktop/src/auth/environment.component.ts b/apps/desktop/src/auth/environment.component.ts index a4b137a9e5..d24e0f86ab 100644 --- a/apps/desktop/src/auth/environment.component.ts +++ b/apps/desktop/src/auth/environment.component.ts @@ -5,6 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service"; 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 { ToastService } from "@bitwarden/components"; @Component({ selector: "app-environment", @@ -16,7 +17,8 @@ export class EnvironmentComponent extends BaseEnvironmentComponent { environmentService: EnvironmentService, i18nService: I18nService, modalService: ModalService, + toastService: ToastService, ) { - super(platformUtilsService, environmentService, i18nService, modalService); + super(platformUtilsService, environmentService, i18nService, modalService, toastService); } } diff --git a/apps/desktop/src/auth/hint.component.ts b/apps/desktop/src/auth/hint.component.ts index cee1f18981..3445702925 100644 --- a/apps/desktop/src/auth/hint.component.ts +++ b/apps/desktop/src/auth/hint.component.ts @@ -7,6 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-hint", @@ -20,7 +21,16 @@ export class HintComponent extends BaseHintComponent { apiService: ApiService, logService: LogService, loginEmailService: LoginEmailServiceAbstraction, + toastService: ToastService, ) { - super(router, i18nService, apiService, platformUtilsService, logService, loginEmailService); + super( + router, + i18nService, + apiService, + platformUtilsService, + logService, + loginEmailService, + toastService, + ); } } diff --git a/apps/desktop/src/auth/lock.component.spec.ts b/apps/desktop/src/auth/lock.component.spec.ts index c5b5b7acf0..d81f2a486f 100644 --- a/apps/desktop/src/auth/lock.component.spec.ts +++ b/apps/desktop/src/auth/lock.component.spec.ts @@ -34,7 +34,7 @@ import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/sp import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { UserId } from "@bitwarden/common/types/guid"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { BiometricsService } from "src/platform/main/biometric"; @@ -62,6 +62,7 @@ describe("LockComponent", () => { let platformUtilsServiceMock: MockProxy; let activatedRouteMock: MockProxy; let mockMasterPasswordService: FakeMasterPasswordService; + let mockToastService: MockProxy; const mockUserId = Utils.newGuid() as UserId; const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); @@ -72,6 +73,7 @@ describe("LockComponent", () => { messagingServiceMock = mock(); broadcasterServiceMock = mock(); platformUtilsServiceMock = mock(); + mockToastService = mock(); activatedRouteMock = mock(); activatedRouteMock.queryParams = mock(); @@ -187,6 +189,10 @@ describe("LockComponent", () => { provide: SyncService, useValue: mock(), }, + { + provide: ToastService, + useValue: mockToastService, + }, ], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); diff --git a/apps/desktop/src/auth/lock.component.ts b/apps/desktop/src/auth/lock.component.ts index 55cc79e0a6..350512b0f3 100644 --- a/apps/desktop/src/auth/lock.component.ts +++ b/apps/desktop/src/auth/lock.component.ts @@ -28,7 +28,7 @@ import { BiometricStateService } from "@bitwarden/common/platform/biometrics/bio import { BiometricsService } from "@bitwarden/common/platform/biometrics/biometric.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; const BroadcasterSubscriptionId = "LockComponent"; @@ -72,6 +72,7 @@ export class LockComponent extends BaseLockComponent implements OnInit, OnDestro authService: AuthService, kdfConfigService: KdfConfigService, syncService: SyncService, + toastService: ToastService, ) { super( masterPasswordService, @@ -100,6 +101,7 @@ export class LockComponent extends BaseLockComponent implements OnInit, OnDestro authService, kdfConfigService, syncService, + toastService, ); } diff --git a/apps/desktop/src/auth/login/login-approval.component.ts b/apps/desktop/src/auth/login/login-approval.component.ts index 296efb50e4..39876f2945 100644 --- a/apps/desktop/src/auth/login/login-approval.component.ts +++ b/apps/desktop/src/auth/login/login-approval.component.ts @@ -18,6 +18,7 @@ import { ButtonModule, DialogModule, DialogService, + ToastService, } from "@bitwarden/components"; const RequestTimeOut = 60000 * 15; //15 Minutes @@ -54,6 +55,7 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { protected appIdService: AppIdService, protected cryptoService: CryptoService, private dialogRef: DialogRef, + private toastService: ToastService, ) { this.notificationId = params.notificationId; } @@ -117,11 +119,11 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { private async retrieveAuthRequestAndRespond(approve: boolean) { this.authRequestResponse = await this.apiService.getAuthRequest(this.notificationId); if (this.authRequestResponse.requestApproved || this.authRequestResponse.responseDate != null) { - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("thisRequestIsNoLongerValid"), - ); + this.toastService.showToast({ + variant: "info", + title: null, + message: this.i18nService.t("thisRequestIsNoLongerValid"), + }); } else { const loginResponse = await this.authRequestService.approveOrDenyAuthRequest( approve, @@ -133,21 +135,21 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { showResultToast(loginResponse: AuthRequestResponse) { if (loginResponse.requestApproved) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t( + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t( "logInConfirmedForEmailOnDevice", this.email, loginResponse.requestDeviceType, ), - ); + }); } else { - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("youDeniedALogInAttemptFromAnotherDevice"), - ); + this.toastService.showToast({ + variant: "info", + title: null, + message: this.i18nService.t("youDeniedALogInAttemptFromAnotherDevice"), + }); } } @@ -186,11 +188,11 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { } else { clearInterval(this.interval); this.dialogRef.close(); - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("loginRequestHasAlreadyExpired"), - ); + this.toastService.showToast({ + variant: "info", + title: null, + message: this.i18nService.t("loginRequestHasAlreadyExpired"), + }); } } } diff --git a/apps/desktop/src/auth/login/login-via-auth-request.component.ts b/apps/desktop/src/auth/login/login-via-auth-request.component.ts index 7a8dfcbcda..c0a6a51b90 100644 --- a/apps/desktop/src/auth/login/login-via-auth-request.component.ts +++ b/apps/desktop/src/auth/login/login-via-auth-request.component.ts @@ -23,6 +23,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EnvironmentComponent } from "../environment.component"; @@ -58,6 +59,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { loginStrategyService: LoginStrategyServiceAbstraction, accountService: AccountService, private location: Location, + toastService: ToastService, ) { super( router, @@ -78,6 +80,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { deviceTrustService, authRequestService, loginStrategyService, + toastService, ); super.onSuccessfulLogin = () => { diff --git a/apps/desktop/src/auth/login/login.component.ts b/apps/desktop/src/auth/login/login.component.ts index 68b25b8b7e..2b5910baa9 100644 --- a/apps/desktop/src/auth/login/login.component.ts +++ b/apps/desktop/src/auth/login/login.component.ts @@ -25,6 +25,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EnvironmentComponent } from "../environment.component"; @@ -74,6 +75,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, registerRouteService: RegisterRouteService, + toastService: ToastService, ) { super( devicesApiService, @@ -95,6 +97,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest ssoLoginService, webAuthnLoginService, registerRouteService, + toastService, ); super.onSuccessfulLogin = () => { return syncService.fullSync(true); @@ -162,11 +165,11 @@ export class LoginComponent extends BaseLoginComponent implements OnInit, OnDest async continue() { await super.validateEmail(); if (!this.formGroup.controls.email.valid) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccured"), - this.i18nService.t("invalidEmail"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccured"), + message: this.i18nService.t("invalidEmail"), + }); return; } this.focusInput(); diff --git a/apps/desktop/src/auth/register.component.ts b/apps/desktop/src/auth/register.component.ts index be44c27648..e7c2cfd32b 100644 --- a/apps/desktop/src/auth/register.component.ts +++ b/apps/desktop/src/auth/register.component.ts @@ -14,7 +14,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; const BroadcasterSubscriptionId = "RegisterComponent"; @@ -41,6 +41,7 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit, logService: LogService, auditService: AuditService, dialogService: DialogService, + toastService: ToastService, ) { super( formValidationErrorService, @@ -57,6 +58,7 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit, logService, auditService, dialogService, + toastService, ); } diff --git a/apps/desktop/src/auth/set-password.component.ts b/apps/desktop/src/auth/set-password.component.ts index f14434b277..28f1f69a59 100644 --- a/apps/desktop/src/auth/set-password.component.ts +++ b/apps/desktop/src/auth/set-password.component.ts @@ -22,7 +22,7 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; const BroadcasterSubscriptionId = "SetPasswordComponent"; @@ -56,6 +56,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On dialogService: DialogService, kdfConfigService: KdfConfigService, encryptService: EncryptService, + toastService: ToastService, ) { super( accountService, @@ -79,6 +80,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On dialogService, kdfConfigService, encryptService, + toastService, ); } diff --git a/apps/desktop/src/auth/sso.component.ts b/apps/desktop/src/auth/sso.component.ts index 234ebc85ce..6821a54894 100644 --- a/apps/desktop/src/auth/sso.component.ts +++ b/apps/desktop/src/auth/sso.component.ts @@ -18,6 +18,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ @@ -43,6 +44,7 @@ export class SsoComponent extends BaseSsoComponent { configService: ConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + toastService: ToastService, ) { super( ssoLoginService, @@ -61,6 +63,7 @@ export class SsoComponent extends BaseSsoComponent { configService, masterPasswordService, accountService, + toastService, ); super.onSuccessfulLogin = async () => { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. diff --git a/apps/web/src/app/auth/hint.component.ts b/apps/web/src/app/auth/hint.component.ts index 944b386e27..4274454623 100644 --- a/apps/web/src/app/auth/hint.component.ts +++ b/apps/web/src/app/auth/hint.component.ts @@ -8,6 +8,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-hint", @@ -30,8 +31,17 @@ export class HintComponent extends BaseHintComponent implements OnInit { logService: LogService, loginEmailService: LoginEmailServiceAbstraction, private formBuilder: FormBuilder, + protected toastService: ToastService, ) { - super(router, i18nService, apiService, platformUtilsService, logService, loginEmailService); + super( + router, + i18nService, + apiService, + platformUtilsService, + logService, + loginEmailService, + toastService, + ); } ngOnInit(): void { diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index 145d766627..1422a7c123 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -29,6 +29,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { flagEnabled } from "../../../utils/flags"; @@ -71,6 +72,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { ssoLoginService: SsoLoginServiceAbstraction, webAuthnLoginService: WebAuthnLoginServiceAbstraction, registerRouteService: RegisterRouteService, + toastService: ToastService, ) { super( devicesApiService, @@ -92,6 +94,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { ssoLoginService, webAuthnLoginService, registerRouteService, + toastService, ); this.onSuccessfulLoginNavigate = this.goAfterLogIn; this.showPasswordless = flagEnabled("showPasswordless"); diff --git a/apps/web/src/app/auth/migrate-encryption/migrate-legacy-encryption.component.ts b/apps/web/src/app/auth/migrate-encryption/migrate-legacy-encryption.component.ts index 6695039307..68eaae618f 100644 --- a/apps/web/src/app/auth/migrate-encryption/migrate-legacy-encryption.component.ts +++ b/apps/web/src/app/auth/migrate-encryption/migrate-legacy-encryption.component.ts @@ -9,6 +9,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { ToastService } from "@bitwarden/components"; import { SharedModule } from "../../shared"; import { UserKeyRotationModule } from "../key-rotation/user-key-rotation.module"; @@ -35,6 +36,7 @@ export class MigrateFromLegacyEncryptionComponent { private messagingService: MessagingService, private logService: LogService, private syncService: SyncService, + private toastService: ToastService, ) {} submit = async () => { @@ -59,12 +61,12 @@ export class MigrateFromLegacyEncryptionComponent { await this.keyRotationService.rotateUserKeyAndEncryptedData(masterPassword, activeUser); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("keyUpdated"), - this.i18nService.t("logBackInOthersToo"), - { timeout: 15000 }, - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("keyUpdated"), + message: this.i18nService.t("logBackInOthersToo"), + timeout: 15000, + }); this.messagingService.send("logout"); } catch (e) { this.logService.error(e); diff --git a/apps/web/src/app/auth/recover-delete.component.ts b/apps/web/src/app/auth/recover-delete.component.ts index 96afd91059..04c3eb1df2 100644 --- a/apps/web/src/app/auth/recover-delete.component.ts +++ b/apps/web/src/app/auth/recover-delete.component.ts @@ -6,6 +6,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { DeleteRecoverRequest } from "@bitwarden/common/models/request/delete-recover.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-recover-delete", @@ -25,6 +26,7 @@ export class RecoverDeleteComponent { private apiService: ApiService, private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, + private toastService: ToastService, ) {} submit = async () => { @@ -35,11 +37,11 @@ export class RecoverDeleteComponent { const request = new DeleteRecoverRequest(); request.email = this.email.value.trim().toLowerCase(); await this.apiService.postAccountRecoverDelete(request); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("deleteRecoverEmailSent"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deleteRecoverEmailSent"), + }); await this.router.navigate(["/"]); }; diff --git a/apps/web/src/app/auth/recover-two-factor.component.ts b/apps/web/src/app/auth/recover-two-factor.component.ts index 28296aa89d..0774a9c777 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.ts @@ -8,6 +8,7 @@ import { TwoFactorRecoveryRequest } from "@bitwarden/common/auth/models/request/ import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-recover-two-factor", @@ -27,6 +28,7 @@ export class RecoverTwoFactorComponent { private i18nService: I18nService, private cryptoService: CryptoService, private loginStrategyService: LoginStrategyServiceAbstraction, + private toastService: ToastService, ) {} get email(): string { @@ -53,11 +55,11 @@ export class RecoverTwoFactorComponent { const key = await this.loginStrategyService.makePreloginKey(this.masterPassword, request.email); request.masterPasswordHash = await this.cryptoService.hashMasterKey(this.masterPassword, key); await this.apiService.postTwoFactorRecover(request); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("twoStepRecoverDisabled"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("twoStepRecoverDisabled"), + }); await this.router.navigate(["/"]); }; } diff --git a/apps/web/src/app/auth/register-form/register-form.component.ts b/apps/web/src/app/auth/register-form/register-form.component.ts index 693cdb4d6c..bf4a3e8203 100644 --- a/apps/web/src/app/auth/register-form/register-form.component.ts +++ b/apps/web/src/app/auth/register-form/register-form.component.ts @@ -17,7 +17,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { AcceptOrganizationInviteService } from "../organization-invite/accept-organization.service"; @@ -52,6 +52,7 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn auditService: AuditService, dialogService: DialogService, acceptOrgInviteService: AcceptOrganizationInviteService, + toastService: ToastService, ) { super( formValidationErrorService, @@ -68,6 +69,7 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn logService, auditService, dialogService, + toastService, ); super.modifyRegisterRequest = async (request: RegisterRequest) => { // Org invites are deep linked. Non-existent accounts are redirected to the register page. @@ -104,11 +106,11 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn this.enforcedPolicyOptions, ) ) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), + }); return; } diff --git a/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts b/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts index b555faf9a1..e20245bfa0 100644 --- a/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts +++ b/apps/web/src/app/auth/settings/account/change-avatar-dialog.component.ts @@ -15,7 +15,7 @@ import { ProfileResponse } from "@bitwarden/common/models/response/profile.respo import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; type ChangeAvatarDialogData = { profile: ProfileResponse; @@ -55,6 +55,7 @@ export class ChangeAvatarDialogComponent implements OnInit, OnDestroy { private platformUtilsService: PlatformUtilsService, private avatarService: AvatarService, private dialogRef: DialogRef, + private toastService: ToastService, ) { this.profile = data.profile; } @@ -93,9 +94,17 @@ export class ChangeAvatarDialogComponent implements OnInit, OnDestroy { if (Utils.validateHexColor(this.currentSelection) || this.currentSelection == null) { await this.avatarService.setAvatarColor(this.currentSelection); this.dialogRef.close(); - this.platformUtilsService.showToast("success", null, this.i18nService.t("avatarUpdated")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("avatarUpdated"), + }); } else { - this.platformUtilsService.showToast("error", null, this.i18nService.t("errorOccurred")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); } }; diff --git a/apps/web/src/app/auth/settings/account/change-email.component.ts b/apps/web/src/app/auth/settings/account/change-email.component.ts index e5a3c72337..ac49335776 100644 --- a/apps/web/src/app/auth/settings/account/change-email.component.ts +++ b/apps/web/src/app/auth/settings/account/change-email.component.ts @@ -12,6 +12,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-change-email", @@ -39,6 +40,7 @@ export class ChangeEmailComponent implements OnInit { private stateService: StateService, private formBuilder: FormBuilder, private kdfConfigService: KdfConfigService, + private toastService: ToastService, ) {} async ngOnInit() { @@ -100,11 +102,11 @@ export class ChangeEmailComponent implements OnInit { try { await this.apiService.postEmail(request); this.reset(); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("emailChanged"), - this.i18nService.t("logBackIn"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("emailChanged"), + message: this.i18nService.t("logBackIn"), + }); this.messagingService.send("logout"); } catch (e) { this.logService.error(e); diff --git a/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts b/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts index 9b9ba7eb79..dcaf38ee29 100644 --- a/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts +++ b/apps/web/src/app/auth/settings/account/deauthorize-sessions.component.ts @@ -7,6 +7,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-deauthorize-sessions", @@ -23,6 +24,7 @@ export class DeauthorizeSessionsComponent { private userVerificationService: UserVerificationService, private messagingService: MessagingService, private logService: LogService, + private toastService: ToastService, ) {} async submit() { @@ -31,11 +33,11 @@ export class DeauthorizeSessionsComponent { .buildRequest(this.masterPassword) .then((request) => this.apiService.postSecurityStamp(request)); await this.formPromise; - this.platformUtilsService.showToast( - "success", - this.i18nService.t("sessionsDeauthorized"), - this.i18nService.t("logBackIn"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("sessionsDeauthorized"), + message: this.i18nService.t("logBackIn"), + }); this.messagingService.send("logout"); } catch (e) { this.logService.error(e); diff --git a/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts b/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts index b3dd8fbe61..c7c67416e1 100644 --- a/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts +++ b/apps/web/src/app/auth/settings/account/delete-account-dialog.component.ts @@ -7,7 +7,7 @@ import { Verification } 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 { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; @Component({ templateUrl: "delete-account-dialog.component.html", @@ -24,6 +24,7 @@ export class DeleteAccountDialogComponent { private formBuilder: FormBuilder, private accountApiService: AccountApiService, private dialogRef: DialogRef, + private toastService: ToastService, ) {} submit = async () => { @@ -31,11 +32,11 @@ export class DeleteAccountDialogComponent { const verification = this.deleteForm.get("verification").value; await this.accountApiService.deleteAccount(verification); this.dialogRef.close(); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("accountDeleted"), - this.i18nService.t("accountDeletedDesc"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("accountDeleted"), + message: this.i18nService.t("accountDeletedDesc"), + }); } catch (e) { if (e instanceof ErrorResponse && e.statusCode === 400) { this.invalidSecret = true; diff --git a/apps/web/src/app/auth/settings/account/profile.component.ts b/apps/web/src/app/auth/settings/account/profile.component.ts index a960adfe5d..8b659e579d 100644 --- a/apps/web/src/app/auth/settings/account/profile.component.ts +++ b/apps/web/src/app/auth/settings/account/profile.component.ts @@ -8,7 +8,7 @@ import { ProfileResponse } from "@bitwarden/common/models/response/profile.respo import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { ChangeAvatarDialogComponent } from "./change-avatar-dialog.component"; @@ -33,6 +33,7 @@ export class ProfileComponent implements OnInit, OnDestroy { private platformUtilsService: PlatformUtilsService, private stateService: StateService, private dialogService: DialogService, + private toastService: ToastService, ) {} async ngOnInit() { @@ -64,6 +65,10 @@ export class ProfileComponent implements OnInit, OnDestroy { submit = async () => { const request = new UpdateProfileRequest(this.formGroup.get("name").value); await this.apiService.putProfile(request); - this.platformUtilsService.showToast("success", null, this.i18nService.t("accountUpdated")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("accountUpdated"), + }); }; } diff --git a/apps/web/src/app/auth/settings/change-password.component.ts b/apps/web/src/app/auth/settings/change-password.component.ts index 5279c05032..2cc7c101d0 100644 --- a/apps/web/src/app/auth/settings/change-password.component.ts +++ b/apps/web/src/app/auth/settings/change-password.component.ts @@ -22,7 +22,7 @@ import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { UserKeyRotationService } from "../key-rotation/user-key-rotation.service"; @@ -60,6 +60,7 @@ export class ChangePasswordComponent kdfConfigService: KdfConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + toastService: ToastService, ) { super( i18nService, @@ -73,6 +74,7 @@ export class ChangePasswordComponent kdfConfigService, masterPasswordService, accountService, + toastService, ); } @@ -141,11 +143,11 @@ export class ChangePasswordComponent this.masterPasswordHint != null && this.masterPasswordHint.toLowerCase() === this.masterPassword.toLowerCase() ) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("hintEqualsPassword"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("hintEqualsPassword"), + }); return; } @@ -159,11 +161,11 @@ export class ChangePasswordComponent async setupSubmitActions() { if (this.currentMasterPassword == null || this.currentMasterPassword === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordRequired"), + }); return false; } @@ -194,11 +196,11 @@ export class ChangePasswordComponent const userKey = await this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey); if (userKey == null) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("invalidMasterPassword"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("invalidMasterPassword"), + }); return; } @@ -225,14 +227,18 @@ export class ChangePasswordComponent await this.formPromise; - this.platformUtilsService.showToast( - "success", - this.i18nService.t("masterPasswordChanged"), - this.i18nService.t("logBackIn"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("masterPasswordChanged"), + message: this.i18nService.t("logBackIn"), + }); this.messagingService.send("logout"); } catch { - this.platformUtilsService.showToast("error", null, this.i18nService.t("errorOccurred")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); } } diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts index d99c693e73..fa5e80c81f 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts @@ -5,7 +5,7 @@ import { FormBuilder, Validators } from "@angular/forms"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { EmergencyAccessService } from "../../emergency-access"; import { EmergencyAccessType } from "../../emergency-access/enums/emergency-access-type"; @@ -51,6 +51,7 @@ export class EmergencyAccessAddEditComponent implements OnInit { private platformUtilsService: PlatformUtilsService, private logService: LogService, private dialogRef: DialogRef, + private toastService: ToastService, ) {} async ngOnInit() { this.editMode = this.loading = this.params.emergencyAccessId != null; @@ -104,11 +105,14 @@ export class EmergencyAccessAddEditComponent implements OnInit { this.addEditForm.value.waitTime, ); } - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t(this.editMode ? "editedUserId" : "invitedUsers", this.params.name), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t( + this.editMode ? "editedUserId" : "invitedUsers", + this.params.name, + ), + }); this.dialogRef.close(EmergencyAccessAddEditDialogResult.Saved); } catch (e) { this.logService.error(e); diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts index 05e65405fb..d8cedd5bd4 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts @@ -10,7 +10,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { EmergencyAccessService } from "../../emergency-access"; import { EmergencyAccessStatusType } from "../../emergency-access/enums/emergency-access-status-type"; @@ -66,6 +66,7 @@ export class EmergencyAccessComponent implements OnInit { protected dialogService: DialogService, billingAccountProfileStateService: BillingAccountProfileStateService, protected organizationManagementPreferencesService: OrganizationManagementPreferencesService, + private toastService: ToastService, ) { this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; } @@ -121,11 +122,11 @@ export class EmergencyAccessComponent implements OnInit { } this.actionPromise = this.emergencyAccessService.reinvite(contact.id); await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("hasBeenReinvited", contact.email), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("hasBeenReinvited", contact.email), + }); this.actionPromise = null; } @@ -153,11 +154,11 @@ export class EmergencyAccessComponent implements OnInit { if (result === EmergencyAccessConfirmDialogResult.Confirmed) { await this.emergencyAccessService.confirm(contact.id, contact.granteeId); updateUser(); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(contact)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(contact)), + }); } return; } @@ -166,11 +167,11 @@ export class EmergencyAccessComponent implements OnInit { await this.actionPromise; updateUser(); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(contact)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("hasBeenConfirmed", this.userNamePipe.transform(contact)), + }); this.actionPromise = null; } @@ -187,11 +188,11 @@ export class EmergencyAccessComponent implements OnInit { try { await this.emergencyAccessService.delete(details.id); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("removedUserId", this.userNamePipe.transform(details)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("removedUserId", this.userNamePipe.transform(details)), + }); if (details instanceof GranteeEmergencyAccess) { this.removeGrantee(details); @@ -221,11 +222,11 @@ export class EmergencyAccessComponent implements OnInit { await this.emergencyAccessService.requestAccess(details.id); details.status = EmergencyAccessStatusType.RecoveryInitiated; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("requestSent", this.userNamePipe.transform(details)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("requestSent", this.userNamePipe.transform(details)), + }); } async approve(details: GranteeEmergencyAccess) { @@ -250,22 +251,22 @@ export class EmergencyAccessComponent implements OnInit { await this.emergencyAccessService.approve(details.id); details.status = EmergencyAccessStatusType.RecoveryApproved; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("emergencyApproved", this.userNamePipe.transform(details)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("emergencyApproved", this.userNamePipe.transform(details)), + }); } async reject(details: GranteeEmergencyAccess) { await this.emergencyAccessService.reject(details.id); details.status = EmergencyAccessStatusType.Confirmed; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("emergencyRejected", this.userNamePipe.transform(details)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("emergencyRejected", this.userNamePipe.transform(details)), + }); } takeover = async (details: GrantorEmergencyAccess) => { @@ -278,11 +279,11 @@ export class EmergencyAccessComponent implements OnInit { }); const result = await lastValueFrom(dialogRef.closed); if (result === EmergencyAccessTakeoverResultType.Done) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("passwordResetFor", this.userNamePipe.transform(details)), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("passwordResetFor", this.userNamePipe.transform(details)), + }); } }; diff --git a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts index a3d856aa69..26995c7ce0 100644 --- a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts @@ -15,7 +15,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { KdfType } from "@bitwarden/common/platform/enums"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { EmergencyAccessService } from "../../../emergency-access"; @@ -64,6 +64,7 @@ export class EmergencyAccessTakeoverComponent kdfConfigService: KdfConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + protected toastService: ToastService, ) { super( i18nService, @@ -77,6 +78,7 @@ export class EmergencyAccessTakeoverComponent kdfConfigService, masterPasswordService, accountService, + toastService, ); } @@ -114,11 +116,11 @@ export class EmergencyAccessTakeoverComponent ); } catch (e) { this.logService.error(e); - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("unexpectedError"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("unexpectedError"), + }); } this.dialogRef.close(EmergencyAccessTakeoverResultType.Done); }; diff --git a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts index 0c754e262e..295037ce6b 100644 --- a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts +++ b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts @@ -12,6 +12,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { KdfType } from "@bitwarden/common/platform/enums"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-change-kdf-confirmation", @@ -35,6 +36,7 @@ export class ChangeKdfConfirmationComponent { private messagingService: MessagingService, @Inject(DIALOG_DATA) params: { kdf: KdfType; kdfConfig: KdfConfig }, private accountService: AccountService, + private toastService: ToastService, ) { this.kdfConfig = params.kdfConfig; this.masterPassword = null; @@ -46,11 +48,11 @@ export class ChangeKdfConfirmationComponent { } this.loading = true; await this.makeKeyAndSaveAsync(); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("encKeySettingsChanged"), - this.i18nService.t("logBackIn"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("encKeySettingsChanged"), + message: this.i18nService.t("logBackIn"), + }); this.messagingService.send("logout"); this.loading = false; }; diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts index b4bef9f74e..fdd595b7fc 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts @@ -17,7 +17,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { TwoFactorBaseComponent } from "./two-factor-base.component"; @@ -68,6 +68,7 @@ export class TwoFactorAuthenticatorComponent private accountService: AccountService, dialogService: DialogService, private configService: ConfigService, + protected toastService: ToastService, ) { super( apiService, @@ -76,6 +77,7 @@ export class TwoFactorAuthenticatorComponent logService, userVerificationService, dialogService, + toastService, ); this.qrScript = window.document.createElement("script"); this.qrScript.src = "scripts/qrious.min.js"; @@ -148,7 +150,11 @@ export class TwoFactorAuthenticatorComponent request.userVerificationToken = this.userVerificationToken; await this.apiService.deleteTwoFactorAuthenticator(request); this.enabled = false; - this.platformUtilsService.showToast("success", null, this.i18nService.t("twoStepDisabled")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("twoStepDisabled"), + }); this.onUpdated.emit(false); } diff --git a/apps/web/src/app/auth/settings/two-factor-base.component.ts b/apps/web/src/app/auth/settings/two-factor-base.component.ts index ac8906641d..2a6af1df98 100644 --- a/apps/web/src/app/auth/settings/two-factor-base.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-base.component.ts @@ -10,7 +10,7 @@ import { AuthResponseBase } from "@bitwarden/common/auth/types/auth-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; @Directive() export abstract class TwoFactorBaseComponent { @@ -33,6 +33,7 @@ export abstract class TwoFactorBaseComponent { protected logService: LogService, protected userVerificationService: UserVerificationService, protected dialogService: DialogService, + protected toastService: ToastService, ) {} protected auth(authResponse: AuthResponseBase) { @@ -76,7 +77,11 @@ export abstract class TwoFactorBaseComponent { } await promise; this.enabled = false; - this.platformUtilsService.showToast("success", null, this.i18nService.t("twoStepDisabled")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("twoStepDisabled"), + }); this.onUpdated.emit(false); } catch (e) { this.logService.error(e); @@ -102,7 +107,11 @@ export abstract class TwoFactorBaseComponent { await this.apiService.putTwoFactorDisable(request); } this.enabled = false; - this.platformUtilsService.showToast("success", null, this.i18nService.t("twoStepDisabled")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("twoStepDisabled"), + }); this.onUpdated.emit(false); } diff --git a/apps/web/src/app/auth/settings/two-factor-duo.component.ts b/apps/web/src/app/auth/settings/two-factor-duo.component.ts index a211aa4c9b..1a5b591710 100644 --- a/apps/web/src/app/auth/settings/two-factor-duo.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-duo.component.ts @@ -11,7 +11,7 @@ import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { TwoFactorBaseComponent } from "./two-factor-base.component"; @@ -40,6 +40,7 @@ export class TwoFactorDuoComponent extends TwoFactorBaseComponent implements OnI dialogService: DialogService, private formBuilder: FormBuilder, private dialogRef: DialogRef, + protected toastService: ToastService, ) { super( apiService, @@ -48,6 +49,7 @@ export class TwoFactorDuoComponent extends TwoFactorBaseComponent implements OnI logService, userVerificationService, dialogService, + toastService, ); } diff --git a/apps/web/src/app/auth/settings/two-factor-email.component.ts b/apps/web/src/app/auth/settings/two-factor-email.component.ts index 96b4bfb38d..524b00d114 100644 --- a/apps/web/src/app/auth/settings/two-factor-email.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-email.component.ts @@ -14,7 +14,7 @@ import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { TwoFactorBaseComponent } from "./two-factor-base.component"; @@ -45,6 +45,7 @@ export class TwoFactorEmailComponent extends TwoFactorBaseComponent implements O dialogService: DialogService, private formBuilder: FormBuilder, private dialogRef: DialogRef, + protected toastService: ToastService, ) { super( apiService, @@ -53,6 +54,7 @@ export class TwoFactorEmailComponent extends TwoFactorBaseComponent implements O logService, userVerificationService, dialogService, + toastService, ); } get token() { diff --git a/apps/web/src/app/auth/settings/two-factor-webauthn.component.ts b/apps/web/src/app/auth/settings/two-factor-webauthn.component.ts index 5e8ea37e93..9aeafaf2c6 100644 --- a/apps/web/src/app/auth/settings/two-factor-webauthn.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-webauthn.component.ts @@ -16,7 +16,7 @@ import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { TwoFactorBaseComponent } from "./two-factor-base.component"; @@ -61,6 +61,7 @@ export class TwoFactorWebAuthnComponent extends TwoFactorBaseComponent { logService: LogService, userVerificationService: UserVerificationService, dialogService: DialogService, + toastService: ToastService, ) { super( apiService, @@ -69,6 +70,7 @@ export class TwoFactorWebAuthnComponent extends TwoFactorBaseComponent { logService, userVerificationService, dialogService, + toastService, ); this.auth(data); } diff --git a/apps/web/src/app/auth/settings/two-factor-yubikey.component.ts b/apps/web/src/app/auth/settings/two-factor-yubikey.component.ts index 83718360ca..3b601084c3 100644 --- a/apps/web/src/app/auth/settings/two-factor-yubikey.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-yubikey.component.ts @@ -55,7 +55,7 @@ export class TwoFactorYubiKeyComponent extends TwoFactorBaseComponent implements userVerificationService: UserVerificationService, dialogService: DialogService, private formBuilder: FormBuilder, - private toastService: ToastService, + protected toastService: ToastService, ) { super( apiService, @@ -64,6 +64,7 @@ export class TwoFactorYubiKeyComponent extends TwoFactorBaseComponent implements logService, userVerificationService, dialogService, + toastService, ); } diff --git a/apps/web/src/app/auth/settings/verify-email.component.ts b/apps/web/src/app/auth/settings/verify-email.component.ts index e8809cd893..6fa7a49bc0 100644 --- a/apps/web/src/app/auth/settings/verify-email.component.ts +++ b/apps/web/src/app/auth/settings/verify-email.component.ts @@ -6,7 +6,13 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { AsyncActionsModule, BannerModule, ButtonModule, LinkModule } from "@bitwarden/components"; +import { + AsyncActionsModule, + BannerModule, + ButtonModule, + LinkModule, + ToastService, +} from "@bitwarden/components"; @Component({ standalone: true, @@ -25,22 +31,27 @@ export class VerifyEmailComponent { private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private tokenService: TokenService, + private toastService: ToastService, ) {} async verifyEmail(): Promise { await this.apiService.refreshIdentityToken(); if (await this.tokenService.getEmailVerified()) { this.onVerified.emit(true); - this.platformUtilsService.showToast("success", null, this.i18nService.t("emailVerified")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("emailVerified"), + }); return; } await this.apiService.postAccountVerifyEmail(); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("checkInboxForVerification"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("checkInboxForVerification"), + }); } send = async () => { diff --git a/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts b/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts index fd72cbbb71..c0ed678d0a 100644 --- a/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts +++ b/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts @@ -9,7 +9,7 @@ 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 { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { WebauthnLoginAdminService } from "../../../core"; import { CredentialCreateOptionsView } from "../../../core/views/credential-create-options.view"; @@ -60,6 +60,7 @@ export class CreateCredentialDialogComponent implements OnInit { private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, private logService: LogService, + private toastService: ToastService, ) {} ngOnInit(): void { @@ -102,11 +103,11 @@ export class CreateCredentialDialogComponent implements OnInit { this.invalidSecret = true; } else { this.logService?.error(error); - this.platformUtilsService.showToast( - "error", - this.i18nService.t("unexpectedError"), - error.message, - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("unexpectedError"), + message: error.message, + }); } return; } @@ -162,17 +163,17 @@ export class CreateCredentialDialogComponent implements OnInit { ); if (await firstValueFrom(this.hasPasskeys$)) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("passkeySaved", name), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("passkeySaved", name), + }); } else { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("loginWithPasskeyEnabled"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("loginWithPasskeyEnabled"), + }); } this.dialogRef.close(CreateCredentialDialogResult.Success); diff --git a/apps/web/src/app/auth/settings/webauthn-login-settings/delete-credential-dialog/delete-credential-dialog.component.ts b/apps/web/src/app/auth/settings/webauthn-login-settings/delete-credential-dialog/delete-credential-dialog.component.ts index 4fec10d269..ce86874ce4 100644 --- a/apps/web/src/app/auth/settings/webauthn-login-settings/delete-credential-dialog/delete-credential-dialog.component.ts +++ b/apps/web/src/app/auth/settings/webauthn-login-settings/delete-credential-dialog/delete-credential-dialog.component.ts @@ -8,7 +8,7 @@ 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 { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { WebauthnLoginAdminService } from "../../../core"; import { WebauthnLoginCredentialView } from "../../../core/views/webauthn-login-credential.view"; @@ -38,6 +38,7 @@ export class DeleteCredentialDialogComponent implements OnInit, OnDestroy { private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, private logService: LogService, + private toastService: ToastService, ) {} ngOnInit(): void { @@ -55,17 +56,21 @@ export class DeleteCredentialDialogComponent implements OnInit, OnDestroy { this.dialogRef.disableClose = true; try { await this.webauthnService.deleteCredential(this.credential.id, this.formGroup.value.secret); - this.platformUtilsService.showToast("success", null, this.i18nService.t("passkeyRemoved")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("passkeyRemoved"), + }); } catch (error) { if (error instanceof ErrorResponse && error.statusCode === 400) { this.invalidSecret = true; } else { this.logService?.error(error); - this.platformUtilsService.showToast( - "error", - this.i18nService.t("unexpectedError"), - error.message, - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("unexpectedError"), + message: error.message, + }); } return false; } finally { diff --git a/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts b/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts index cd4ac2db35..7947d53c99 100644 --- a/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts +++ b/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts @@ -9,7 +9,7 @@ import { import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; /** * @deprecated Jan 24, 2024: Use new libs/auth UserVerificationDialogComponent instead. @@ -25,8 +25,17 @@ export class UserVerificationPromptComponent extends BaseUserVerificationPrompt formBuilder: FormBuilder, platformUtilsService: PlatformUtilsService, i18nService: I18nService, + toastService: ToastService, ) { - super(null, data, userVerificationService, formBuilder, platformUtilsService, i18nService); + super( + null, + data, + userVerificationService, + formBuilder, + platformUtilsService, + i18nService, + toastService, + ); } override close(success: boolean) { diff --git a/apps/web/src/app/auth/sso.component.ts b/apps/web/src/app/auth/sso.component.ts index 93a00054eb..f55152fed3 100644 --- a/apps/web/src/app/auth/sso.component.ts +++ b/apps/web/src/app/auth/sso.component.ts @@ -25,6 +25,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Component({ @@ -60,6 +61,7 @@ export class SsoComponent extends BaseSsoComponent implements OnInit { configService: ConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + toastService: ToastService, ) { super( ssoLoginService, @@ -78,6 +80,7 @@ export class SsoComponent extends BaseSsoComponent implements OnInit { configService, masterPasswordService, accountService, + toastService, ); this.redirectUri = window.location.origin + "/sso-connector.html"; this.clientId = "web"; diff --git a/apps/web/src/app/auth/two-factor-auth.component.ts b/apps/web/src/app/auth/two-factor-auth.component.ts index fbdddecce9..18660b2ca6 100644 --- a/apps/web/src/app/auth/two-factor-auth.component.ts +++ b/apps/web/src/app/auth/two-factor-auth.component.ts @@ -17,7 +17,13 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { LinkModule, TypographyModule, CheckboxModule, DialogService } from "@bitwarden/components"; +import { + LinkModule, + TypographyModule, + CheckboxModule, + DialogService, + ToastService, +} from "@bitwarden/components"; import { TwoFactorAuthAuthenticatorComponent } from "../../../../../libs/angular/src/auth/components/two-factor-auth/two-factor-auth-authenticator.component"; import { TwoFactorAuthEmailComponent } from "../../../../../libs/angular/src/auth/components/two-factor-auth/two-factor-auth-email.component"; @@ -81,6 +87,7 @@ export class TwoFactorAuthComponent extends BaseTwoFactorAuthComponent { accountService: AccountService, formBuilder: FormBuilder, @Inject(WINDOW) protected win: Window, + toastService: ToastService, ) { super( loginStrategyService, @@ -100,6 +107,7 @@ export class TwoFactorAuthComponent extends BaseTwoFactorAuthComponent { accountService, formBuilder, win, + toastService, ); this.onSuccessfulLoginNavigate = this.goAfterLogIn; } diff --git a/apps/web/src/app/auth/verify-email-token.component.ts b/apps/web/src/app/auth/verify-email-token.component.ts index 67ea7c9785..d47e2c885e 100644 --- a/apps/web/src/app/auth/verify-email-token.component.ts +++ b/apps/web/src/app/auth/verify-email-token.component.ts @@ -8,6 +8,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-verify-email-token", @@ -23,6 +24,7 @@ export class VerifyEmailTokenComponent implements OnInit { private apiService: ApiService, private logService: LogService, private stateService: StateService, + private toastService: ToastService, ) {} ngOnInit() { @@ -36,7 +38,11 @@ export class VerifyEmailTokenComponent implements OnInit { if (await this.stateService.getIsAuthenticated()) { await this.apiService.refreshIdentityToken(); } - this.platformUtilsService.showToast("success", null, this.i18nService.t("emailVerified")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("emailVerified"), + }); // 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.router.navigate(["/"]); @@ -45,7 +51,11 @@ export class VerifyEmailTokenComponent implements OnInit { this.logService.error(e); } } - this.platformUtilsService.showToast("error", null, this.i18nService.t("emailVerifiedFailed")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("emailVerifiedFailed"), + }); // 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.router.navigate(["/"]); diff --git a/apps/web/src/app/auth/verify-recover-delete.component.ts b/apps/web/src/app/auth/verify-recover-delete.component.ts index b3d380fcbd..179913d7e3 100644 --- a/apps/web/src/app/auth/verify-recover-delete.component.ts +++ b/apps/web/src/app/auth/verify-recover-delete.component.ts @@ -7,6 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VerifyDeleteRecoverRequest } from "@bitwarden/common/models/request/verify-delete-recover.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Component({ selector: "app-verify-recover-delete", @@ -26,6 +27,7 @@ export class VerifyRecoverDeleteComponent implements OnInit { private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, private route: ActivatedRoute, + private toastService: ToastService, ) {} ngOnInit() { @@ -44,11 +46,11 @@ export class VerifyRecoverDeleteComponent implements OnInit { submit = async () => { const request = new VerifyDeleteRecoverRequest(this.userId, this.token); await this.apiService.postAccountRecoverDeleteToken(request); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("accountDeleted"), - this.i18nService.t("accountDeletedDesc"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("accountDeleted"), + message: this.i18nService.t("accountDeletedDesc"), + }); await this.router.navigate(["/"]); }; } diff --git a/bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts b/bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts index 4074c20d9d..e37da8c784 100644 --- a/bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts +++ b/bitwarden_license/bit-web/src/app/auth/sso/sso.component.ts @@ -26,9 +26,11 @@ import { SsoConfigApi } from "@bitwarden/common/auth/models/api/sso-config.api"; import { OrganizationSsoRequest } from "@bitwarden/common/auth/models/request/organization-sso.request"; import { OrganizationSsoResponse } from "@bitwarden/common/auth/models/response/organization-sso.response"; import { SsoConfigView } from "@bitwarden/common/auth/models/view/sso-config.view"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { ToastService } from "@bitwarden/components"; import { ssoTypeValidator } from "./sso-type.validator"; @@ -189,6 +191,8 @@ export class SsoComponent implements OnInit, OnDestroy { private i18nService: I18nService, private organizationService: OrganizationService, private organizationApiService: OrganizationApiServiceAbstraction, + private configService: ConfigService, + private toastService: ToastService, ) {} async ngOnInit() { @@ -282,7 +286,11 @@ export class SsoComponent implements OnInit, OnDestroy { const response = await this.organizationApiService.updateSso(this.organizationId, request); this.populateForm(response); - this.platformUtilsService.showToast("success", null, this.i18nService.t("ssoSettingsSaved")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("ssoSettingsSaved"), + }); }; async validateKeyConnectorUrl() { diff --git a/libs/angular/src/auth/components/base-login-decryption-options.component.ts b/libs/angular/src/auth/components/base-login-decryption-options.component.ts index 0cc416a74b..80088bf7f9 100644 --- a/libs/angular/src/auth/components/base-login-decryption-options.component.ts +++ b/libs/angular/src/auth/components/base-login-decryption-options.component.ts @@ -39,6 +39,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; enum State { NewUser, @@ -104,6 +105,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction, protected ssoLoginService: SsoLoginServiceAbstraction, protected accountService: AccountService, + protected toastService: ToastService, ) {} async ngOnInit() { @@ -275,11 +277,11 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { const keysRequest = new KeysRequest(publicKey, privateKey.encryptedString); await this.apiService.postAccountKeys(keysRequest); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("accountSuccessfullyCreated"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("accountSuccessfullyCreated"), + }); await this.passwordResetEnrollmentService.enroll(this.data.organizationId); diff --git a/libs/angular/src/auth/components/captcha-protected.component.ts b/libs/angular/src/auth/components/captcha-protected.component.ts index 0f549d2498..7186f6c3c4 100644 --- a/libs/angular/src/auth/components/captcha-protected.component.ts +++ b/libs/angular/src/auth/components/captcha-protected.component.ts @@ -6,6 +6,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { ToastService } from "@bitwarden/components"; @Directive() export abstract class CaptchaProtectedComponent { @@ -17,6 +18,7 @@ export abstract class CaptchaProtectedComponent { protected environmentService: EnvironmentService, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, + protected toastService: ToastService, ) {} async setupCaptcha() { @@ -31,10 +33,18 @@ export abstract class CaptchaProtectedComponent { this.captchaToken = token; }, (error: string) => { - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), error); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: error, + }); }, (info: string) => { - this.platformUtilsService.showToast("info", this.i18nService.t("info"), info); + this.toastService.showToast({ + variant: "info", + title: this.i18nService.t("info"), + message: info, + }); }, ); } diff --git a/libs/angular/src/auth/components/change-password.component.ts b/libs/angular/src/auth/components/change-password.component.ts index d6c0ec9271..45ddf9095f 100644 --- a/libs/angular/src/auth/components/change-password.component.ts +++ b/libs/angular/src/auth/components/change-password.component.ts @@ -15,7 +15,7 @@ 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 { UserKey, MasterKey } from "@bitwarden/common/types/key"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { PasswordColorText } from "../../tools/password-strength/password-strength.component"; @@ -49,6 +49,7 @@ export class ChangePasswordComponent implements OnInit, OnDestroy { protected kdfConfigService: KdfConfigService, protected masterPasswordService: InternalMasterPasswordServiceAbstraction, protected accountService: AccountService, + protected toastService: ToastService, ) {} async ngOnInit() { @@ -127,27 +128,27 @@ export class ChangePasswordComponent implements OnInit, OnDestroy { async strongPassword(): Promise { if (this.masterPassword == null || this.masterPassword === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordRequired"), + }); return false; } if (this.masterPassword.length < this.minimumLength) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordMinimumlength", this.minimumLength), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordMinimumlength", this.minimumLength), + }); return false; } if (this.masterPassword !== this.masterPasswordRetype) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPassDoesntMatch"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPassDoesntMatch"), + }); return false; } @@ -161,11 +162,11 @@ export class ChangePasswordComponent implements OnInit, OnDestroy { this.enforcedPolicyOptions, ) ) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordPolicyRequirementsNotMet"), + }); return false; } diff --git a/libs/angular/src/auth/components/environment.component.ts b/libs/angular/src/auth/components/environment.component.ts index a58d5e5082..25f1055330 100644 --- a/libs/angular/src/auth/components/environment.component.ts +++ b/libs/angular/src/auth/components/environment.component.ts @@ -7,6 +7,7 @@ import { } 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 { ToastService } from "@bitwarden/components"; import { ModalService } from "../../services/modal.service"; @@ -27,6 +28,7 @@ export class EnvironmentComponent { protected environmentService: EnvironmentService, protected i18nService: I18nService, private modalService: ModalService, + private toastService: ToastService, ) { this.environmentService.environment$.pipe(takeUntilDestroyed()).subscribe((env) => { if (env.getRegion() !== Region.SelfHosted) { @@ -59,7 +61,11 @@ export class EnvironmentComponent { notifications: this.notificationsUrl, }); - this.platformUtilsService.showToast("success", null, this.i18nService.t("environmentSaved")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("environmentSaved"), + }); this.saved(); } diff --git a/libs/angular/src/auth/components/hint.component.ts b/libs/angular/src/auth/components/hint.component.ts index 484604b6a5..7a152efbb9 100644 --- a/libs/angular/src/auth/components/hint.component.ts +++ b/libs/angular/src/auth/components/hint.component.ts @@ -7,6 +7,7 @@ import { PasswordHintRequest } from "@bitwarden/common/auth/models/request/passw import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; @Directive() export class HintComponent implements OnInit { @@ -23,6 +24,7 @@ export class HintComponent implements OnInit { protected platformUtilsService: PlatformUtilsService, private logService: LogService, private loginEmailService: LoginEmailServiceAbstraction, + protected toastService: ToastService, ) {} ngOnInit(): void { @@ -31,26 +33,30 @@ export class HintComponent implements OnInit { async submit() { if (this.email == null || this.email === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("emailRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("emailRequired"), + }); return; } if (this.email.indexOf("@") === -1) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("invalidEmail"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidEmail"), + }); return; } try { this.formPromise = this.apiService.postPasswordHint(new PasswordHintRequest(this.email)); await this.formPromise; - this.platformUtilsService.showToast("success", null, this.i18nService.t("masterPassSent")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("masterPassSent"), + }); if (this.onSuccessfulSubmit != null) { this.onSuccessfulSubmit(); } else if (this.router != null) { diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index 400dcfd889..484e1c6346 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -36,7 +36,7 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; @Directive() export class LockComponent implements OnInit, OnDestroy { @@ -90,6 +90,7 @@ export class LockComponent implements OnInit, OnDestroy { protected authService: AuthService, protected kdfConfigService: KdfConfigService, protected syncService: SyncService, + protected toastService: ToastService, ) {} async ngOnInit() { @@ -167,11 +168,11 @@ export class LockComponent implements OnInit, OnDestroy { private async handlePinRequiredUnlock() { if (this.pin == null || this.pin === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("pinRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("pinRequired"), + }); return; } @@ -195,36 +196,36 @@ export class LockComponent implements OnInit, OnDestroy { // Log user out if they have entered an invalid PIN too many times if (this.invalidPinAttempts >= MAX_INVALID_PIN_ENTRY_ATTEMPTS) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("tooManyInvalidPinEntryAttemptsLoggingOut"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("tooManyInvalidPinEntryAttemptsLoggingOut"), + }); this.messagingService.send("logout"); return; } - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("invalidPin"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidPin"), + }); } catch { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("unexpectedError"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("unexpectedError"), + }); } } private async handleMasterPasswordRequiredUnlock() { if (this.masterPassword == null || this.masterPassword === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordRequired"), + }); return; } await this.doUnlockWithMasterPassword(); @@ -258,11 +259,11 @@ export class LockComponent implements OnInit, OnDestroy { } if (!passwordValid) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("invalidMasterPassword"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidMasterPassword"), + }); return; } diff --git a/libs/angular/src/auth/components/login-via-auth-request.component.ts b/libs/angular/src/auth/components/login-via-auth-request.component.ts index f6356314f5..452b5ceee1 100644 --- a/libs/angular/src/auth/components/login-via-auth-request.component.ts +++ b/libs/angular/src/auth/components/login-via-auth-request.component.ts @@ -32,6 +32,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { CaptchaProtectedComponent } from "./captcha-protected.component"; @@ -88,8 +89,9 @@ export class LoginViaAuthRequestComponent private deviceTrustService: DeviceTrustServiceAbstraction, private authRequestService: AuthRequestServiceAbstraction, private loginStrategyService: LoginStrategyServiceAbstraction, + protected toastService: ToastService, ) { - super(environmentService, i18nService, platformUtilsService); + super(environmentService, i18nService, platformUtilsService, toastService); // TODO: I don't know why this is necessary. // Why would the existence of the email depend on the navigation? @@ -105,7 +107,11 @@ export class LoginViaAuthRequestComponent .subscribe((id) => { // eslint-disable-next-line @typescript-eslint/no-floating-promises this.verifyAndHandleApprovedAuthReq(id).catch((e: Error) => { - this.platformUtilsService.showToast("error", this.i18nService.t("error"), e.message); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("error"), + message: e.message, + }); this.logService.error("Failed to use approved auth request: " + e.message); }); }); @@ -135,7 +141,11 @@ export class LoginViaAuthRequestComponent const userId = (await firstValueFrom(this.accountService.activeAccount$)).id; if (!this.email) { - this.platformUtilsService.showToast("error", null, this.i18nService.t("userEmailMissing")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("userEmailMissing"), + }); // 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.router.navigate(["/login-initiated"]); @@ -158,7 +168,11 @@ export class LoginViaAuthRequestComponent this.email = this.loginEmailService.getEmail(); if (!this.email) { - this.platformUtilsService.showToast("error", null, this.i18nService.t("userEmailMissing")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("userEmailMissing"), + }); // 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.router.navigate(["/login"]); @@ -402,7 +416,11 @@ export class LoginViaAuthRequestComponent // TODO: this should eventually be enforced via deleting this on the server once it is used await this.authRequestService.clearAdminAuthRequest(userId); - this.platformUtilsService.showToast("success", null, this.i18nService.t("loginApproved")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("loginApproved"), + }); // Now that we have a decrypted user key in memory, we can check if we // need to establish trust on the current device diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index 40880b514a..501d753a97 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -24,6 +24,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { @@ -92,8 +93,9 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, protected ssoLoginService: SsoLoginServiceAbstraction, protected webAuthnLoginService: WebAuthnLoginServiceAbstraction, protected registerRouteService: RegisterRouteService, + protected toastService: ToastService, ) { - super(environmentService, i18nService, platformUtilsService); + super(environmentService, i18nService, platformUtilsService, toastService); } async ngOnInit() { @@ -135,7 +137,11 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, //desktop, browser; This should be removed once all clients use reactive forms if (this.formGroup.invalid && showToast) { const errorText = this.getErrorToastMessage(); - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), errorText); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: errorText, + }); return; } @@ -327,11 +333,11 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, return false; } - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccured"), - this.i18nService.t("encryptionKeyMigrationRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccured"), + message: this.i18nService.t("encryptionKeyMigrationRequired"), + }); return true; } diff --git a/libs/angular/src/auth/components/register.component.ts b/libs/angular/src/auth/components/register.component.ts index 366290a79a..60adcba4d9 100644 --- a/libs/angular/src/auth/components/register.component.ts +++ b/libs/angular/src/auth/components/register.component.ts @@ -17,7 +17,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { @@ -97,8 +97,9 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn protected logService: LogService, protected auditService: AuditService, protected dialogService: DialogService, + protected toastService: ToastService, ) { - super(environmentService, i18nService, platformUtilsService); + super(environmentService, i18nService, platformUtilsService, toastService); this.showTerms = !platformUtilsService.isSelfHost(); this.characterMinimumMessage = this.i18nService.t("characterMinimum", this.minimumLength); } @@ -129,11 +130,11 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn } if (this.isInTrialFlow) { if (!this.accountCreated) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("trialAccountCreated"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("trialAccountCreated"), + }); } const loginResponse = await this.logIn(email, masterPassword, this.captchaBypassToken); if (loginResponse.captchaRequired) { @@ -141,11 +142,11 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn } this.createdAccount.emit(this.formGroup.value.email); } else { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("newAccountCreated"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("newAccountCreated"), + }); // 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.router.navigate([this.successRoute], { queryParams: { email: email } }); @@ -210,11 +211,11 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn this.showErrorSummary = true; if (this.formGroup.get("acceptPolicies").hasError("required")) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("acceptPoliciesRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("acceptPoliciesRequired"), + }); return { isValid: false }; } @@ -226,7 +227,11 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn //desktop, browser if (this.formGroup.invalid && showToast) { const errorText = this.getErrorToastMessage(); - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), errorText); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: errorText, + }); return { isValid: false }; } diff --git a/libs/angular/src/auth/components/remove-password.component.ts b/libs/angular/src/auth/components/remove-password.component.ts index ad5027734c..4b8e9cc52f 100644 --- a/libs/angular/src/auth/components/remove-password.component.ts +++ b/libs/angular/src/auth/components/remove-password.component.ts @@ -9,7 +9,7 @@ import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-con import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; @Directive() export class RemovePasswordComponent implements OnInit { @@ -30,6 +30,7 @@ export class RemovePasswordComponent implements OnInit { private keyConnectorService: KeyConnectorService, private organizationApiService: OrganizationApiServiceAbstraction, private dialogService: DialogService, + private toastService: ToastService, ) {} async ngOnInit() { @@ -47,17 +48,21 @@ export class RemovePasswordComponent implements OnInit { try { await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("removedMasterPassword"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("removedMasterPassword"), + }); await this.keyConnectorService.removeConvertAccountRequired(); // 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.router.navigate([""]); } catch (e) { - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), e.message); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: e.message, + }); } }; @@ -76,13 +81,21 @@ export class RemovePasswordComponent implements OnInit { this.leaving = true; this.actionPromise = this.organizationApiService.leave(this.organization.id); await this.actionPromise; - this.platformUtilsService.showToast("success", null, this.i18nService.t("leftOrganization")); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("leftOrganization"), + }); await this.keyConnectorService.removeConvertAccountRequired(); // 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.router.navigate([""]); } catch (e) { - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), e); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: e, + }); } }; } diff --git a/libs/angular/src/auth/components/set-password.component.ts b/libs/angular/src/auth/components/set-password.component.ts index f94a31e8d2..e9662c7107 100644 --- a/libs/angular/src/auth/components/set-password.component.ts +++ b/libs/angular/src/auth/components/set-password.component.ts @@ -32,7 +32,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; @@ -74,6 +74,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements dialogService: DialogService, kdfConfigService: KdfConfigService, private encryptService: EncryptService, + protected toastService: ToastService, ) { super( i18nService, @@ -87,6 +88,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements kdfConfigService, masterPasswordService, accountService, + toastService, ); } @@ -137,7 +139,11 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements ) .subscribe({ error: () => { - this.platformUtilsService.showToast("error", null, this.i18nService.t("errorOccurred")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); }, }); } @@ -237,7 +243,11 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements this.router.navigate([this.successRoute]); } } catch { - this.platformUtilsService.showToast("error", null, this.i18nService.t("errorOccurred")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("errorOccurred"), + }); } } diff --git a/libs/angular/src/auth/components/sso.component.spec.ts b/libs/angular/src/auth/components/sso.component.spec.ts index 8584abeeb8..af92c7dd1d 100644 --- a/libs/angular/src/auth/components/sso.component.spec.ts +++ b/libs/angular/src/auth/components/sso.component.spec.ts @@ -28,6 +28,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { SsoComponent } from "./sso.component"; @@ -65,7 +66,7 @@ describe("SsoComponent", () => { let mockSsoLoginService: MockProxy; let mockStateService: MockProxy; - let mockPlatformUtilsService: MockProxy; + let mockToastService: MockProxy; let mockApiService: MockProxy; let mockCryptoFunctionService: MockProxy; let mockEnvironmentService: MockProxy; @@ -75,6 +76,7 @@ describe("SsoComponent", () => { let mockConfigService: MockProxy; let mockMasterPasswordService: FakeMasterPasswordService; let mockAccountService: FakeAccountService; + let mockPlatformUtilsService: MockProxy; // Mock authService.logIn params let code: string; @@ -117,7 +119,7 @@ describe("SsoComponent", () => { mockSsoLoginService = mock(); mockStateService = mock(); - mockPlatformUtilsService = mock(); + mockToastService = mock(); mockApiService = mock(); mockCryptoFunctionService = mock(); mockEnvironmentService = mock(); @@ -127,6 +129,7 @@ describe("SsoComponent", () => { mockConfigService = mock(); mockAccountService = mockAccountServiceWith(userId); mockMasterPasswordService = new FakeMasterPasswordService(); + mockPlatformUtilsService = mock(); // Mock loginStrategyService.logIn params code = "code"; @@ -196,7 +199,7 @@ describe("SsoComponent", () => { { provide: I18nService, useValue: mockI18nService }, { provide: ActivatedRoute, useValue: mockActivatedRoute }, { provide: StateService, useValue: mockStateService }, - { provide: PlatformUtilsService, useValue: mockPlatformUtilsService }, + { provide: ToastService, useValue: mockToastService }, { provide: ApiService, useValue: mockApiService }, { provide: CryptoFunctionService, useValue: mockCryptoFunctionService }, @@ -214,6 +217,7 @@ describe("SsoComponent", () => { { provide: ConfigService, useValue: mockConfigService }, { provide: InternalMasterPasswordServiceAbstraction, useValue: mockMasterPasswordService }, { provide: AccountService, useValue: mockAccountService }, + { provide: PlatformUtilsService, useValue: mockPlatformUtilsService }, ], }); @@ -594,12 +598,12 @@ describe("SsoComponent", () => { expect(mockLogService.error).toHaveBeenCalledTimes(1); expect(mockLogService.error).toHaveBeenCalledWith(error); - expect(mockPlatformUtilsService.showToast).toHaveBeenCalledTimes(1); - expect(mockPlatformUtilsService.showToast).toHaveBeenCalledWith( - "error", - null, - "ssoKeyConnectorError", - ); + expect(mockToastService.showToast).toHaveBeenCalledTimes(1); + expect(mockToastService.showToast).toHaveBeenCalledWith({ + variant: "error", + title: null, + message: "ssoKeyConnectorError", + }); expect(mockRouter.navigate).not.toHaveBeenCalled(); }); diff --git a/libs/angular/src/auth/components/sso.component.ts b/libs/angular/src/auth/components/sso.component.ts index cc105222c2..ac64ae0246 100644 --- a/libs/angular/src/auth/components/sso.component.ts +++ b/libs/angular/src/auth/components/sso.component.ts @@ -26,6 +26,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; @Directive() @@ -71,6 +72,7 @@ export class SsoComponent implements OnInit { protected configService: ConfigService, protected masterPasswordService: InternalMasterPasswordServiceAbstraction, protected accountService: AccountService, + protected toastService: ToastService, ) {} async ngOnInit() { @@ -111,11 +113,11 @@ export class SsoComponent implements OnInit { async submit(returnUri?: string, includeUserIdentifier?: boolean) { if (this.identifier == null || this.identifier === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("ssoValidationFailed"), - this.i18nService.t("ssoIdentifierRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("ssoValidationFailed"), + message: this.i18nService.t("ssoIdentifierRequired"), + }); return; } @@ -382,11 +384,11 @@ export class SsoComponent implements OnInit { // TODO: Key Connector Service should pass this error message to the logout callback instead of displaying here if (e.message === "Key Connector error") { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("ssoKeyConnectorError"), - ); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("ssoKeyConnectorError"), + }); } } diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-email.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-email.component.ts index 5a1231daac..72d7e6a76c 100644 --- a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-email.component.ts +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-email.component.ts @@ -20,6 +20,7 @@ import { TypographyModule, FormFieldModule, AsyncActionsModule, + ToastService, } from "@bitwarden/components"; @Component({ @@ -55,6 +56,7 @@ export class TwoFactorAuthEmailComponent implements OnInit { protected logService: LogService, protected apiService: ApiService, protected appIdService: AppIdService, + private toastService: ToastService, ) {} async ngOnInit(): Promise { @@ -74,11 +76,11 @@ export class TwoFactorAuthEmailComponent implements OnInit { } if ((await this.loginStrategyService.getEmail()) == null) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("sessionTimeout"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("sessionTimeout"), + }); return; } @@ -94,11 +96,11 @@ export class TwoFactorAuthEmailComponent implements OnInit { this.emailPromise = this.apiService.postTwoFactorEmail(request); await this.emailPromise; if (doToast) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail), + }); } } catch (e) { this.logService.error(e); diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-webauthn.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-webauthn.component.ts index 7f0554c1f0..7e9f648691 100644 --- a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-webauthn.component.ts +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-webauthn.component.ts @@ -21,6 +21,7 @@ import { TypographyModule, FormFieldModule, AsyncActionsModule, + ToastService, } from "@bitwarden/components"; @Component({ @@ -56,6 +57,7 @@ export class TwoFactorAuthWebAuthnComponent implements OnInit, OnDestroy { protected environmentService: EnvironmentService, protected twoFactorService: TwoFactorService, protected route: ActivatedRoute, + private toastService: ToastService, ) { this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win); @@ -85,11 +87,11 @@ export class TwoFactorAuthWebAuthnComponent implements OnInit, OnDestroy { this.token.emit(token); }, (error: string) => { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("webauthnCancelOrTimeout"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("webauthnCancelOrTimeout"), + }); }, (info: string) => { if (info === "ready") { diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.spec.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.spec.ts index 489ca5c178..755813a677 100644 --- a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.spec.ts +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.spec.ts @@ -35,7 +35,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { TwoFactorAuthComponent } from "./two-factor-auth.component"; @@ -76,6 +76,7 @@ describe("TwoFactorComponent", () => { let mockMasterPasswordService: FakeMasterPasswordService; let mockAccountService: FakeAccountService; let mockDialogService: MockProxy; + let mockToastService: MockProxy; let mockUserDecryptionOpts: { noMasterPassword: UserDecryptionOptions; @@ -113,6 +114,7 @@ describe("TwoFactorComponent", () => { mockAccountService = mockAccountServiceWith(userId); mockMasterPasswordService = new FakeMasterPasswordService(); mockDialogService = mock(); + mockToastService = mock(); mockUserDecryptionOpts = { noMasterPassword: new UserDecryptionOptions({ @@ -193,6 +195,7 @@ describe("TwoFactorComponent", () => { { provide: InternalMasterPasswordServiceAbstraction, useValue: mockMasterPasswordService }, { provide: AccountService, useValue: mockAccountService }, { provide: DialogService, useValue: mockDialogService }, + { provide: ToastService, useValue: mockToastService }, ], }); diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts index 21aaf119c4..58edeed93e 100644 --- a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth.component.ts @@ -34,6 +34,7 @@ import { ButtonModule, DialogService, FormFieldModule, + ToastService, } from "@bitwarden/components"; import { CaptchaProtectedComponent } from "../captcha-protected.component"; @@ -142,8 +143,9 @@ export class TwoFactorAuthComponent extends CaptchaProtectedComponent implements private accountService: AccountService, private formBuilder: FormBuilder, @Inject(WINDOW) protected win: Window, + protected toastService: ToastService, ) { - super(environmentService, i18nService, platformUtilsService); + super(environmentService, i18nService, platformUtilsService, toastService); } async ngOnInit() { @@ -184,11 +186,11 @@ export class TwoFactorAuthComponent extends CaptchaProtectedComponent implements await this.setupCaptcha(); if (this.token == null || this.token === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("verificationCodeRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("verificationCodeRequired"), + }); return; } @@ -202,11 +204,11 @@ export class TwoFactorAuthComponent extends CaptchaProtectedComponent implements await this.handleLoginResponse(authResult); } catch { this.logService.error("Error submitting two factor token"); - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("invalidVerificationCode"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidVerificationCode"), + }); } } diff --git a/libs/angular/src/auth/components/two-factor.component.ts b/libs/angular/src/auth/components/two-factor.component.ts index 8c849db6c6..eaff9d665f 100644 --- a/libs/angular/src/auth/components/two-factor.component.ts +++ b/libs/angular/src/auth/components/two-factor.component.ts @@ -97,7 +97,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI protected accountService: AccountService, protected toastService: ToastService, ) { - super(environmentService, i18nService, platformUtilsService); + super(environmentService, i18nService, platformUtilsService, toastService); this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win); } @@ -135,7 +135,11 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI this.submit(); }, (error: string) => { - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), error); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: error, + }); }, (info: string) => { if (info === "ready") { @@ -201,11 +205,11 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI await this.setupCaptcha(); if (this.token == null || this.token === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("verificationCodeRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("verificationCodeRequired"), + }); return; } @@ -243,11 +247,11 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI return false; } - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccured"), - this.i18nService.t("encryptionKeyMigrationRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccured"), + message: this.i18nService.t("encryptionKeyMigrationRequired"), + }); return true; } @@ -414,11 +418,11 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI } if ((await this.loginStrategyService.getEmail()) == null) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("sessionTimeout"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("sessionTimeout"), + }); return; } @@ -434,11 +438,11 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI this.emailPromise = this.apiService.postTwoFactorEmail(request); await this.emailPromise; if (doToast) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail), + }); } } catch (e) { this.logService.error(e); diff --git a/libs/angular/src/auth/components/update-password.component.ts b/libs/angular/src/auth/components/update-password.component.ts index 661e50e887..98dd4aeb49 100644 --- a/libs/angular/src/auth/components/update-password.component.ts +++ b/libs/angular/src/auth/components/update-password.component.ts @@ -19,7 +19,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; @@ -50,6 +50,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { kdfConfigService: KdfConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + toastService: ToastService, ) { super( i18nService, @@ -63,6 +64,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { kdfConfigService, masterPasswordService, accountService, + toastService, ); } @@ -77,11 +79,11 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { async setupSubmitActions(): Promise { if (this.currentMasterPassword == null || this.currentMasterPassword === "") { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("masterPasswordRequired"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("masterPasswordRequired"), + }); return false; } @@ -92,7 +94,11 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { try { await this.userVerificationService.verifyUser(secret); } catch (e) { - this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), e.message); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: e.message, + }); return false; } @@ -120,11 +126,11 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent { // eslint-disable-next-line @typescript-eslint/no-floating-promises this.apiService.postPassword(request); - this.platformUtilsService.showToast( - "success", - this.i18nService.t("masterPasswordChanged"), - this.i18nService.t("logBackIn"), - ); + this.toastService.showToast({ + variant: "success", + title: this.i18nService.t("masterPasswordChanged"), + message: this.i18nService.t("logBackIn"), + }); if (this.onSuccessfulChangePassword != null) { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. diff --git a/libs/angular/src/auth/components/update-temp-password.component.ts b/libs/angular/src/auth/components/update-temp-password.component.ts index 4991e2b152..78fb9b625b 100644 --- a/libs/angular/src/auth/components/update-temp-password.component.ts +++ b/libs/angular/src/auth/components/update-temp-password.component.ts @@ -24,7 +24,7 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; @@ -64,6 +64,7 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent imp kdfConfigService: KdfConfigService, accountService: AccountService, masterPasswordService: InternalMasterPasswordServiceAbstraction, + toastService: ToastService, ) { super( i18nService, @@ -77,6 +78,7 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent imp kdfConfigService, masterPasswordService, accountService, + toastService, ); } @@ -176,11 +178,11 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent imp } await this.formPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("updatedMasterPassword"), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("updatedMasterPassword"), + }); const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; await this.masterPasswordService.setForceSetPasswordReason( diff --git a/libs/angular/src/auth/components/user-verification-prompt.component.ts b/libs/angular/src/auth/components/user-verification-prompt.component.ts index d999042722..4b25a7cc0f 100644 --- a/libs/angular/src/auth/components/user-verification-prompt.component.ts +++ b/libs/angular/src/auth/components/user-verification-prompt.component.ts @@ -5,6 +5,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/abstractions/use import { Verification } from "@bitwarden/common/auth/types/verification"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ToastService } from "@bitwarden/components"; import { ModalRef } from "../../components/modal/modal.ref"; @@ -37,6 +38,7 @@ export class UserVerificationPromptComponent { private formBuilder: FormBuilder, private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, + private toastService: ToastService, ) {} get secret() { @@ -56,7 +58,11 @@ export class UserVerificationPromptComponent { this.invalidSecret = false; } catch (e) { this.invalidSecret = true; - this.platformUtilsService.showToast("error", this.i18nService.t("error"), e.message); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("error"), + message: e.message, + }); return; } diff --git a/libs/auth/src/angular/user-verification/user-verification-dialog.component.ts b/libs/auth/src/angular/user-verification/user-verification-dialog.component.ts index f8746b5b24..0c3e6ab71e 100644 --- a/libs/auth/src/angular/user-verification/user-verification-dialog.component.ts +++ b/libs/auth/src/angular/user-verification/user-verification-dialog.component.ts @@ -15,6 +15,7 @@ import { CalloutModule, DialogModule, DialogService, + ToastService, } from "@bitwarden/components"; import { ActiveClientVerificationOption } from "./active-client-verification-option.enum"; @@ -58,6 +59,7 @@ export class UserVerificationDialogComponent { private userVerificationService: UserVerificationService, private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, + private toastService: ToastService, ) {} /** @@ -256,19 +258,27 @@ export class UserVerificationDialogComponent { // Only pin should ever get here, but added this check to be safe. if (this.activeClientVerificationOption === ActiveClientVerificationOption.Pin) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("error"), - this.i18nService.t("invalidPin"), - ); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("error"), + message: this.i18nService.t("invalidPin"), + }); } else { - this.platformUtilsService.showToast("error", null, this.i18nService.t("unexpectedError")); + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("unexpectedError"), + }); } } } catch (e) { // Catch handles OTP and MP verification scenarios as those throw errors on verification failure instead of returning false like PIN and biometrics. this.invalidSecret = true; - this.platformUtilsService.showToast("error", this.i18nService.t("error"), e.message); + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("error"), + message: e.message, + }); return; } };