feat: honor album access permissions in search endpoints (#29352)
This commit is contained in:
@@ -73,9 +73,16 @@ export class SearchService extends BaseService {
|
||||
checksum = Buffer.from(dto.checksum, encoding);
|
||||
}
|
||||
|
||||
let userIds: string[] | undefined;
|
||||
|
||||
if (dto.albumIds && dto.albumIds.length > 0) {
|
||||
await this.requireAccess({ auth, ids: dto.albumIds, permission: Permission.AlbumRead });
|
||||
} else {
|
||||
userIds = await this.getUserIdsToSearch(auth, dto.visibility);
|
||||
}
|
||||
|
||||
const page = dto.page ?? 1;
|
||||
const size = dto.size || 250;
|
||||
const userIds = await this.getUserIdsToSearch(auth, dto.visibility);
|
||||
const { hasNextPage, items } = await this.searchRepository.searchMetadata(
|
||||
{ page, size },
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Kysely } from 'kysely';
|
||||
import { SearchSuggestionType } from 'src/dtos/search.dto';
|
||||
import { AssetVisibility } from 'src/enum';
|
||||
import { AlbumUserRole, AssetVisibility } from 'src/enum';
|
||||
import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
@@ -139,6 +139,43 @@ describe(SearchService.name, () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('albumIds option', () => {
|
||||
it('should return assets from shared album', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { user: otherUser } = await ctx.newUser();
|
||||
|
||||
const { asset } = await ctx.newAsset({ ownerId: otherUser.id });
|
||||
const { album } = await ctx.newAlbum({ ownerId: otherUser.id });
|
||||
await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id });
|
||||
await ctx.newAlbumUser({ albumId: album.id, userId: user.id, role: AlbumUserRole.Editor });
|
||||
|
||||
const auth = factory.auth({ user: { id: user.id } });
|
||||
|
||||
const response = await sut.searchMetadata(auth, { albumIds: [album.id] });
|
||||
|
||||
expect(response.assets.items.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should not return assets for album, a user is not in, when partner sharing is enabled', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { user: otherUser } = await ctx.newUser();
|
||||
|
||||
await ctx.newPartner({ sharedById: otherUser.id, sharedWithId: user.id });
|
||||
|
||||
const { asset } = await ctx.newAsset({ ownerId: otherUser.id });
|
||||
const { album } = await ctx.newAlbum({ ownerId: otherUser.id });
|
||||
await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id });
|
||||
|
||||
const auth = factory.auth({ user: { id: user.id } });
|
||||
|
||||
await expect(sut.searchMetadata(auth, { albumIds: [album.id] })).rejects.toThrow(
|
||||
'Not found or no album.read access',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSearchSuggestions', () => {
|
||||
it('should filter out empty search suggestions', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
|
||||
Reference in New Issue
Block a user