From 94b15b8678307dcbd57b33c72c7d87f459df3a99 Mon Sep 17 00:00:00 2001 From: Yaros Date: Tue, 24 Mar 2026 03:39:30 +0100 Subject: [PATCH] fix(server): album permissions for editors (#27214) * fix(server): album permissions for editors * test: adjust e2e test * test: fix test --- e2e/src/specs/server/api/album.e2e-spec.ts | 11 ++++++++--- server/src/utils/access.ts | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/e2e/src/specs/server/api/album.e2e-spec.ts b/e2e/src/specs/server/api/album.e2e-spec.ts index c4f06edd93..a9e90940ab 100644 --- a/e2e/src/specs/server/api/album.e2e-spec.ts +++ b/e2e/src/specs/server/api/album.e2e-spec.ts @@ -524,14 +524,19 @@ describe('/albums', () => { expect(body).toEqual(errorDto.badRequest('Not found or no album.update access')); }); - it('should not be able to update as an editor', async () => { + it('should be able to update as an editor', async () => { const { status, body } = await request(app) .patch(`/albums/${user1Albums[0].id}`) .set('Authorization', `Bearer ${user2.accessToken}`) .send({ albumName: 'New album name' }); - expect(status).toBe(400); - expect(body).toEqual(errorDto.badRequest('Not found or no album.update access')); + expect(status).toBe(200); + expect(body).toEqual( + expect.objectContaining({ + id: user1Albums[0].id, + albumName: 'New album name', + }), + ); }); }); diff --git a/server/src/utils/access.ts b/server/src/utils/access.ts index 7431cb3293..2e0f7d10d0 100644 --- a/server/src/utils/access.ts +++ b/server/src/utils/access.ts @@ -190,7 +190,13 @@ const checkOtherAccess = async (access: AccessRepository, request: OtherAccessRe } case Permission.AlbumUpdate: { - return await access.album.checkOwnerAccess(auth.user.id, ids); + const isOwner = await access.album.checkOwnerAccess(auth.user.id, ids); + const isShared = await access.album.checkSharedAlbumAccess( + auth.user.id, + setDifference(ids, isOwner), + AlbumUserRole.Editor, + ); + return setUnion(isOwner, isShared); } case Permission.AlbumDelete: { @@ -198,7 +204,13 @@ const checkOtherAccess = async (access: AccessRepository, request: OtherAccessRe } case Permission.AlbumShare: { - return await access.album.checkOwnerAccess(auth.user.id, ids); + const isOwner = await access.album.checkOwnerAccess(auth.user.id, ids); + const isShared = await access.album.checkSharedAlbumAccess( + auth.user.id, + setDifference(ids, isOwner), + AlbumUserRole.Editor, + ); + return setUnion(isOwner, isShared); } case Permission.AlbumDownload: {