From bdf91e24c6f537880abdc31f087577ad1627e530 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Fri, 4 Oct 2024 12:11:03 -0700 Subject: [PATCH] [PM-13177] Fix Unassigned cipher collection assignment in AC (#11419) * [PM-13177] Add saveCollectionsWithServerAdmin to CipherService * [PM-13177] Introduce isSingleCipherAdmin flag to AssignCollections component --- .../src/app/vault/org-vault/vault.component.ts | 2 ++ .../src/vault/abstractions/cipher.service.ts | 7 +++++++ libs/common/src/vault/services/cipher.service.ts | 5 +++++ .../components/assign-collections.component.ts | 15 ++++++++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) 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 1eea053d1f02..a52530dde1a0 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -1249,6 +1249,8 @@ export class VaultComponent implements OnInit, OnDestroy { organizationId: this.organization?.id as OrganizationId, availableCollections, activeCollection: this.activeFilter?.selectedCollectionNode?.node, + isSingleCipherAdmin: + items.length === 1 && (this.organization?.canEditAllCiphers || items[0].isUnassigned), }, }); diff --git a/libs/common/src/vault/abstractions/cipher.service.ts b/libs/common/src/vault/abstractions/cipher.service.ts index 061bd5cedb51..e82c07653cd0 100644 --- a/libs/common/src/vault/abstractions/cipher.service.ts +++ b/libs/common/src/vault/abstractions/cipher.service.ts @@ -113,6 +113,13 @@ export abstract class CipherService implements UserKeyRotationDataProvider Promise; + + /** + * Save the collections for a cipher with the server as an admin. + * Used for Unassigned ciphers or when the user only has admin access to the cipher (not assigned normally). + * @param cipher + */ + saveCollectionsWithServerAdmin: (cipher: Cipher) => Promise; /** * Bulk update collections for many ciphers with the server * @param orgId diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index 9761387284f0..a06ca4d793d5 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -858,6 +858,11 @@ export class CipherService implements CipherServiceAbstraction { return new Cipher(updated[cipher.id as CipherId], cipher.localData); } + async saveCollectionsWithServerAdmin(cipher: Cipher): Promise { + const request = new CipherCollectionsRequest(cipher.collectionIds); + await this.apiService.putCipherCollectionsAdmin(cipher.id, request); + } + /** * Bulk update collections for many ciphers with the server * @param orgId diff --git a/libs/vault/src/components/assign-collections.component.ts b/libs/vault/src/components/assign-collections.component.ts index db4d61691c96..884a79bf1d07 100644 --- a/libs/vault/src/components/assign-collections.component.ts +++ b/libs/vault/src/components/assign-collections.component.ts @@ -64,6 +64,15 @@ export interface CollectionAssignmentParams { * removed from the ciphers upon submission. */ activeCollection?: CollectionView; + + /** + * Flag indicating if the user is performing the action as an admin on a SINGLE cipher. When true, + * the `/admin` endpoint will be used to update the cipher's collections. Required when updating + * ciphers an Admin does not normally have access to or for Unassigned ciphers. + * + * The bulk method already handles admin actions internally. + */ + isSingleCipherAdmin?: boolean; } export enum CollectionAssignmentResult { @@ -463,6 +472,10 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI const { collections } = this.formGroup.getRawValue(); cipherView.collectionIds = collections.map((i) => i.id as CollectionId); const cipher = await this.cipherService.encrypt(cipherView, this.activeUserId); - await this.cipherService.saveCollectionsWithServer(cipher); + if (this.params.isSingleCipherAdmin) { + await this.cipherService.saveCollectionsWithServerAdmin(cipher); + } else { + await this.cipherService.saveCollectionsWithServer(cipher); + } } }