diff --git a/src/services/item/item.controller.ts b/src/services/item/item.controller.ts index 4fcaf5b70..228c4514c 100644 --- a/src/services/item/item.controller.ts +++ b/src/services/item/item.controller.ts @@ -158,7 +158,7 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => { ); // remap to discriminated packed items - const packedItems = await itemWrapperService.createPackedItems(db, result.data); + const packedItems = await itemWrapperService.createPackedItems(db, member, result.data); return { ...result, data: packedItems }; }, ); diff --git a/src/services/item/packedItem.dto.spec.ts b/src/services/item/packedItem.dto.spec.ts index de9ea804e..a045e0441 100644 --- a/src/services/item/packedItem.dto.spec.ts +++ b/src/services/item/packedItem.dto.spec.ts @@ -96,6 +96,7 @@ describe('PackedItemService', () => { itemThumbnailService, ).createPackedItems( MOCK_DB, + actor, items.map((i) => ({ ...resolveItemType(i), creator: actor })), resultOfMemberships, ); @@ -104,5 +105,62 @@ describe('PackedItemService', () => { // should return parent visibility, not item visibility expect(packedItems[1].hidden!.id).toEqual(itemVisibilities[1].id); }); + + it('Return the permission for the current user', async () => { + const MOCK_DB = {} as DBConnection; + const { actor, items, itemMemberships } = await seedFromJson({ + items: [ + { + memberships: [ + { account: { name: 'toto' }, permission: 'admin' }, + { account: 'actor', permission: 'read' }, + ], + }, + ], + }); + assertIsDefined(actor); + assertIsMemberForTest(actor); + + const itemVisibilityRepository = { + getForManyItems: vi.fn(), + } as unknown as ItemVisibilityRepository; + vi.spyOn(itemVisibilityRepository, 'getForManyItems').mockImplementation(async () => ({ + data: { + [items[0].id]: [], + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, + errors: [], + })); + + const resultOfMemberships = { + data: { + [items[0].id]: [itemMemberships[0], itemMemberships[1]], + }, + errors: [], + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + const itemMembershipRepository = { + getForManyItems: vi.fn(), + } as unknown as ItemMembershipRepository; + vi.spyOn(itemMembershipRepository, 'getForManyItems').mockImplementation( + async () => resultOfMemberships, + ); + + const itemThumbnailService = { getUrlsByItems: vi.fn() } as unknown as ItemThumbnailService; + vi.spyOn(itemThumbnailService, 'getUrlsByItems').mockImplementation(async () => ({})); + + const packedItems = await new PackedItemService( + itemVisibilityRepository, + itemMembershipRepository, + itemThumbnailService, + ).createPackedItems( + MOCK_DB, + actor, + items.map((i) => ({ ...resolveItemType(i), creator: actor })), + resultOfMemberships, + ); + + expect(packedItems[0].permission).toEqual('read'); + }); }); }); diff --git a/src/services/item/packedItem.dto.ts b/src/services/item/packedItem.dto.ts index 15a638067..80160b42e 100644 --- a/src/services/item/packedItem.dto.ts +++ b/src/services/item/packedItem.dto.ts @@ -9,6 +9,7 @@ import type { ItemWithCreator, MinimalAccount, } from '../../drizzle/types'; +import { MaybeUser } from '../../types'; import { ItemMembershipRepository } from '../itemMembership/membership.repository'; import { Item, resolveItemType } from './item'; import { ItemVisibilityRepository } from './plugins/itemVisibility/itemVisibility.repository'; @@ -128,6 +129,7 @@ export class PackedItemService { async createPackedItems( dbConnection: DBConnection, + currentAccount: MaybeUser, items: ItemWithCreator[], memberships?: ResultOf, ): Promise { @@ -140,11 +142,14 @@ export class PackedItemService { const m = memberships ?? (await this.itemMembershipRepository.getForManyItems(dbConnection, items)); - const itemsThumbnails = await this.itemThumbnailService.getUrlsByItems(items); return items.map((item) => { - const permission = m.data[item.id][0]?.permission; + // get the permission for the current user + const itemMemberships = m.data[item.id]; + const permission = + itemMemberships.find((membership) => membership.accountId === currentAccount?.id) + ?.permission ?? null; const thumbnails = itemsThumbnails[item.id]; // sort visibilities to retrieve the most restrictive (highest) visibility first diff --git a/src/services/item/plugins/publication/published/itemPublished.controller.test.ts b/src/services/item/plugins/publication/published/itemPublished.controller.test.ts index 68f2efcb7..152058b34 100644 --- a/src/services/item/plugins/publication/published/itemPublished.controller.test.ts +++ b/src/services/item/plugins/publication/published/itemPublished.controller.test.ts @@ -182,9 +182,7 @@ describe('Item Published', () => { expect(res.statusCode).toBe(StatusCodes.OK); expectManyPackedItems( res.json(), - items.map((i) => - new PackedItemDTO({ ...i, creator: member }, { permission: 'admin' }).packed(), - ), + items.map((i) => new PackedItemDTO({ ...i, creator: member }, null).packed()), undefined, undefined, itemVisibilities, @@ -231,9 +229,7 @@ describe('Item Published', () => { expect(res.statusCode).toBe(StatusCodes.OK); expectManyPackedItems( res.json(), - items.map((i) => - new PackedItemDTO({ ...i, creator: member }, { permission: 'admin' }).packed(), - ), + items.map((i) => new PackedItemDTO({ ...i, creator: member }, null).packed()), member, undefined, itemVisibilities, diff --git a/src/services/item/plugins/publication/published/itemPublished.service.ts b/src/services/item/plugins/publication/published/itemPublished.service.ts index 8237ae839..d8978e296 100644 --- a/src/services/item/plugins/publication/published/itemPublished.service.ts +++ b/src/services/item/plugins/publication/published/itemPublished.service.ts @@ -269,7 +269,7 @@ export class ItemPublishedService { async getItemsForMember(dbConnection: DBConnection, actor: MaybeUser, memberId: UUID) { const items = await this.itemRepository.getPublishedItemsForMember(dbConnection, memberId); - return this.itemWrapperService.createPackedItems(dbConnection, items); + return this.itemWrapperService.createPackedItems(dbConnection, actor, items); } async getRecentItems(dbConnection: DBConnection, actor: MaybeUser, limit?: number) {