diff --git a/server/src/utils/database.ts b/server/src/utils/database.ts index 985d7bb40..51aac25b1 100644 --- a/server/src/utils/database.ts +++ b/server/src/utils/database.ts @@ -436,6 +436,11 @@ export function searchAssetBuilderLegacy(kysely: Kysely, 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) => diff --git a/server/test/medium/specs/services/search.service.spec.ts b/server/test/medium/specs/services/search.service.spec.ts index 9617431ce..faab71eed 100644 --- a/server/test/medium/specs/services/search.service.spec.ts +++ b/server/test/medium/specs/services/search.service.spec.ts @@ -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', () => {