fix(server): exclude partners' locked assets from legacy search (#32604)

(cherry picked from commit 8dab52c7491c79cba742315dea8d7f5212915875)
This commit is contained in:
bo0tzz
2026-10-22 05:25:45 +03:00
committed by Codex
parent 7c78b00df6
commit ad9b368cb8
2 changed files with 30 additions and 0 deletions
+5
View File
@@ -436,6 +436,11 @@ export function searchAssetBuilderLegacy(kysely: Kysely<DB>, options: AssetSearc
? qb.where('asset.visibility', '!=', AssetVisibility.Locked)
: qb.where('asset.visibility', '=', options.visibility!),
)
.$if(!!options.viewingUserId, (qb) =>
qb.where((eb) =>
eb.or([eb('asset.visibility', '!=', AssetVisibility.Locked), eb('asset.ownerId', '=', options.viewingUserId!)]),
),
)
.$if(!!options.albumIds && options.albumIds.length > 0, (qb) => inAlbums(qb, options.albumIds!))
.$if(!!options.tagIds && options.tagIds.length > 0, (qb) => hasTags(qb, options.tagIds!))
.$if(options.tagIds === null, (qb) =>
@@ -123,6 +123,31 @@ describe(SearchService.name, () => {
expect(result).toEqual({ total: 0 });
});
it('should not return locked assets of partner in elevated session without a visibility filter', async () => {
const { sut, ctx } = setup();
const { user } = await ctx.newUser();
const { user: partner } = await ctx.newUser();
await ctx.newPartner({ sharedById: partner.id, sharedWithId: user.id });
await ctx.newAsset({ ownerId: user.id, visibility: AssetVisibility.Locked });
await ctx.newAsset({ ownerId: partner.id, visibility: AssetVisibility.Locked });
await ctx.newAsset({ ownerId: partner.id });
const auth = factory.auth({ user: { id: user.id }, session: { hasElevatedPermission: true } });
await expect(sut.searchStatistics(auth, {})).resolves.toEqual({ total: 2 });
const response = await sut.searchMetadata(auth, { size: 250, withStacked: false });
expect(response.assets.items.map(({ ownerId, visibility }) => ({ ownerId, visibility }))).toEqual(
expect.arrayContaining([
{ ownerId: user.id, visibility: AssetVisibility.Locked },
{ ownerId: partner.id, visibility: AssetVisibility.Timeline },
]),
);
expect(response.assets.items).toHaveLength(2);
});
});
describe('withStacked option', () => {