From 18bee811905c81933be78e898b6d0e13c80ab73e Mon Sep 17 00:00:00 2001 From: Nik Gilmore Date: Wed, 7 Jan 2026 15:16:26 -0800 Subject: [PATCH] Implement restoreWithServer and restoreManyWithServer using SDK --- .../src/vault/services/cipher.service.ts | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index 6e343de59d3..b99d2b2e45a 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -1424,7 +1424,7 @@ export class CipherService implements CipherServiceAbstraction { await this.delete(id, userId); } - async deleteWithServer_sdk(id: string, userId: UserId, asAdmin = false): Promise { + private async deleteWithServer_sdk(id: string, userId: UserId, asAdmin = false): Promise { this.sdkService.userClient$(userId).pipe( map(async (sdk) => { if (!sdk) { @@ -1462,7 +1462,11 @@ export class CipherService implements CipherServiceAbstraction { await this.delete(ids, userId); } - async deleteManyWithServer_sdk(ids: string[], userId: UserId, asAdmin = false): Promise { + private async deleteManyWithServer_sdk( + ids: string[], + userId: UserId, + asAdmin = false, + ): Promise { this.sdkService.userClient$(userId).pipe( map(async (sdk) => { if (!sdk) { @@ -1487,6 +1491,7 @@ export class CipherService implements CipherServiceAbstraction { } }), ); + await this.clearCache(userId); } async deleteAttachment( @@ -1703,6 +1708,13 @@ export class CipherService implements CipherServiceAbstraction { } async restoreWithServer(id: string, userId: UserId, asAdmin = false): Promise { + const useSdk = await this.configService.getFeatureFlag( + FeatureFlag.PM27632_SdkCipherCrudOperations, + ); + if (useSdk) { + return await this.restoreWithServer_sdk(id, userId, asAdmin); + } + let response; if (asAdmin) { response = await this.apiService.putRestoreCipherAdmin(id); @@ -1713,11 +1725,35 @@ export class CipherService implements CipherServiceAbstraction { await this.restore({ id: id, revisionDate: response.revisionDate }, userId); } + private async restoreWithServer_sdk(id: string, userId: UserId, asAdmin = false): Promise { + this.sdkService.userClient$(userId).pipe( + map(async (sdk) => { + if (!sdk) { + throw new Error("SDK not available"); + } + using ref = sdk.take(); + if (asAdmin) { + await ref.value.vault().ciphers().admin().restore(asUuid(id)); + } else { + await ref.value.vault().ciphers().restore(asUuid(id)); + } + }), + ); + await this.clearCache(userId); + } + /** * No longer using an asAdmin Param. Org Vault bulkRestore will assess if an item is unassigned or editable * The Org Vault will pass those ids an array as well as the orgId when calling bulkRestore */ async restoreManyWithServer(ids: string[], userId: UserId, orgId?: string): Promise { + const useSdk = await this.configService.getFeatureFlag( + FeatureFlag.PM27632_SdkCipherCrudOperations, + ); + if (useSdk) { + return await this.restoreManyWithServer_sdk(ids, userId, orgId); + } + let response; if (orgId) { @@ -1735,6 +1771,40 @@ export class CipherService implements CipherServiceAbstraction { await this.restore(restores, userId); } + private async restoreManyWithServer_sdk( + ids: string[], + userId: UserId, + orgId?: string, + ): Promise { + this.sdkService.userClient$(userId).pipe( + map(async (sdk) => { + if (!sdk) { + throw new Error("SDK not available"); + } + using ref = sdk.take(); + + // No longer using an asAdmin Param. Org Vault bulkRestore will assess if an item is unassigned or editable + // The Org Vault will pass those ids an array as well as the orgId when calling bulkRestore + if (orgId) { + await ref.value + .vault() + .ciphers() + .admin() + .restore_many( + ids.map((id) => asUuid(id)), + asUuid(orgId), + ); + } else { + await ref.value + .vault() + .ciphers() + .restore_many(ids.map((id) => asUuid(id))); + } + }), + ); + await this.clearCache(userId); + } + async getKeyForCipherKeyDecryption(cipher: Cipher, userId: UserId): Promise { if (cipher.organizationId == null) { return await firstValueFrom(this.keyService.userKey$(userId));