From 849bf53eca073f183ddf0e76a9245cc2e0e8de77 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Thu, 12 Mar 2026 08:56:02 -0500 Subject: [PATCH] verify that enableIndividualItemsTransfer is set for organization ownership policy (#19506) --- ...fault-vault-items-transfer.service.spec.ts | 67 +++++++++++++++++-- .../default-vault-items-transfer.service.ts | 4 +- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/libs/vault/src/services/default-vault-items-transfer.service.spec.ts b/libs/vault/src/services/default-vault-items-transfer.service.spec.ts index b7d24681e64..dca96e519eb 100644 --- a/libs/vault/src/services/default-vault-items-transfer.service.spec.ts +++ b/libs/vault/src/services/default-vault-items-transfer.service.spec.ts @@ -141,10 +141,55 @@ describe("DefaultVaultItemsTransferService", () => { }); }); - describe("when policy exists", () => { + describe("when policy exists with enableIndividualItemsTransfer: false", () => { + beforeEach(() => { + setupMocksForMigrationScenario({ + policies: [ + { + organizationId: organizationId, + revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: false }, + } as Policy, + ], + organizations: [{ id: organizationId, name: "Test Org" } as Organization], + ciphers: [{ id: "cipher-1" } as CipherView], + }); + }); + + it("returns requiresMigration: false", async () => { + const result = await firstValueFrom(service.userMigrationInfo$(userId)); + + expect(result).toEqual({ requiresMigration: false }); + }); + }); + + describe("when policy exists without enableIndividualItemsTransfer set", () => { + beforeEach(() => { + setupMocksForMigrationScenario({ + policies: [ + { + organizationId: organizationId, + revisionDate: new Date("2024-01-01"), + data: {}, + } as Policy, + ], + organizations: [{ id: organizationId, name: "Test Org" } as Organization], + ciphers: [{ id: "cipher-1" } as CipherView], + }); + }); + + it("returns requiresMigration: false", async () => { + const result = await firstValueFrom(service.userMigrationInfo$(userId)); + + expect(result).toEqual({ requiresMigration: false }); + }); + }); + + describe("when policy exists with enableIndividualItemsTransfer: true", () => { const policy = { organizationId: organizationId, revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; const organization = { id: organizationId, @@ -229,14 +274,25 @@ describe("DefaultVaultItemsTransferService", () => { }); describe("when multiple policies exist", () => { + const oldestPolicy = { + organizationId: "oldest-org-id" as OrganizationId, + revisionDate: new Date("2023-09-13"), + data: { enableIndividualItemsTransfer: false }, + } as Policy; const olderPolicy = { organizationId: "older-org-id" as OrganizationId, revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; const newerPolicy = { organizationId: organizationId, revisionDate: new Date("2024-06-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; + const oldestOrganization = { + id: "oldest-org-id" as OrganizationId, + name: "Oldest Org", + } as Organization; const olderOrganization = { id: "older-org-id" as OrganizationId, name: "Older Org", @@ -248,13 +304,13 @@ describe("DefaultVaultItemsTransferService", () => { beforeEach(() => { setupMocksForMigrationScenario({ - policies: [newerPolicy, olderPolicy], - organizations: [olderOrganization, newerOrganization], + policies: [newerPolicy, olderPolicy, oldestPolicy], + organizations: [oldestOrganization, olderOrganization, newerOrganization], ciphers: [{ id: "cipher-1" } as CipherView], }); }); - it("uses the oldest policy when selecting enforcing organization", async () => { + it("uses the oldest enforced policy when selecting enforcing organization", async () => { const result = await firstValueFrom(service.userMigrationInfo$(userId)); expect(result).toEqual({ @@ -543,6 +599,7 @@ describe("DefaultVaultItemsTransferService", () => { const policy = { organizationId: organizationId, revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; const organization = { id: organizationId, @@ -858,6 +915,7 @@ describe("DefaultVaultItemsTransferService", () => { const policy = { organizationId: organizationId, revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; const organization = { id: organizationId, @@ -943,6 +1001,7 @@ describe("DefaultVaultItemsTransferService", () => { const policy = { organizationId: organizationId, revisionDate: new Date("2024-01-01"), + data: { enableIndividualItemsTransfer: true }, } as Policy; const organization = { id: organizationId, diff --git a/libs/vault/src/services/default-vault-items-transfer.service.ts b/libs/vault/src/services/default-vault-items-transfer.service.ts index 8b1c24c8ca2..042d1eceab8 100644 --- a/libs/vault/src/services/default-vault-items-transfer.service.ts +++ b/libs/vault/src/services/default-vault-items-transfer.service.ts @@ -72,7 +72,9 @@ export class DefaultVaultItemsTransferService implements VaultItemsTransferServi return this.policyService.policiesByType$(PolicyType.OrganizationDataOwnership, userId).pipe( map( (policies) => - policies.sort((a, b) => a.revisionDate.getTime() - b.revisionDate.getTime())?.[0], + policies + .filter((p) => p.data?.enableIndividualItemsTransfer === true) + .sort((a, b) => a.revisionDate.getTime() - b.revisionDate.getTime())?.[0], ), switchMap((policy) => { if (policy == null) {