mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
refactor(server): prevent sharing album with owner by filtering out user from albumUsers (#28891)
fix(server): prevent sharing album with owner by filtering out user from albumUsers
This commit is contained in:
parent
9e453440e6
commit
474efd39f8
3 changed files with 24 additions and 19 deletions
|
|
@ -504,13 +504,14 @@ describe('/albums', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be able to share album with owner', async () => {
|
it('should deduplicate owner from albumUsers on create', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post('/albums')
|
.post('/albums')
|
||||||
.send({ albumName: 'New album', albumUsers: [{ role: AlbumUserRole.Editor, userId: user1.userId }] })
|
.send({ albumName: 'New album', albumUsers: [{ role: AlbumUserRole.Editor, userId: user1.userId }] })
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(201);
|
||||||
expect(body).toEqual(errorDto.badRequest('Cannot share album with owner'));
|
expect(body.albumUsers).toHaveLength(1);
|
||||||
|
expect(body.albumUsers[0]).toMatchObject({ role: AlbumUserRole.Owner, user: { id: user1.userId } });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,17 +348,25 @@ describe(AlbumService.name, () => {
|
||||||
expect(mocks.access.asset.checkOwnerAccess).toHaveBeenCalledWith(owner.id, new Set([assetId, 'asset-2']), false);
|
expect(mocks.access.asset.checkOwnerAccess).toHaveBeenCalledWith(owner.id, new Set([assetId, 'asset-2']), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the userId is the ownerId', async () => {
|
it('should deduplicate owner from albumUsers on create', async () => {
|
||||||
const album = AlbumFactory.create();
|
const auth = AuthFactory.create();
|
||||||
const { user: owner } = album.albumUsers.find(({ role }) => role === AlbumUserRole.Owner)!;
|
const album = AlbumFactory.from().build();
|
||||||
mocks.user.get.mockResolvedValue(owner);
|
mocks.album.create.mockResolvedValue(getForAlbum(album));
|
||||||
await expect(
|
mocks.user.getMetadata.mockResolvedValue([]);
|
||||||
sut.create(AuthFactory.create(owner), {
|
mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set());
|
||||||
albumName: 'Empty album',
|
|
||||||
albumUsers: [{ userId: owner.id, role: AlbumUserRole.Editor }],
|
await sut.create(auth, {
|
||||||
}),
|
albumName: 'Empty album',
|
||||||
).rejects.toBeInstanceOf(BadRequestException);
|
albumUsers: [{ userId: auth.user.id, role: AlbumUserRole.Editor }],
|
||||||
expect(mocks.album.create).not.toHaveBeenCalled();
|
});
|
||||||
|
|
||||||
|
expect(mocks.user.get).not.toHaveBeenCalled();
|
||||||
|
expect(mocks.album.create).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ albumName: 'Empty album' }),
|
||||||
|
[],
|
||||||
|
[{ userId: auth.user.id, role: AlbumUserRole.Owner }],
|
||||||
|
auth.user.id,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ export class AlbumService extends BaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(auth: AuthDto, dto: CreateAlbumDto): Promise<AlbumResponseDto> {
|
async create(auth: AuthDto, dto: CreateAlbumDto): Promise<AlbumResponseDto> {
|
||||||
const albumUsers = dto.albumUsers || [];
|
const albumUsers = (dto.albumUsers || []).filter(({ userId }) => userId !== auth.user.id);
|
||||||
|
|
||||||
for (const { userId } of albumUsers) {
|
for (const { userId } of albumUsers) {
|
||||||
const exists = await this.userRepository.get(userId, {});
|
const exists = await this.userRepository.get(userId, {});
|
||||||
|
|
@ -106,10 +106,6 @@ export class AlbumService extends BaseService {
|
||||||
this.logger.debug('Album creation failed: user not found');
|
this.logger.debug('Album creation failed: user not found');
|
||||||
throw new BadRequestException('Invalid user');
|
throw new BadRequestException('Invalid user');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId == auth.user.id) {
|
|
||||||
throw new BadRequestException('Cannot share album with owner');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const allowedAssetIdsSet = await this.checkAccess({
|
const allowedAssetIdsSet = await this.checkAccess({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue