fix: unauthorized album owner update (#29883)

This commit is contained in:
Daniel Dietzler
2026-07-13 18:46:18 +02:00
committed by GitHub
parent da8774801b
commit 84dff19ca9
3 changed files with 26 additions and 0 deletions

View File

@@ -796,5 +796,22 @@ describe('/albums', () => {
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest('Not found or no album.share access'));
});
it('should not allow an editor to change the role of an owner', async () => {
const album = await utils.createAlbum(user1.accessToken, {
albumName: 'testAlbum',
albumUsers: [{ userId: user2.userId, role: AlbumUserRole.Editor }],
});
expect(album.albumUsers[1].role).toEqual(AlbumUserRole.Editor);
const { status, body } = await request(app)
.put(`/albums/${album.id}/user/${user1.userId}`)
.set('Authorization', `Bearer ${user2.accessToken}`)
.send({ role: AlbumUserRole.Editor });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest('User is owner'));
});
});
});

View File

@@ -663,6 +663,7 @@ describe(AlbumService.name, () => {
const album = AlbumFactory.from().albumUser({ userId: user.id }).build();
const { user: owner } = album.albumUsers.find(({ role }) => role === AlbumUserRole.Owner)!;
mocks.access.album.checkOwnerAccess.mockResolvedValue(new Set([album.id]));
mocks.album.getById.mockResolvedValue(getForAlbum(album));
mocks.albumUser.update.mockResolvedValue();
await sut.updateUser(AuthFactory.create(owner), album.id, user.id, { role: AlbumUserRole.Viewer });

View File

@@ -335,6 +335,14 @@ export class AlbumService extends BaseService {
async updateUser(auth: AuthDto, id: string, userId: string, dto: UpdateAlbumUserDto): Promise<void> {
await this.requireAccess({ auth, permission: Permission.AlbumShare, ids: [id] });
const album = await this.findOrFail(id, userId, { withAssets: false });
const owner = album.albumUsers[0];
if (owner.user.id === userId) {
throw new BadRequestException('User is owner');
}
await this.albumUserRepository.update({ albumId: id, userId }, { role: dto.role });
}