From a73525a80c56c0ed1d6bdc0560446bc5cee4f725 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 28 Jun 2023 15:02:22 +0200 Subject: [PATCH 1/2] [PM-2135] [BEEEP] Refactor and refresh web user verification components (#5377) * [PM-2135] feat: create new user-verification module * [PM-2136] feat: add ability to remove form field bottom margin (cherry picked from commit 05925ff77ed47f3865c2aecade8271390d9e2fa6) * [PM-2135] feat: refactor user-verification component * [PM-2135] feat: refactor user-verification-prompt * [PM-2135] feat: use form validation in prompt * [PM-2135] feat: change autofocus target * [PM-2135] chore: clean up old code * [PM-2135] feat: allow user verification to show invalid password error * [PM-2135] feat: hack mark as touched to get error to display * [PM-2135] chore: move to auth * [PM-2135] fix: hardcoded dialog buttons * [PM-2135] feat: add onDestroy handler * [PM-2135] fix: remove unecessary directive input * [PM-2135] feat: add password toggle * [PM-2135] chore: add hack comment * [PM-2135] chore: move services to auth folder and rename * [PM-2135] fix: show correct error messages * [PM-2135] fix: re-add non-existant files to whitelist I honestly don't know why the linter is complaining about this * Fix capital letters whitelist * [PM-2135] chore: remove rows that were mistakenly added during merge from master * [PM-2135] chore: remove rows that were mistakenly added during merge from master * [PM-2135] feat: disable built-in browser validations * Revert "[PM-2135] feat: disable built-in browser validations" This reverts commit 969f75822a046a731dc70ac1d3bc2f6089a32337. --------- Co-authored-by: Thomas Rittson --- .github/whitelist-capital-letters.txt | 3 - .../browser/src/background/main.background.ts | 4 +- .../src/popup/services/services.module.ts | 2 +- .../tools/popup/settings/export.component.ts | 2 +- .../src/app/tools/export/export.component.ts | 2 +- .../delete-organization-dialog.component.ts | 4 +- .../import-export/org-export.component.ts | 5 +- .../enroll-master-password-reset.component.ts | 2 +- .../users/organization-user.module.ts | 2 +- .../deauthorize-sessions.component.ts | 2 +- .../two-factor-authenticator.component.ts | 2 +- .../settings/two-factor-base.component.ts | 2 +- .../auth/settings/two-factor-duo.component.ts | 2 +- .../settings/two-factor-email.component.ts | 2 +- .../settings/two-factor-verify.component.ts | 2 +- .../settings/two-factor-webauthn.component.ts | 2 +- .../settings/two-factor-yubikey.component.ts | 2 +- .../components/user-verification/index.ts | 2 +- .../user-verification-prompt.component.html | 20 ++++++ .../user-verification-prompt.component.ts | 60 ++++++++++++++++ .../user-verification.component.html | 41 +++++++++++ .../user-verification.component.ts | 0 .../user-verification.module.ts | 5 +- .../src/app/auth/update-password.component.ts | 2 +- .../billing-sync-api-key.component.ts | 2 +- .../organization-billing.module.ts | 2 +- .../web/src/app/settings/api-key.component.ts | 2 +- .../src/app/settings/purge-vault.component.ts | 2 +- .../user-verification-prompt.component.html | 26 ------- .../user-verification-prompt.component.ts | 8 --- .../user-verification.component.html | 46 ------------- .../src/app/shared/loose-components.module.ts | 3 +- .../tools/import-export/export.component.ts | 12 ++-- apps/web/src/locales/en/messages.json | 6 ++ .../access/access-tokens.component.ts | 9 ++- .../settings/porting/sm-export.component.ts | 13 ++-- .../components/update-password.component.ts | 2 +- .../update-temp-password.component.ts | 2 +- .../user-verification-prompt.component.ts | 46 +++++++++---- .../components/user-verification.component.ts | 69 +++++++++++++++---- .../src/services/jslib-services.module.ts | 4 +- .../export/components/export.component.ts | 2 +- ...r-verification-api.service.abstraction.ts} | 2 +- .../user-verification.service.abstraction.ts} | 4 +- .../src/auth/services/account-api.service.ts | 2 +- .../user-verification-api.service.ts | 2 +- .../user-verification.service.ts | 4 +- .../src/form-field/form-field.component.ts | 19 ++++- 48 files changed, 288 insertions(+), 173 deletions(-) rename apps/web/src/app/{ => auth}/shared/components/user-verification/index.ts (100%) create mode 100644 apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.html create mode 100644 apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts create mode 100644 apps/web/src/app/auth/shared/components/user-verification/user-verification.component.html rename apps/web/src/app/{ => auth}/shared/components/user-verification/user-verification.component.ts (100%) rename apps/web/src/app/{ => auth}/shared/components/user-verification/user-verification.module.ts (68%) delete mode 100644 apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html delete mode 100644 apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts delete mode 100644 apps/web/src/app/shared/components/user-verification/user-verification.component.html rename libs/common/src/{abstractions/userVerification/userVerification-api.service.abstraction.ts => auth/abstractions/user-verification/user-verification-api.service.abstraction.ts} (69%) rename libs/common/src/{abstractions/userVerification/userVerification.service.abstraction.ts => auth/abstractions/user-verification/user-verification.service.abstraction.ts} (66%) diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 471602a09b..fd03af5f08 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -4,7 +4,6 @@ ./apps/browser/src/safari/desktop/Base.lproj ./apps/browser/src/services/vaultTimeout ./apps/browser/store/windows/Assets -./libs/common/src/abstractions/userVerification ./libs/common/src/abstractions/vaultTimeout ./libs/common/src/services/vaultTimeout ./bitwarden_license/README.md @@ -26,8 +25,6 @@ ./libs/common/src/misc/linkedFieldOption.decorator.ts ./libs/common/src/misc/serviceUtils.ts ./libs/common/src/misc/serviceUtils.spec.ts -./libs/common/src/abstractions/userVerification/userVerification.service.abstraction.ts -./libs/common/src/abstractions/userVerification/userVerification-api.service.abstraction.ts ./libs/common/src/abstractions/vaultTimeout/vaultTimeoutSettings.service.ts ./libs/common/src/abstractions/vaultTimeout/vaultTimeout.service.ts ./libs/common/src/abstractions/anonymousHub.service.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 0437fa55e0..f816624097 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -7,8 +7,6 @@ import { NotificationsService as NotificationsServiceAbstraction } from "@bitwar import { SearchService as SearchServiceAbstraction } from "@bitwarden/common/abstractions/search.service"; import { SettingsService as SettingsServiceAbstraction } from "@bitwarden/common/abstractions/settings.service"; import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/abstractions/totp.service"; -import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification-api.service.abstraction"; -import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { InternalOrganizationService as InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -21,6 +19,8 @@ import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/ab import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction"; +import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; import { TokenService } from "@bitwarden/common/auth/services/token.service"; diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 1b3244064b..7b26980098 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -15,7 +15,6 @@ import { NotificationsService } from "@bitwarden/common/abstractions/notificatio import { SearchService as SearchServiceAbstraction } from "@bitwarden/common/abstractions/search.service"; import { SettingsService } from "@bitwarden/common/abstractions/settings.service"; import { TotpService } from "@bitwarden/common/abstractions/totp.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -31,6 +30,7 @@ import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-con import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { LoginService } from "@bitwarden/common/auth/services/login.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; diff --git a/apps/browser/src/tools/popup/settings/export.component.ts b/apps/browser/src/tools/popup/settings/export.component.ts index c56b5c1f25..e21f3b9bd4 100644 --- a/apps/browser/src/tools/popup/settings/export.component.ts +++ b/apps/browser/src/tools/popup/settings/export.component.ts @@ -5,8 +5,8 @@ import { Router } from "@angular/router"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; diff --git a/apps/desktop/src/app/tools/export/export.component.ts b/apps/desktop/src/app/tools/export/export.component.ts index 70f74d0ecd..770c3bf5f5 100644 --- a/apps/desktop/src/app/tools/export/export.component.ts +++ b/apps/desktop/src/app/tools/export/export.component.ts @@ -6,8 +6,8 @@ import { UntypedFormBuilder } from "@angular/forms"; import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog"; import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; diff --git a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts index 646b542aa1..df436e687e 100644 --- a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts @@ -4,10 +4,10 @@ import { FormBuilder, FormControl, Validators } from "@angular/forms"; import { combineLatest, Subject, takeUntil } from "rxjs"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; 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"; @@ -17,7 +17,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { UserVerificationModule } from "../../../../shared/components/user-verification"; +import { UserVerificationModule } from "../../../../auth/shared/components/user-verification"; import { SharedModule } from "../../../../shared/shared.module"; class CountBasedLocalizationKey { diff --git a/apps/web/src/app/admin-console/organizations/tools/import-export/org-export.component.ts b/apps/web/src/app/admin-console/organizations/tools/import-export/org-export.component.ts index 56fffd8260..35d445cb41 100644 --- a/apps/web/src/app/admin-console/organizations/tools/import-export/org-export.component.ts +++ b/apps/web/src/app/admin-console/organizations/tools/import-export/org-export.component.ts @@ -3,10 +3,9 @@ import { UntypedFormBuilder } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { EventType } from "@bitwarden/common/enums"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; @@ -35,7 +34,6 @@ export class OrganizationExportComponent extends ExportComponent { userVerificationService: UserVerificationService, formBuilder: UntypedFormBuilder, fileDownloadService: FileDownloadService, - modalService: ModalService, dialogService: DialogServiceAbstraction ) { super( @@ -49,7 +47,6 @@ export class OrganizationExportComponent extends ExportComponent { userVerificationService, formBuilder, fileDownloadService, - modalService, dialogService ); } diff --git a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts index 68203033ee..882bb78cea 100644 --- a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts +++ b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts @@ -4,9 +4,9 @@ import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; import { ModalConfig } from "@bitwarden/angular/services/modal.service"; import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service"; import { OrganizationUserResetPasswordEnrollmentRequest } from "@bitwarden/common/abstractions/organization-user/requests"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; diff --git a/apps/web/src/app/admin-console/organizations/users/organization-user.module.ts b/apps/web/src/app/admin-console/organizations/users/organization-user.module.ts index 6799ae3ac4..30e2b5abe7 100644 --- a/apps/web/src/app/admin-console/organizations/users/organization-user.module.ts +++ b/apps/web/src/app/admin-console/organizations/users/organization-user.module.ts @@ -1,8 +1,8 @@ import { ScrollingModule } from "@angular/cdk/scrolling"; import { NgModule } from "@angular/core"; +import { UserVerificationModule } from "../../../auth/shared/components/user-verification"; import { LooseComponentsModule, SharedModule } from "../../../shared"; -import { UserVerificationModule } from "../../../shared/components/user-verification"; import { EnrollMasterPasswordReset } from "./enroll-master-password-reset.component"; diff --git a/apps/web/src/app/auth/settings/deauthorize-sessions.component.ts b/apps/web/src/app/auth/settings/deauthorize-sessions.component.ts index fe758024cc..6c64933629 100644 --- a/apps/web/src/app/auth/settings/deauthorize-sessions.component.ts +++ b/apps/web/src/app/auth/settings/deauthorize-sessions.component.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; 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 fadf03b32e..29cc6df156 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 @@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { UpdateTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/update-two-factor-authenticator.request"; import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response"; 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 95257421f8..d60da177a5 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 @@ -2,7 +2,7 @@ import { Directive, EventEmitter, Output } from "@angular/core"; import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; 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 81d6ed859e..354f58f7f2 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 @@ -2,7 +2,7 @@ import { Component } from "@angular/core"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { UpdateTwoFactorDuoRequest } from "@bitwarden/common/auth/models/request/update-two-factor-duo.request"; import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response"; 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 f0140dd245..8a7976a19e 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 @@ -2,7 +2,7 @@ import { Component } from "@angular/core"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request"; import { UpdateTwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/update-two-factor-email.request"; diff --git a/apps/web/src/app/auth/settings/two-factor-verify.component.ts b/apps/web/src/app/auth/settings/two-factor-verify.component.ts index e460a8cbd6..71a7772c8e 100644 --- a/apps/web/src/app/auth/settings/two-factor-verify.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-verify.component.ts @@ -1,7 +1,7 @@ import { Component, EventEmitter, Input, Output } from "@angular/core"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; 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 8e57e6e152..d528e81a8c 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 @@ -2,7 +2,7 @@ import { Component, NgZone } from "@angular/core"; import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; import { UpdateTwoFactorWebAuthnDeleteRequest } from "@bitwarden/common/auth/models/request/update-two-factor-web-authn-delete.request"; 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 4f6be97813..b9d2bd69f8 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 @@ -2,7 +2,7 @@ import { Component } from "@angular/core"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { UpdateTwoFactorYubioOtpRequest } from "@bitwarden/common/auth/models/request/update-two-factor-yubio-otp.request"; import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response"; diff --git a/apps/web/src/app/shared/components/user-verification/index.ts b/apps/web/src/app/auth/shared/components/user-verification/index.ts similarity index 100% rename from apps/web/src/app/shared/components/user-verification/index.ts rename to apps/web/src/app/auth/shared/components/user-verification/index.ts index 9fe21e309c..4fde4e67a2 100644 --- a/apps/web/src/app/shared/components/user-verification/index.ts +++ b/apps/web/src/app/auth/shared/components/user-verification/index.ts @@ -1,3 +1,3 @@ export * from "./user-verification.module"; -export * from "./user-verification-prompt.component"; export * from "./user-verification.component"; +export * from "./user-verification-prompt.component"; diff --git a/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.html b/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.html new file mode 100644 index 0000000000..8001b6b0d6 --- /dev/null +++ b/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.html @@ -0,0 +1,20 @@ +
+ + {{ modalTitle | i18n }} + +

{{ confirmDescription | i18n }}

+ +
+ + + + +
+
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 new file mode 100644 index 0000000000..2abacd3e8a --- /dev/null +++ b/apps/web/src/app/auth/shared/components/user-verification/user-verification-prompt.component.ts @@ -0,0 +1,60 @@ +import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; + +import { UserVerificationPromptComponent as BaseUserVerificationPrompt } from "@bitwarden/angular/auth/components/user-verification-prompt.component"; +import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; +import { ModalConfig } from "@bitwarden/angular/services/modal.service"; +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"; + +export interface UserVerificationPromptParams { + confirmDescription: string; + confirmButtonText: string; + modalTitle: string; +} + +@Component({ + templateUrl: "user-verification-prompt.component.html", +}) +export class UserVerificationPromptComponent extends BaseUserVerificationPrompt { + constructor( + @Inject(DIALOG_DATA) data: UserVerificationPromptParams, + private dialogRef: DialogRef, + userVerificationService: UserVerificationService, + formBuilder: FormBuilder, + platformUtilsService: PlatformUtilsService, + i18nService: I18nService + ) { + // TODO: Remove when BaseUserVerificationPrompt has support for CL + const modalConfig: ModalConfig = { data }; + super( + null, + modalConfig, + userVerificationService, + formBuilder, + platformUtilsService, + i18nService + ); + } + + override close(success: boolean) { + this.dialogRef.close(success); + } +} + +/** + * Strongly typed helper to open a UserVerificationPrompt + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param config Configuration for the dialog + */ +export const openUserVerificationPrompt = ( + dialogService: DialogServiceAbstraction, + config: DialogConfig +) => { + return dialogService.open( + UserVerificationPromptComponent, + config + ); +}; diff --git a/apps/web/src/app/auth/shared/components/user-verification/user-verification.component.html b/apps/web/src/app/auth/shared/components/user-verification/user-verification.component.html new file mode 100644 index 0000000000..a15ce41738 --- /dev/null +++ b/apps/web/src/app/auth/shared/components/user-verification/user-verification.component.html @@ -0,0 +1,41 @@ + + + {{ "masterPass" | i18n }} + + + {{ "confirmIdentity" | i18n }} + + + +
+ + + + + {{ "codeSent" | i18n }} + +
+ + + {{ "verificationCode" | i18n }} + + {{ "confirmIdentity" | i18n }} + +
diff --git a/apps/web/src/app/shared/components/user-verification/user-verification.component.ts b/apps/web/src/app/auth/shared/components/user-verification/user-verification.component.ts similarity index 100% rename from apps/web/src/app/shared/components/user-verification/user-verification.component.ts rename to apps/web/src/app/auth/shared/components/user-verification/user-verification.component.ts diff --git a/apps/web/src/app/shared/components/user-verification/user-verification.module.ts b/apps/web/src/app/auth/shared/components/user-verification/user-verification.module.ts similarity index 68% rename from apps/web/src/app/shared/components/user-verification/user-verification.module.ts rename to apps/web/src/app/auth/shared/components/user-verification/user-verification.module.ts index de6b32f7fe..2287b76ae5 100644 --- a/apps/web/src/app/shared/components/user-verification/user-verification.module.ts +++ b/apps/web/src/app/auth/shared/components/user-verification/user-verification.module.ts @@ -1,12 +1,13 @@ import { NgModule } from "@angular/core"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { SharedModule } from "../../shared.module"; +import { SharedModule } from "../../../../shared/shared.module"; import { UserVerificationPromptComponent } from "./user-verification-prompt.component"; import { UserVerificationComponent } from "./user-verification.component"; @NgModule({ - imports: [SharedModule], + imports: [SharedModule, FormsModule, ReactiveFormsModule], declarations: [UserVerificationComponent, UserVerificationPromptComponent], exports: [UserVerificationComponent, UserVerificationPromptComponent], }) diff --git a/apps/web/src/app/auth/update-password.component.ts b/apps/web/src/app/auth/update-password.component.ts index d1d0ea8071..6c8e81fb4b 100644 --- a/apps/web/src/app/auth/update-password.component.ts +++ b/apps/web/src/app/auth/update-password.component.ts @@ -4,8 +4,8 @@ import { Router } from "@angular/router"; import { UpdatePasswordComponent as BaseUpdatePasswordComponent } from "@bitwarden/angular/auth/components/update-password.component"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; diff --git a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.ts b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.ts index 9bbcdf9333..8386747170 100644 --- a/apps/web/src/app/billing/organizations/billing-sync-api-key.component.ts +++ b/apps/web/src/app/billing/organizations/billing-sync-api-key.component.ts @@ -2,10 +2,10 @@ import { Component } from "@angular/core"; import { ModalConfig } from "@bitwarden/angular/services/modal.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationApiKeyType } from "@bitwarden/common/admin-console/enums"; import { OrganizationApiKeyRequest } from "@bitwarden/common/admin-console/models/request/organization-api-key.request"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/apps/web/src/app/billing/organizations/organization-billing.module.ts b/apps/web/src/app/billing/organizations/organization-billing.module.ts index 8d3dbecd7b..590069cd85 100644 --- a/apps/web/src/app/billing/organizations/organization-billing.module.ts +++ b/apps/web/src/app/billing/organizations/organization-billing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from "@angular/core"; +import { UserVerificationModule } from "../../auth/shared/components/user-verification"; import { LooseComponentsModule, SharedModule } from "../../shared"; -import { UserVerificationModule } from "../../shared/components/user-verification"; import { AdjustSubscription } from "./adjust-subscription.component"; import { BillingSyncApiKeyComponent } from "./billing-sync-api-key.component"; diff --git a/apps/web/src/app/settings/api-key.component.ts b/apps/web/src/app/settings/api-key.component.ts index 2360a84e01..bdb74845c4 100644 --- a/apps/web/src/app/settings/api-key.component.ts +++ b/apps/web/src/app/settings/api-key.component.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request"; import { ApiKeyResponse } from "@bitwarden/common/auth/models/response/api-key.response"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; diff --git a/apps/web/src/app/settings/purge-vault.component.ts b/apps/web/src/app/settings/purge-vault.component.ts index 23b7513268..83e8c2a8df 100644 --- a/apps/web/src/app/settings/purge-vault.component.ts +++ b/apps/web/src/app/settings/purge-vault.component.ts @@ -2,7 +2,7 @@ import { Component, Input } from "@angular/core"; import { Router } from "@angular/router"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; 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"; diff --git a/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html b/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html deleted file mode 100644 index 10a137c51e..0000000000 --- a/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.html +++ /dev/null @@ -1,26 +0,0 @@ - diff --git a/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts b/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts deleted file mode 100644 index 4b24b446a8..0000000000 --- a/apps/web/src/app/shared/components/user-verification/user-verification-prompt.component.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Component } from "@angular/core"; - -import { UserVerificationPromptComponent as BaseUserVerificationPrompt } from "@bitwarden/angular/auth/components/user-verification-prompt.component"; - -@Component({ - templateUrl: "user-verification-prompt.component.html", -}) -export class UserVerificationPromptComponent extends BaseUserVerificationPrompt {} diff --git a/apps/web/src/app/shared/components/user-verification/user-verification.component.html b/apps/web/src/app/shared/components/user-verification/user-verification.component.html deleted file mode 100644 index b90c6074d8..0000000000 --- a/apps/web/src/app/shared/components/user-verification/user-verification.component.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - {{ "confirmIdentity" | i18n }} - - -
- - - - - {{ "codeSent" | i18n }} - -
- -
- - - {{ "confirmIdentity" | i18n }} -
-
diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index c17cf5c76b..498f3af6d8 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -43,6 +43,7 @@ import { TwoFactorVerifyComponent } from "../auth/settings/two-factor-verify.com import { TwoFactorWebAuthnComponent } from "../auth/settings/two-factor-webauthn.component"; import { TwoFactorYubiKeyComponent } from "../auth/settings/two-factor-yubikey.component"; import { VerifyEmailComponent } from "../auth/settings/verify-email.component"; +import { UserVerificationModule } from "../auth/shared/components/user-verification"; import { SsoComponent } from "../auth/sso.component"; import { TwoFactorOptionsComponent } from "../auth/two-factor-options.component"; import { TwoFactorComponent } from "../auth/two-factor.component"; @@ -108,7 +109,6 @@ import { AttachmentsComponent as OrgAttachmentsComponent } from "../vault/org-va import { CollectionsComponent as OrgCollectionsComponent } from "../vault/org-vault/collections.component"; import { AccountFingerprintComponent } from "./components/account-fingerprint/account-fingerprint.component"; -import { UserVerificationModule } from "./components/user-verification"; import { SharedModule } from "./shared.module"; // Please do not add to this list of declarations - we should refactor these into modules when doing so makes sense until there are none left. @@ -230,6 +230,7 @@ import { SharedModule } from "./shared.module"; LowKdfComponent, ], exports: [ + UserVerificationModule, PremiumBadgeComponent, AcceptEmergencyComponent, AcceptOrganizationComponent, diff --git a/apps/web/src/app/tools/import-export/export.component.ts b/apps/web/src/app/tools/import-export/export.component.ts index 71c25bbb7c..9d57f83f2a 100644 --- a/apps/web/src/app/tools/import-export/export.component.ts +++ b/apps/web/src/app/tools/import-export/export.component.ts @@ -1,12 +1,12 @@ import { Component } from "@angular/core"; import { UntypedFormBuilder } from "@angular/forms"; +import { firstValueFrom } from "rxjs"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/tools/export/components/export.component"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { EncryptedExportType } from "@bitwarden/common/enums"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; @@ -15,7 +15,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; -import { UserVerificationPromptComponent } from "../../shared/components/user-verification"; +import { openUserVerificationPrompt } from "../../auth/shared/components/user-verification"; @Component({ selector: "app-export", @@ -37,7 +37,6 @@ export class ExportComponent extends BaseExportComponent { userVerificationService: UserVerificationService, formBuilder: UntypedFormBuilder, fileDownloadService: FileDownloadService, - private modalService: ModalService, dialogService: DialogServiceAbstraction ) { super( @@ -101,8 +100,7 @@ export class ExportComponent extends BaseExportComponent { confirmDescription = "encExportKeyWarningDesc"; } - const ref = this.modalService.open(UserVerificationPromptComponent, { - allowMultipleModals: true, + const ref = openUserVerificationPrompt(this.dialogService, { data: { confirmDescription: confirmDescription, confirmButtonText: "exportVault", @@ -114,7 +112,7 @@ export class ExportComponent extends BaseExportComponent { return; } - return ref.onClosedPromise(); + return firstValueFrom(ref.closed); } get isFileEncryptedExport() { diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index f80bccdf60..991daa65de 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -2658,6 +2658,12 @@ "failedLogin2fa": { "message": "Login attempt failed with incorrect two-step login." }, + "incorrectPassword": { + "message": "Incorrect password" + }, + "incorrectCode": { + "message": "Incorrect code" + }, "exportedVault": { "message": "Vault exported" }, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts index 4e088c5a3c..e7e3c17fca 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { combineLatestWith, Observable, startWith, switchMap } from "rxjs"; +import { combineLatestWith, firstValueFrom, Observable, startWith, switchMap } from "rxjs"; import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; 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 { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/shared/components/user-verification"; +import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification"; import { AccessTokenView } from "../models/view/access-token.view"; @@ -75,8 +75,7 @@ export class AccessTokenComponent implements OnInit { } private verifyUser() { - const ref = this.modalService.open(UserVerificationPromptComponent, { - allowMultipleModals: true, + const ref = openUserVerificationPrompt(this.dialogService, { data: { confirmDescription: "revokeAccessTokenDesc", confirmButtonText: "revokeAccessToken", @@ -88,7 +87,7 @@ export class AccessTokenComponent implements OnInit { return; } - return ref.onClosedPromise(); + return firstValueFrom(ref.closed); } private async getAccessTokens(): Promise { diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts index 492207415a..9939e122e9 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts @@ -1,15 +1,15 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; -import { Subject, switchMap, takeUntil } from "rxjs"; +import { firstValueFrom, Subject, switchMap, takeUntil } from "rxjs"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; +import { DialogServiceAbstraction } from "@bitwarden/angular/services/dialog"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.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 { UserVerificationPromptComponent } from "@bitwarden/web-vault/app/shared/components/user-verification"; +import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification"; import { SecretsManagerPortingApiService } from "../services/sm-porting-api.service"; import { SecretsManagerPortingService } from "../services/sm-porting.service"; @@ -42,7 +42,7 @@ export class SecretsManagerExportComponent implements OnInit, OnDestroy { private smPortingService: SecretsManagerPortingService, private fileDownloadService: FileDownloadService, private logService: LogService, - private modalService: ModalService, + private dialogService: DialogServiceAbstraction, private secretsManagerApiService: SecretsManagerPortingApiService ) {} @@ -98,8 +98,7 @@ export class SecretsManagerExportComponent implements OnInit, OnDestroy { } private verifyUser() { - const ref = this.modalService.open(UserVerificationPromptComponent, { - allowMultipleModals: true, + const ref = openUserVerificationPrompt(this.dialogService, { data: { confirmDescription: "exportWarningDesc", confirmButtonText: "exportVault", @@ -111,6 +110,6 @@ export class SecretsManagerExportComponent implements OnInit, OnDestroy { return; } - return ref.onClosedPromise(); + return firstValueFrom(ref.closed); } } diff --git a/libs/angular/src/auth/components/update-password.component.ts b/libs/angular/src/auth/components/update-password.component.ts index 9a6e98156a..c9d3c3a8ec 100644 --- a/libs/angular/src/auth/components/update-password.component.ts +++ b/libs/angular/src/auth/components/update-password.component.ts @@ -2,9 +2,9 @@ import { Directive } from "@angular/core"; import { Router } from "@angular/router"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; 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 34833c3bbf..01128c4ba6 100644 --- a/libs/angular/src/auth/components/update-temp-password.component.ts +++ b/libs/angular/src/auth/components/update-temp-password.component.ts @@ -2,9 +2,9 @@ import { Directive } from "@angular/core"; import { Router } from "@angular/router"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { ForceResetPasswordReason } from "@bitwarden/common/auth/models/domain/force-reset-password-reason"; import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request"; 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 1a10c96cf5..1b0a1dbed8 100644 --- a/libs/angular/src/auth/components/user-verification-prompt.component.ts +++ b/libs/angular/src/auth/components/user-verification-prompt.component.ts @@ -1,9 +1,10 @@ import { Directive } from "@angular/core"; -import { FormBuilder, FormControl } from "@angular/forms"; +import { FormBuilder } from "@angular/forms"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; +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 { Verification } from "@bitwarden/common/types/verification"; import { ModalRef } from "../../components/modal/modal.ref"; import { ModalConfig } from "../../services/modal.service"; @@ -16,7 +17,12 @@ export class UserVerificationPromptComponent { confirmDescription = this.config.data.confirmDescription; confirmButtonText = this.config.data.confirmButtonText; modalTitle = this.config.data.modalTitle; - secret = new FormControl(); + + formGroup = this.formBuilder.group({ + secret: this.formBuilder.control(null), + }); + + protected invalidSecret = false; constructor( private modalRef: ModalRef, @@ -27,19 +33,31 @@ export class UserVerificationPromptComponent { private i18nService: I18nService ) {} - async submit() { - try { - //Incorrect secret will throw an invalid password error. - await this.userVerificationService.verifyUser(this.secret.value); - } catch (e) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("error"), - this.i18nService.t("invalidMasterPassword") - ); + get secret() { + return this.formGroup.controls.secret; + } + + submit = async () => { + this.formGroup.markAllAsTouched(); + + if (this.formGroup.invalid) { return; } - this.modalRef.close(true); + try { + //Incorrect secret will throw an invalid password error. + await this.userVerificationService.verifyUser(this.secret.value); + this.invalidSecret = false; + } catch (e) { + this.invalidSecret = true; + this.platformUtilsService.showToast("error", this.i18nService.t("error"), e.message); + return; + } + + this.close(true); + }; + + close(success: boolean) { + this.modalRef.close(success); } } diff --git a/libs/angular/src/auth/components/user-verification.component.ts b/libs/angular/src/auth/components/user-verification.component.ts index 5f9d62c3dc..9dfed5b924 100644 --- a/libs/angular/src/auth/components/user-verification.component.ts +++ b/libs/angular/src/auth/components/user-verification.component.ts @@ -1,9 +1,11 @@ -import { Directive, OnInit } from "@angular/core"; -import { ControlValueAccessor, FormControl } from "@angular/forms"; +import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; +import { ControlValueAccessor, FormControl, Validators } from "@angular/forms"; +import { Subject, takeUntil } from "rxjs"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Verification } from "@bitwarden/common/types/verification"; @@ -17,29 +19,65 @@ import { Verification } from "@bitwarden/common/types/verification"; selector: "app-user-verification", }) // eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class UserVerificationComponent implements ControlValueAccessor, OnInit { - usesKeyConnector = false; +export class UserVerificationComponent implements ControlValueAccessor, OnInit, OnDestroy { + private _invalidSecret = false; + @Input() + get invalidSecret() { + return this._invalidSecret; + } + set invalidSecret(value: boolean) { + this._invalidSecret = value; + this.invalidSecretChange.emit(value); + + // ISSUE: This is pretty hacky but unfortunately there is no way of knowing if the parent + // control has been marked as touched, see: https://github.com/angular/angular/issues/10887 + // When that functionality has been added we should also look into forwarding reactive form + // controls errors so that we don't need a separate input/output `invalidSecret`. + if (value) { + this.secret.markAsTouched(); + } + this.secret.updateValueAndValidity({ emitEvent: false }); + } + @Output() invalidSecretChange = new EventEmitter(); + + usesKeyConnector = true; disableRequestOTP = false; sentCode = false; - secret = new FormControl(""); + secret = new FormControl("", [ + Validators.required, + () => { + if (this.invalidSecret) { + return { + invalidSecret: { + message: this.usesKeyConnector + ? this.i18nService.t("incorrectCode") + : this.i18nService.t("incorrectPassword"), + }, + }; + } + }, + ]); private onChange: (value: Verification) => void; + private destroy$ = new Subject(); constructor( private keyConnectorService: KeyConnectorService, - private userVerificationService: UserVerificationService + private userVerificationService: UserVerificationService, + private i18nService: I18nService ) {} async ngOnInit() { this.usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector(); this.processChanges(this.secret.value); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - this.secret.valueChanges.subscribe((secret: string) => this.processChanges(secret)); + this.secret.valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe((secret: string) => this.processChanges(secret)); } - async requestOTP() { + requestOTP = async () => { if (this.usesKeyConnector) { this.disableRequestOTP = true; try { @@ -49,7 +87,7 @@ export class UserVerificationComponent implements ControlValueAccessor, OnInit { this.disableRequestOTP = false; } } - } + }; writeValue(obj: any): void { this.secret.setValue(obj); @@ -72,7 +110,14 @@ export class UserVerificationComponent implements ControlValueAccessor, OnInit { } } - private processChanges(secret: string) { + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + + protected processChanges(secret: string) { + this.invalidSecret = false; + if (this.onChange == null) { return; } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 234359a523..08b790c3f2 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -18,8 +18,6 @@ import { OrganizationUserService } from "@bitwarden/common/abstractions/organiza import { SearchService as SearchServiceAbstraction } from "@bitwarden/common/abstractions/search.service"; import { SettingsService as SettingsServiceAbstraction } from "@bitwarden/common/abstractions/settings.service"; import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/abstractions/totp.service"; -import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification-api.service.abstraction"; -import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeout.service"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; @@ -48,6 +46,8 @@ import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarde import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service"; import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction"; +import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AccountApiServiceImplementation } from "@bitwarden/common/auth/services/account-api.service"; import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; diff --git a/libs/angular/src/tools/export/components/export.component.ts b/libs/angular/src/tools/export/components/export.component.ts index d7d3a1fc4c..595a6ebdfd 100644 --- a/libs/angular/src/tools/export/components/export.component.ts +++ b/libs/angular/src/tools/export/components/export.component.ts @@ -3,9 +3,9 @@ import { UntypedFormBuilder, Validators } from "@angular/forms"; import { merge, startWith, Subject, takeUntil } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { EncryptedExportType, EventType } from "@bitwarden/common/enums"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; diff --git a/libs/common/src/abstractions/userVerification/userVerification-api.service.abstraction.ts b/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts similarity index 69% rename from libs/common/src/abstractions/userVerification/userVerification-api.service.abstraction.ts rename to libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts index 78e4099eee..b861ce4471 100644 --- a/libs/common/src/abstractions/userVerification/userVerification-api.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/user-verification/user-verification-api.service.abstraction.ts @@ -1,4 +1,4 @@ -import { VerifyOTPRequest } from "../../auth/models/request/verify-otp.request"; +import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; export abstract class UserVerificationApiServiceAbstraction { postAccountVerifyOTP: (request: VerifyOTPRequest) => Promise; diff --git a/libs/common/src/abstractions/userVerification/userVerification.service.abstraction.ts b/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts similarity index 66% rename from libs/common/src/abstractions/userVerification/userVerification.service.abstraction.ts rename to libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts index dcfd52bf05..09e4063434 100644 --- a/libs/common/src/abstractions/userVerification/userVerification.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/user-verification/user-verification.service.abstraction.ts @@ -1,5 +1,5 @@ -import { SecretVerificationRequest } from "../../auth/models/request/secret-verification.request"; -import { Verification } from "../../types/verification"; +import { Verification } from "../../../types/verification"; +import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; export abstract class UserVerificationService { buildRequest: ( diff --git a/libs/common/src/auth/services/account-api.service.ts b/libs/common/src/auth/services/account-api.service.ts index 05ec1b8453..270ec1a201 100644 --- a/libs/common/src/auth/services/account-api.service.ts +++ b/libs/common/src/auth/services/account-api.service.ts @@ -1,9 +1,9 @@ import { ApiService } from "../../abstractions/api.service"; -import { UserVerificationService } from "../../abstractions/userVerification/userVerification.service.abstraction"; import { LogService } from "../../platform/abstractions/log.service"; import { Verification } from "../../types/verification"; import { AccountApiService } from "../abstractions/account-api.service"; import { InternalAccountService } from "../abstractions/account.service"; +import { UserVerificationService } from "../abstractions/user-verification/user-verification.service.abstraction"; export class AccountApiServiceImplementation implements AccountApiService { constructor( diff --git a/libs/common/src/auth/services/user-verification/user-verification-api.service.ts b/libs/common/src/auth/services/user-verification/user-verification-api.service.ts index 1e0d9b2c57..0f0eb16e92 100644 --- a/libs/common/src/auth/services/user-verification/user-verification-api.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification-api.service.ts @@ -1,5 +1,5 @@ import { ApiService } from "../../../abstractions/api.service"; -import { UserVerificationApiServiceAbstraction } from "../../../abstractions/userVerification/userVerification-api.service.abstraction"; +import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; export class UserVerificationApiService implements UserVerificationApiServiceAbstraction { diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.ts b/libs/common/src/auth/services/user-verification/user-verification.service.ts index 085c6ac572..0be8d3e729 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.ts @@ -1,8 +1,8 @@ -import { UserVerificationApiServiceAbstraction } from "../../../abstractions/userVerification/userVerification-api.service.abstraction"; -import { UserVerificationService as UserVerificationServiceAbstraction } from "../../../abstractions/userVerification/userVerification.service.abstraction"; import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { Verification } from "../../../types/verification"; +import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; +import { UserVerificationService as UserVerificationServiceAbstraction } from "../../abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "../../enums/verification-type"; import { SecretVerificationRequest } from "../../models/request/secret-verification.request"; import { VerifyOTPRequest } from "../../models/request/verify-otp.request"; diff --git a/libs/components/src/form-field/form-field.component.ts b/libs/components/src/form-field/form-field.component.ts index 9553641188..6fcb4090dd 100644 --- a/libs/components/src/form-field/form-field.component.ts +++ b/libs/components/src/form-field/form-field.component.ts @@ -1,8 +1,11 @@ +import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { AfterContentChecked, Component, ContentChild, ContentChildren, + HostBinding, + Input, QueryList, ViewChild, } from "@angular/core"; @@ -17,9 +20,6 @@ import { BitSuffixDirective } from "./suffix.directive"; @Component({ selector: "bit-form-field", templateUrl: "./form-field.component.html", - host: { - class: "tw-mb-6 tw-block", - }, }) export class BitFormFieldComponent implements AfterContentChecked { @ContentChild(BitFormFieldControl) input: BitFormFieldControl; @@ -30,6 +30,19 @@ export class BitFormFieldComponent implements AfterContentChecked { @ContentChildren(BitPrefixDirective) prefixChildren: QueryList; @ContentChildren(BitSuffixDirective) suffixChildren: QueryList; + private _disableMargin = false; + @Input() set disableMargin(value: boolean | "") { + this._disableMargin = coerceBooleanProperty(value); + } + get disableMargin() { + return this._disableMargin; + } + + @HostBinding("class") + get classList() { + return ["tw-block"].concat(this.disableMargin ? [] : ["tw-mb-6"]); + } + ngAfterContentChecked(): void { if (this.error) { this.input.ariaDescribedBy = this.error.id; From a1c4460068cf9a8a9eb354762abe712eab963ae0 Mon Sep 17 00:00:00 2001 From: ike-kottlowski <137194738+ike-kottlowski@users.noreply.github.com> Date: Wed, 28 Jun 2023 07:11:48 -0700 Subject: [PATCH 2/2] [PM-270] fixed case in EN locale for browser (#5670) --- apps/browser/src/_locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 27c985453e..f23815200a 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -952,7 +952,7 @@ "message": "Server URL" }, "apiUrl": { - "message": "API Server URL" + "message": "API server URL" }, "webVaultUrl": { "message": "Web vault server URL"