Skip to content

Commit 62e931b

Browse files
committed
fix: accessible returns wrong permission when there are multiple (#2099)
* fix: add test that fails * fix: add code that fixes the issue * fix: itemPublished tests
1 parent 417fce9 commit 62e931b

5 files changed

Lines changed: 69 additions & 10 deletions

File tree

src/services/item/item.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
158158
);
159159

160160
// remap to discriminated packed items
161-
const packedItems = await itemWrapperService.createPackedItems(db, result.data);
161+
const packedItems = await itemWrapperService.createPackedItems(db, member, result.data);
162162
return { ...result, data: packedItems };
163163
},
164164
);

src/services/item/packedItem.dto.spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ describe('PackedItemService', () => {
9696
itemThumbnailService,
9797
).createPackedItems(
9898
MOCK_DB,
99+
actor,
99100
items.map((i) => ({ ...resolveItemType(i), creator: actor })),
100101
resultOfMemberships,
101102
);
@@ -104,5 +105,62 @@ describe('PackedItemService', () => {
104105
// should return parent visibility, not item visibility
105106
expect(packedItems[1].hidden!.id).toEqual(itemVisibilities[1].id);
106107
});
108+
109+
it('Return the permission for the current user', async () => {
110+
const MOCK_DB = {} as DBConnection;
111+
const { actor, items, itemMemberships } = await seedFromJson({
112+
items: [
113+
{
114+
memberships: [
115+
{ account: { name: 'toto' }, permission: 'admin' },
116+
{ account: 'actor', permission: 'read' },
117+
],
118+
},
119+
],
120+
});
121+
assertIsDefined(actor);
122+
assertIsMemberForTest(actor);
123+
124+
const itemVisibilityRepository = {
125+
getForManyItems: vi.fn(),
126+
} as unknown as ItemVisibilityRepository;
127+
vi.spyOn(itemVisibilityRepository, 'getForManyItems').mockImplementation(async () => ({
128+
data: {
129+
[items[0].id]: [],
130+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
131+
} as any,
132+
errors: [],
133+
}));
134+
135+
const resultOfMemberships = {
136+
data: {
137+
[items[0].id]: [itemMemberships[0], itemMemberships[1]],
138+
},
139+
errors: [],
140+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
141+
} as any;
142+
const itemMembershipRepository = {
143+
getForManyItems: vi.fn(),
144+
} as unknown as ItemMembershipRepository;
145+
vi.spyOn(itemMembershipRepository, 'getForManyItems').mockImplementation(
146+
async () => resultOfMemberships,
147+
);
148+
149+
const itemThumbnailService = { getUrlsByItems: vi.fn() } as unknown as ItemThumbnailService;
150+
vi.spyOn(itemThumbnailService, 'getUrlsByItems').mockImplementation(async () => ({}));
151+
152+
const packedItems = await new PackedItemService(
153+
itemVisibilityRepository,
154+
itemMembershipRepository,
155+
itemThumbnailService,
156+
).createPackedItems(
157+
MOCK_DB,
158+
actor,
159+
items.map((i) => ({ ...resolveItemType(i), creator: actor })),
160+
resultOfMemberships,
161+
);
162+
163+
expect(packedItems[0].permission).toEqual('read');
164+
});
107165
});
108166
});

src/services/item/packedItem.dto.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
ItemWithCreator,
1010
MinimalAccount,
1111
} from '../../drizzle/types';
12+
import { MaybeUser } from '../../types';
1213
import { ItemMembershipRepository } from '../itemMembership/membership.repository';
1314
import { Item, resolveItemType } from './item';
1415
import { ItemVisibilityRepository } from './plugins/itemVisibility/itemVisibility.repository';
@@ -128,6 +129,7 @@ export class PackedItemService {
128129

129130
async createPackedItems(
130131
dbConnection: DBConnection,
132+
currentAccount: MaybeUser,
131133
items: ItemWithCreator[],
132134
memberships?: ResultOf<ItemMembershipRaw[]>,
133135
): Promise<PackedItem[]> {
@@ -140,11 +142,14 @@ export class PackedItemService {
140142

141143
const m =
142144
memberships ?? (await this.itemMembershipRepository.getForManyItems(dbConnection, items));
143-
144145
const itemsThumbnails = await this.itemThumbnailService.getUrlsByItems(items);
145146

146147
return items.map((item) => {
147-
const permission = m.data[item.id][0]?.permission;
148+
// get the permission for the current user
149+
const itemMemberships = m.data[item.id];
150+
const permission =
151+
itemMemberships.find((membership) => membership.accountId === currentAccount?.id)
152+
?.permission ?? null;
148153
const thumbnails = itemsThumbnails[item.id];
149154

150155
// sort visibilities to retrieve the most restrictive (highest) visibility first

src/services/item/plugins/publication/published/itemPublished.controller.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,7 @@ describe('Item Published', () => {
182182
expect(res.statusCode).toBe(StatusCodes.OK);
183183
expectManyPackedItems(
184184
res.json(),
185-
items.map((i) =>
186-
new PackedItemDTO({ ...i, creator: member }, { permission: 'admin' }).packed(),
187-
),
185+
items.map((i) => new PackedItemDTO({ ...i, creator: member }, null).packed()),
188186
undefined,
189187
undefined,
190188
itemVisibilities,
@@ -231,9 +229,7 @@ describe('Item Published', () => {
231229
expect(res.statusCode).toBe(StatusCodes.OK);
232230
expectManyPackedItems(
233231
res.json(),
234-
items.map((i) =>
235-
new PackedItemDTO({ ...i, creator: member }, { permission: 'admin' }).packed(),
236-
),
232+
items.map((i) => new PackedItemDTO({ ...i, creator: member }, null).packed()),
237233
member,
238234
undefined,
239235
itemVisibilities,

src/services/item/plugins/publication/published/itemPublished.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export class ItemPublishedService {
269269
async getItemsForMember(dbConnection: DBConnection, actor: MaybeUser, memberId: UUID) {
270270
const items = await this.itemRepository.getPublishedItemsForMember(dbConnection, memberId);
271271

272-
return this.itemWrapperService.createPackedItems(dbConnection, items);
272+
return this.itemWrapperService.createPackedItems(dbConnection, actor, items);
273273
}
274274

275275
async getRecentItems(dbConnection: DBConnection, actor: MaybeUser, limit?: number) {

0 commit comments

Comments
 (0)