mirror of
https://github.com/immich-app/immich.git
synced 2025-04-28 13:50:12 +02:00
fix(server): require asset permission when creating an album with them (#8686)
require asset permission when creating an album with them
This commit is contained in:
parent
56079527ef
commit
ad5d115abe
@ -4,7 +4,9 @@ import {
|
|||||||
AssetOrder,
|
AssetOrder,
|
||||||
LoginResponseDto,
|
LoginResponseDto,
|
||||||
SharedLinkType,
|
SharedLinkType,
|
||||||
|
addAssetsToAlbum,
|
||||||
deleteUser,
|
deleteUser,
|
||||||
|
getAlbumInfo,
|
||||||
} from '@immich/sdk';
|
} from '@immich/sdk';
|
||||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||||
import { errorDto } from 'src/responses';
|
import { errorDto } from 'src/responses';
|
||||||
@ -65,7 +67,6 @@ describe('/album', () => {
|
|||||||
utils.createAlbum(user2.accessToken, {
|
utils.createAlbum(user2.accessToken, {
|
||||||
albumName: user2SharedUser,
|
albumName: user2SharedUser,
|
||||||
sharedWithUserIds: [user1.userId],
|
sharedWithUserIds: [user1.userId],
|
||||||
assetIds: [user1Asset1.id],
|
|
||||||
}),
|
}),
|
||||||
utils.createAlbum(user2.accessToken, { albumName: user2SharedLink }),
|
utils.createAlbum(user2.accessToken, { albumName: user2SharedLink }),
|
||||||
utils.createAlbum(user2.accessToken, { albumName: user2NotShared }),
|
utils.createAlbum(user2.accessToken, { albumName: user2NotShared }),
|
||||||
@ -77,6 +78,13 @@ describe('/album', () => {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
await addAssetsToAlbum(
|
||||||
|
{ id: albums[3].id, bulkIdsDto: { ids: [user1Asset1.id] } },
|
||||||
|
{ headers: asBearerAuth(user1.accessToken) },
|
||||||
|
);
|
||||||
|
|
||||||
|
albums[3] = await getAlbumInfo({ id: albums[3].id }, { headers: asBearerAuth(user2.accessToken) });
|
||||||
|
|
||||||
user1Albums = albums.slice(0, 3);
|
user1Albums = albums.slice(0, 3);
|
||||||
user2Albums = albums.slice(3, 6);
|
user2Albums = albums.slice(3, 6);
|
||||||
|
|
||||||
|
@ -175,6 +175,7 @@ describe(AlbumService.name, () => {
|
|||||||
it('creates album', async () => {
|
it('creates album', async () => {
|
||||||
albumMock.create.mockResolvedValue(albumStub.empty);
|
albumMock.create.mockResolvedValue(albumStub.empty);
|
||||||
userMock.get.mockResolvedValue(userStub.user1);
|
userMock.get.mockResolvedValue(userStub.user1);
|
||||||
|
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['123']));
|
||||||
|
|
||||||
await sut.create(authStub.admin, {
|
await sut.create(authStub.admin, {
|
||||||
albumName: 'Empty album',
|
albumName: 'Empty album',
|
||||||
@ -193,6 +194,7 @@ describe(AlbumService.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(userMock.get).toHaveBeenCalledWith('user-id', {});
|
expect(userMock.get).toHaveBeenCalledWith('user-id', {});
|
||||||
|
expect(accessMock.asset.checkOwnerAccess).toHaveBeenCalledWith(authStub.admin.user.id, new Set(['123']));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require valid userIds', async () => {
|
it('should require valid userIds', async () => {
|
||||||
@ -206,6 +208,31 @@ describe(AlbumService.name, () => {
|
|||||||
expect(userMock.get).toHaveBeenCalledWith('user-3', {});
|
expect(userMock.get).toHaveBeenCalledWith('user-3', {});
|
||||||
expect(albumMock.create).not.toHaveBeenCalled();
|
expect(albumMock.create).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should only add assets the user is allowed to access', async () => {
|
||||||
|
userMock.get.mockResolvedValue(userStub.user1);
|
||||||
|
albumMock.create.mockResolvedValue(albumStub.oneAsset);
|
||||||
|
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set(['asset-1']));
|
||||||
|
|
||||||
|
await sut.create(authStub.admin, {
|
||||||
|
albumName: 'Test album',
|
||||||
|
description: '',
|
||||||
|
assetIds: ['asset-1', 'asset-2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(albumMock.create).toHaveBeenCalledWith({
|
||||||
|
ownerId: authStub.admin.user.id,
|
||||||
|
albumName: 'Test album',
|
||||||
|
description: '',
|
||||||
|
sharedUsers: [],
|
||||||
|
assets: [{ id: 'asset-1' }],
|
||||||
|
albumThumbnailAssetId: 'asset-1',
|
||||||
|
});
|
||||||
|
expect(accessMock.asset.checkOwnerAccess).toHaveBeenCalledWith(
|
||||||
|
authStub.admin.user.id,
|
||||||
|
new Set(['asset-1', 'asset-2']),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('update', () => {
|
describe('update', () => {
|
||||||
|
@ -119,13 +119,16 @@ export class AlbumService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allowedAssetIdsSet = await this.access.checkAccess(auth, Permission.ASSET_SHARE, new Set(dto.assetIds));
|
||||||
|
const assets = [...allowedAssetIdsSet].map((id) => ({ id }) as AssetEntity);
|
||||||
|
|
||||||
const album = await this.albumRepository.create({
|
const album = await this.albumRepository.create({
|
||||||
ownerId: auth.user.id,
|
ownerId: auth.user.id,
|
||||||
albumName: dto.albumName,
|
albumName: dto.albumName,
|
||||||
description: dto.description,
|
description: dto.description,
|
||||||
sharedUsers: dto.sharedWithUserIds?.map((value) => ({ id: value }) as UserEntity) ?? [],
|
sharedUsers: dto.sharedWithUserIds?.map((value) => ({ id: value }) as UserEntity) ?? [],
|
||||||
assets: (dto.assetIds || []).map((id) => ({ id }) as AssetEntity),
|
assets,
|
||||||
albumThumbnailAssetId: dto.assetIds?.[0] || null,
|
albumThumbnailAssetId: assets[0]?.id || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapAlbumWithAssets(album);
|
return mapAlbumWithAssets(album);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user