diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cc8eb66289..80730e8b22 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,7 +4,7 @@ # The following owners will be the default owners for everything in the repo. # Unless a later match takes precedence -@bitwarden/team-leads +* @bitwarden/team-leads-eng ## Secrets Manager team files ## bitwarden_license/bit-web/src/app/secrets-manager @bitwarden/team-secrets-manager-dev @@ -76,3 +76,10 @@ libs/components @bitwarden/team-platform-dev ## Desktop native module ## apps/desktop/desktop_native @bitwarden/team-platform-dev + +## Multiple file owners ## +/apps/web/config +/apps/web/package.json + +## DevOps team files ## +/.github/workflows @bitwarden/dept-devops 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/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 4a7918a81b..185b3b96cb 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -84,6 +84,8 @@ jobs: npm_command: "build:bit:ee" - name: "cloud-euprd" npm_command: "build:bit:euprd" + - name: "cloud-euqa" + npm_command: "build:bit:euqa" steps: - name: Checkout repo diff --git a/.github/workflows/deploy-eu-qa-web.yml b/.github/workflows/deploy-eu-qa-web.yml new file mode 100644 index 0000000000..f4d32f7681 --- /dev/null +++ b/.github/workflows/deploy-eu-qa-web.yml @@ -0,0 +1,60 @@ +--- +name: Deploy Web to EU-QA Cloud + +on: + workflow_dispatch: + inputs: + tag: + description: "Branch name to deploy (examples: 'master', 'feature/sm')" + required: true + type: string + default: master + +jobs: + azure-deploy: + name: Deploy to Azure + runs-on: ubuntu-22.04 + env: + _WEB_ARTIFACT: "web-*-cloud-euqa.zip" + steps: + - name: Login to Azure - EU Subscription + uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.6 + with: + creds: ${{ secrets.AZURE_KV_EU_QA_SERVICE_PRINCIPAL }} + + - name: Retrieve Storage Account connection string + id: retrieve-secrets + uses: bitwarden/gh-actions/get-keyvault-secrets@37ffa14164a7308bc273829edfe75c97cd562375 + with: + keyvault: webvaulteu-westeurope-qa + secrets: "sa-bitwarden-web-vault-dev-key-temp" + + - name: Download latest cloud asset + uses: bitwarden/gh-actions/download-artifacts@37ffa14164a7308bc273829edfe75c97cd562375 + with: + workflow: build-web.yml + path: apps/web + workflow_conclusion: success + branch: ${{ github.event.inputs.tag }} + artifacts: ${{ env._WEB_ARTIFACT }} + + - name: Unzip build asset + working-directory: apps/web + run: unzip ${{ env._WEB_ARTIFACT }} + + - name: Empty container in Storage Account + run: | + az storage blob delete-batch \ + --source '$web' \ + --pattern '*' \ + --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" + + - name: Deploy to Azure Storage Account + working-directory: apps/web + run: | + az storage blob upload-batch \ + --source "./build" \ + --destination '$web' \ + --connection-string "${{ steps.retrieve-secrets.outputs.sa-bitwarden-web-vault-dev-key-temp }}" \ + --overwrite \ + --no-progress diff --git a/.github/workflows/deploy-non-prod-web.yml b/.github/workflows/deploy-non-prod-web.yml index d041369d84..c215ed3546 100644 --- a/.github/workflows/deploy-non-prod-web.yml +++ b/.github/workflows/deploy-non-prod-web.yml @@ -12,8 +12,6 @@ on: type: choice options: - QA - - POC2 - - eudevtest jobs: diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index d7d37a71e7..0bc9fc5bac 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -101,6 +101,7 @@ const preview: Preview = { }, options: { storySort: { + method: "alphabetical", order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"], }, }, 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" 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/config/eudevtest.json b/apps/web/config/eudevtest.json deleted file mode 100644 index faaba2177c..0000000000 --- a/apps/web/config/eudevtest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "urls": { - "icons": "https://icons.eudevtest.bitwarden.pw", - "notifications": "https://notifications.eudevtest.bitwarden.pw", - "scim": "https://scim.eudevtest.bitwarden.pw" - }, - "flags": { - "secretsManager": true, - "showPasswordless": true - } -} diff --git a/apps/web/config/euprd.json b/apps/web/config/euprd.json index 576b5b4cfa..4218593ede 100644 --- a/apps/web/config/euprd.json +++ b/apps/web/config/euprd.json @@ -1,6 +1,6 @@ { "urls": { - "icons": "https://icons.bitwarden.net", + "icons": "https://icons.bitwarden.eu", "notifications": "https://notifications.bitwarden.eu", "scim": "https://scim.bitwarden.eu" }, diff --git a/apps/web/config/euqa.json b/apps/web/config/euqa.json new file mode 100644 index 0000000000..496b52065c --- /dev/null +++ b/apps/web/config/euqa.json @@ -0,0 +1,11 @@ +{ + "urls": { + "icons": "https://icons.euqa.bitwarden.pw", + "notifications": "https://notifications.euqa.bitwarden.pw", + "scim": "https://scim.euqa.bitwarden.pw" + }, + "flags": { + "secretsManager": true, + "showPasswordless": true + } +} diff --git a/apps/web/package.json b/apps/web/package.json index 5b5f25d437..4be9ecc941 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -11,7 +11,7 @@ "build:bit:dev:watch": "cross-env ENV=development npm run build:bit:watch", "build:bit:qa": "cross-env NODE_ENV=production ENV=qa npm run build:bit", "build:bit:euprd": "cross-env NODE_ENV=production ENV=euprd npm run build:bit", - "build:bit:eudevtest": "cross-env NODE_ENV=production ENV=eudevtest npm run build:bit", + "build:bit:euqa": "cross-env NODE_ENV=production ENV=euqa npm run build:bit", "build:bit:cloud": "cross-env NODE_ENV=production ENV=cloud npm run build:bit", "build:oss:selfhost:watch": "cross-env ENV=selfhosted npm run build:oss:watch", "build:bit:selfhost:watch": "cross-env ENV=selfhosted npm run build:bit:watch", 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 781e19d67b..bebf382a16 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 cf9a43915a..588c3a156e 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"; @@ -109,7 +110,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. @@ -234,6 +234,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/app/vault/components/collection-dialog/collection-dialog.component.html b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html index 785afc0e95..e39dcb12ef 100644 --- a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html +++ b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.html @@ -22,6 +22,19 @@ + + {{ "organization" | i18n }} + + + + + + {{ "externalId" | i18n }} diff --git a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts index ac3c62a5b8..74b7d0fdd3 100644 --- a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts +++ b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts @@ -1,7 +1,16 @@ import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; import { Component, Inject, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; -import { combineLatest, of, shareReplay, Subject, switchMap, takeUntil } from "rxjs"; +import { + combineLatest, + map, + Observable, + of, + shareReplay, + Subject, + switchMap, + takeUntil, +} from "rxjs"; import { DialogServiceAbstraction, SimpleDialogType } from "@bitwarden/angular/services/dialog"; import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service"; @@ -10,6 +19,8 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; 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 { CollectionResponse } from "@bitwarden/common/vault/models/response/collection.response"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; import { BitValidators } from "@bitwarden/components"; @@ -35,9 +46,16 @@ export interface CollectionDialogParams { organizationId: string; initialTab?: CollectionDialogTabType; parentCollectionId?: string; + showOrgSelector?: boolean; + collectionIds?: string[]; } -export enum CollectionDialogResult { +export interface CollectionDialogResult { + action: CollectionDialogAction; + collection: CollectionResponse; +} + +export enum CollectionDialogAction { Saved = "saved", Canceled = "canceled", Deleted = "deleted", @@ -48,6 +66,7 @@ export enum CollectionDialogResult { }) export class CollectionDialogComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); + protected organizations$: Observable; protected tabIndex: CollectionDialogTabType; protected loading = true; @@ -56,11 +75,13 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { protected nestOptions: CollectionView[] = []; protected accessItems: AccessItemView[] = []; protected deletedParentName: string | undefined; + protected showOrgSelector = false; protected formGroup = this.formBuilder.group({ name: ["", [Validators.required, BitValidators.forbiddenCharacters(["/"])]], externalId: "", parent: undefined as string | undefined, access: [[] as AccessItemValue[]], + selectedOrg: "", }); protected PermissionMode = PermissionMode; @@ -79,8 +100,31 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.tabIndex = params.initialTab ?? CollectionDialogTabType.Info; } - ngOnInit() { - const organization$ = of(this.organizationService.get(this.params.organizationId)).pipe( + async ngOnInit() { + // Opened from the individual vault + if (this.params.showOrgSelector) { + this.showOrgSelector = true; + this.formGroup.controls.selectedOrg.valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe((id) => this.loadOrg(id, this.params.collectionIds)); + this.organizations$ = this.organizationService.organizations$.pipe( + map((orgs) => + orgs + .filter((o) => o.canCreateNewCollections) + .sort(Utils.getSortFunction(this.i18nService, "name")) + ) + ); + // patchValue will trigger a call to loadOrg() in this case, so no need to call it again here + this.formGroup.patchValue({ selectedOrg: this.params.organizationId }); + } else { + // Opened from the org vault + this.formGroup.patchValue({ selectedOrg: this.params.organizationId }); + this.loadOrg(this.params.organizationId, this.params.collectionIds); + } + } + + async loadOrg(orgId: string, collectionIds: string[]) { + const organization$ = of(this.organizationService.get(orgId)).pipe( shareReplay({ refCount: true, bufferSize: 1 }) ); const groups$ = organization$.pipe( @@ -89,20 +133,19 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { return of([] as GroupView[]); } - return this.groupService.getAll(this.params.organizationId); + return this.groupService.getAll(orgId); }) ); - combineLatest({ organization: organization$, - collections: this.collectionService.getAll(this.params.organizationId), + collections: this.collectionService.getAll(orgId), collectionDetails: this.params.collectionId - ? this.collectionService.get(this.params.organizationId, this.params.collectionId) + ? this.collectionService.get(orgId, this.params.collectionId) : of(null), groups: groups$, - users: this.organizationUserService.getAllUsers(this.params.organizationId), + users: this.organizationUserService.getAllUsers(orgId), }) - .pipe(takeUntil(this.destroy$)) + .pipe(takeUntil(this.formGroup.controls.selectedOrg.valueChanges), takeUntil(this.destroy$)) .subscribe(({ organization, collections, collectionDetails, groups, users }) => { this.organization = organization; this.accessItems = [].concat( @@ -110,6 +153,10 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { users.data.map(mapUserToAccessItemView) ); + if (collectionIds) { + collections = collections.filter((c) => collectionIds.includes(c.id)); + } + if (this.params.collectionId) { this.collection = collections.find((c) => c.id === this.collectionId); this.nestOptions = collections.filter((c) => c.id !== this.collectionId); @@ -149,7 +196,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { } protected async cancel() { - this.close(CollectionDialogResult.Canceled); + this.close(CollectionDialogAction.Canceled); } protected submit = async () => { @@ -168,7 +215,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { const collectionView = new CollectionAdminView(); collectionView.id = this.params.collectionId; - collectionView.organizationId = this.params.organizationId; + collectionView.organizationId = this.formGroup.controls.selectedOrg.value; collectionView.externalId = this.formGroup.controls.externalId.value; collectionView.groups = this.formGroup.controls.access.value .filter((v) => v.type === AccessItemType.Group) @@ -184,7 +231,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { collectionView.name = this.formGroup.controls.name.value; } - await this.collectionService.save(collectionView); + const savedCollection = await this.collectionService.save(collectionView); this.platformUtilsService.showToast( "success", @@ -195,7 +242,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { ) ); - this.close(CollectionDialogResult.Saved); + this.close(CollectionDialogAction.Saved, savedCollection); }; protected delete = async () => { @@ -217,7 +264,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.i18nService.t("deletedCollectionId", this.collection?.name) ); - this.close(CollectionDialogResult.Deleted); + this.close(CollectionDialogAction.Deleted); }; ngOnDestroy(): void { @@ -225,8 +272,8 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.destroy$.complete(); } - private close(result: CollectionDialogResult) { - this.dialogRef.close(result); + private close(action: CollectionDialogAction, collection?: CollectionResponse) { + this.dialogRef.close({ action, collection } as CollectionDialogResult); } } diff --git a/apps/web/src/app/vault/core/collection-admin.service.ts b/apps/web/src/app/vault/core/collection-admin.service.ts index efeb3817ea..08e94e58bd 100644 --- a/apps/web/src/app/vault/core/collection-admin.service.ts +++ b/apps/web/src/app/vault/core/collection-admin.service.ts @@ -46,7 +46,7 @@ export class CollectionAdminService { return view; } - async save(collection: CollectionAdminView): Promise { + async save(collection: CollectionAdminView): Promise { const request = await this.encrypt(collection); let response: CollectionResponse; @@ -61,9 +61,7 @@ export class CollectionAdminService { ); } - // TODO: Implement upsert when in PS-1083: Collection Service refactors - // await this.collectionService.upsert(data); - return; + return response; } async delete(organizationId: string, collectionId: string): Promise { diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/components/vault-filter.component.ts b/apps/web/src/app/vault/individual-vault/vault-filter/components/vault-filter.component.ts index 0cce8df38b..084573446f 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/components/vault-filter.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/components/vault-filter.component.ts @@ -32,7 +32,6 @@ import { OrganizationOptionsComponent } from "./organization-options.component"; export class VaultFilterComponent implements OnInit, OnDestroy { filters?: VaultFilterList; @Input() activeFilter: VaultFilter = new VaultFilter(); - @Output() onAddFolder = new EventEmitter(); @Output() onEditFolder = new EventEmitter(); @Input() searchText = ""; @@ -142,10 +141,6 @@ export class VaultFilterComponent implements OnInit, OnDestroy { filter.selectedCollectionNode = collectionNode; }; - addFolder = async (): Promise => { - this.onAddFolder.emit(); - }; - editFolder = async (folder: FolderFilter): Promise => { this.onEditFolder.emit(folder); }; @@ -249,10 +244,6 @@ export class VaultFilterComponent implements OnInit, OnDestroy { text: "editFolder", action: this.editFolder, }, - add: { - text: "Add Folder", - action: this.addFolder, - }, }; return folderFilterSection; } diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/shared/components/vault-filter-section.component.html b/apps/web/src/app/vault/individual-vault/vault-filter/shared/components/vault-filter-section.component.html index b26b827274..bcd151193a 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/shared/components/vault-filter-section.component.html +++ b/apps/web/src/app/vault/individual-vault/vault-filter/shared/components/vault-filter-section.component.html @@ -34,16 +34,6 @@

 {{ headerNode.node.name | i18n }}

- -