From 8ede1d54d8505315f2300187a35320502ca5f802 Mon Sep 17 00:00:00 2001 From: bo0tzz Date: Mon, 28 Sep 2026 18:21:44 +0200 Subject: [PATCH] fix(server): exclude hidden assets from large files search (#31479) Co-authored-by: Daniel Dietzler --- server/src/queries/search.repository.sql | 1 + server/src/repositories/search.repository.ts | 3 +++ .../medium/specs/services/search.service.spec.ts | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/server/src/queries/search.repository.sql b/server/src/queries/search.repository.sql index 819d7cf8e..0c82de5c2 100644 --- a/server/src/queries/search.repository.sql +++ b/server/src/queries/search.repository.sql @@ -144,6 +144,7 @@ where and "asset"."ownerId" = any ($3::uuid[]) and "asset"."isFavorite" = $4 and "asset"."deletedAt" is null + and "asset"."visibility" != 'hidden' and "asset_exif"."fileSizeInByte" > $5 order by "asset_exif"."fileSizeInByte" desc diff --git a/server/src/repositories/search.repository.ts b/server/src/repositories/search.repository.ts index 18b84bfbd..a49c17065 100644 --- a/server/src/repositories/search.repository.ts +++ b/server/src/repositories/search.repository.ts @@ -294,6 +294,9 @@ export class SearchRepository { return searchAssetBuilderLegacy(this.db, options) .select(columns.searchAsset) .$call(withExifInner) + .$if(options.visibility !== AssetVisibility.Hidden, (qb) => + qb.where('asset.visibility', '!=', sql.lit(AssetVisibility.Hidden)), + ) .where('asset_exif.fileSizeInByte', '>', options.minFileSize || 0) .orderBy('asset_exif.fileSizeInByte', orderDirection) .limit(size) diff --git a/server/test/medium/specs/services/search.service.spec.ts b/server/test/medium/specs/services/search.service.spec.ts index 6ba0d9903..9617431ce 100644 --- a/server/test/medium/specs/services/search.service.spec.ts +++ b/server/test/medium/specs/services/search.service.spec.ts @@ -65,6 +65,22 @@ describe(SearchService.name, () => { ]); }); + it('should not return hidden assets', async () => { + const { sut, ctx } = setup(); + const { user } = await ctx.newUser(); + + const { asset: visibleAsset } = await ctx.newAsset({ ownerId: user.id }); + await ctx.newExif({ assetId: visibleAsset.id, fileSizeInByte: 1000 }); + const { asset: hiddenAsset } = await ctx.newAsset({ ownerId: user.id, visibility: AssetVisibility.Hidden }); + await ctx.newExif({ assetId: hiddenAsset.id, fileSizeInByte: 2000 }); + + const auth = factory.auth({ user: { id: user.id } }); + + await expect(sut.searchLargeAssets(auth, { size: 250 })).resolves.toEqual([ + expect.objectContaining({ id: visibleAsset.id }), + ]); + }); + describe('searchStatistics', () => { it('should return statistics when filtering by personIds', async () => { const { sut, ctx } = setup();