From 33dcddc714836daeb1236a9ebddd65e543a2ebe8 Mon Sep 17 00:00:00 2001 From: Nick Krantz Date: Mon, 23 Sep 2024 12:55:30 -0500 Subject: [PATCH] add `addCipherV2` method in the admin console vault --- .../app/vault/org-vault/vault.component.ts | 68 +++++++++++++++++-- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts index fce33a972bf..18ce159b636 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -41,16 +41,17 @@ import { EventCollectionService } from "@bitwarden/common/abstractions/event/eve import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { EventType } from "@bitwarden/common/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; 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"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/platform/sync"; -import { OrganizationId } from "@bitwarden/common/types/guid"; +import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; @@ -61,7 +62,11 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; import { ServiceUtils } from "@bitwarden/common/vault/service-utils"; import { DialogService, Icons, NoItemsModule, ToastService } from "@bitwarden/components"; -import { CollectionAssignmentResult, PasswordRepromptService } from "@bitwarden/vault"; +import { + CipherFormConfigService, + CollectionAssignmentResult, + PasswordRepromptService, +} from "@bitwarden/vault"; import { GroupService, GroupView } from "../../admin-console/organizations/core"; import { openEntityEventsDialog } from "../../admin-console/organizations/manage/entity-events.component"; @@ -78,6 +83,11 @@ import { VaultItemEvent } from "../components/vault-items/vault-item-event"; import { VaultItemsModule } from "../components/vault-items/vault-items.module"; import { CollectionAdminService } from "../core/collection-admin.service"; import { CollectionAdminView } from "../core/views/collection-admin.view"; +import { + AddEditCipherDialogCloseResult, + AddEditCipherDialogResult, + openAddEditCipherDialog, +} from "../individual-vault/add-edit-v2.component"; import { BulkDeleteDialogResult, openBulkDeleteDialog, @@ -108,8 +118,8 @@ import { } from "./bulk-collections-dialog"; import { CollectionAccessRestrictedComponent } from "./collection-access-restricted.component"; import { openOrgVaultCollectionsDialog } from "./collections.component"; +import { AdminConsoleCipherFormConfigService } from "./services/admin-console-cipher-form-config.service"; import { VaultFilterModule } from "./vault-filter/vault-filter.module"; - const BroadcasterSubscriptionId = "OrgVaultComponent"; const SearchTextDebounceInterval = 200; @@ -131,7 +141,11 @@ enum AddAccessStatusType { NoItemsModule, ViewComponent, ], - providers: [RoutedVaultFilterService, RoutedVaultFilterBridgeService], + providers: [ + RoutedVaultFilterService, + RoutedVaultFilterBridgeService, + { provide: CipherFormConfigService, useClass: AdminConsoleCipherFormConfigService }, + ], }) export class VaultComponent implements OnInit, OnDestroy { protected Unassigned = Unassigned; @@ -178,6 +192,7 @@ export class VaultComponent implements OnInit, OnDestroy { private refresh$ = new BehaviorSubject(null); private destroy$ = new Subject(); protected addAccessStatus$ = new BehaviorSubject(0); + private extensionRefreshEnabled: boolean; constructor( private route: ActivatedRoute, @@ -208,10 +223,15 @@ export class VaultComponent implements OnInit, OnDestroy { private collectionService: CollectionService, private organizationUserApiService: OrganizationUserApiService, private toastService: ToastService, - private accountService: AccountService, + private configService: ConfigService, + private cipherFormConfigService: CipherFormConfigService, ) {} async ngOnInit() { + this.extensionRefreshEnabled = await this.configService.getFeatureFlag( + FeatureFlag.ExtensionRefresh, + ); + this.trashCleanupWarning = this.i18nService.t( this.platformUtilsService.isSelfHost() ? "trashCleanupWarningSelfHosted" @@ -764,6 +784,10 @@ export class VaultComponent implements OnInit, OnDestroy { } async addCipher(cipherType?: CipherType) { + if (this.extensionRefreshEnabled) { + return this.addCipherV2(cipherType); + } + let collections: CollectionView[] = []; // Admins limited to only adding items to collections they have access to. @@ -778,6 +802,38 @@ export class VaultComponent implements OnInit, OnDestroy { }); } + /** Opens the Add/Edit Dialog. Only to be used when the BrowserExtension feature flag is active */ + async addCipherV2(cipherType?: CipherType) { + const cipherFormConfig = await this.cipherFormConfigService.buildConfig( + "add", + null, + cipherType, + ); + + cipherFormConfig.initialValues = { + organizationId: this.organization.id as OrganizationId, + collectionIds: this.collections.map((c) => c.id as CollectionId), + }; + + // Open the dialog. + const dialogRef = openAddEditCipherDialog(this.dialogService, { + data: cipherFormConfig, + }); + + // Wait for the dialog to close. + const result: AddEditCipherDialogCloseResult = await lastValueFrom(dialogRef.closed); + + // Refresh the vault to show the new cipher. + if (result?.action === AddEditCipherDialogResult.Added) { + this.refresh(); + this.go({ itemId: result.id, action: "view" }); + return; + } + + // If the dialog was closed by any other action navigate back to the vault. + this.go({ cipherId: null, itemId: null, action: null }); + } + async editCipher( cipher: CipherView, additionalComponentParameters?: (comp: AddEditComponent) => void,