From eca952720ae008b88a669e9c8f43af3d9468a786 Mon Sep 17 00:00:00 2001 From: Yaros Date: Tue, 27 Oct 2026 16:09:08 +0100 Subject: [PATCH] fix: permission for admin notification endpoints (#32567) (cherry picked from commit 045d295d2d0b506af6f2abe14d1ed2cb89c5235f) --- open-api/immich-openapi-specs.json | 3 ++ .../notification-admin.controller.spec.ts | 35 +++++++++++++++++++ .../notification-admin.controller.ts | 8 ++--- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 0ffa714fb..00ee30781 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -1237,6 +1237,7 @@ "state": "Stable" } ], + "x-immich-permission": "notification.create", "x-immich-state": "Stable" } }, @@ -1306,6 +1307,7 @@ "state": "Stable" } ], + "x-immich-permission": "notification.create", "x-immich-state": "Stable" } }, @@ -1366,6 +1368,7 @@ "state": "Stable" } ], + "x-immich-permission": "notification.create", "x-immich-state": "Stable" } }, diff --git a/server/src/controllers/notification-admin.controller.spec.ts b/server/src/controllers/notification-admin.controller.spec.ts index dd71439bd..d70b57dee 100644 --- a/server/src/controllers/notification-admin.controller.spec.ts +++ b/server/src/controllers/notification-admin.controller.spec.ts @@ -1,5 +1,6 @@ import request from 'supertest'; import { NotificationAdminController } from 'src/controllers/notification-admin.controller.js'; +import { Permission } from 'src/enum.js'; import { NotificationAdminService } from 'src/services/notification-admin.service.js'; import { factory } from 'test/small.factory.js'; import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils.js'; @@ -27,5 +28,39 @@ describe(NotificationAdminController.name, () => { .send({ title: 'Test', userId: factory.uuid(), readAt: null }); expect(service.create).toHaveBeenCalledWith(undefined, expect.objectContaining({ readAt: null })); }); + + it('should require notification create permission', async () => { + await request(ctx.getHttpServer()).post(`/admin/notifications`).send({ title: 'Test', userId: factory.uuid() }); + + expect(ctx.authenticate).toHaveBeenCalledWith( + expect.objectContaining({ + metadata: expect.objectContaining({ permission: Permission.NotificationCreate, adminRoute: true }), + }), + ); + }); + }); + + describe('POST /admin/notifications/test-email', () => { + it('should require notification create permission', async () => { + await request(ctx.getHttpServer()).post(`/admin/notifications/test-email`).send({}); + + expect(ctx.authenticate).toHaveBeenCalledWith( + expect.objectContaining({ + metadata: expect.objectContaining({ permission: Permission.NotificationCreate, adminRoute: true }), + }), + ); + }); + }); + + describe('POST /admin/notifications/templates/:name', () => { + it('should require notification create permission', async () => { + await request(ctx.getHttpServer()).post(`/admin/notifications/templates/welcome`).send({ template: '' }); + + expect(ctx.authenticate).toHaveBeenCalledWith( + expect.objectContaining({ + metadata: expect.objectContaining({ permission: Permission.NotificationCreate, adminRoute: true }), + }), + ); + }); }); }); diff --git a/server/src/controllers/notification-admin.controller.ts b/server/src/controllers/notification-admin.controller.ts index bc1de5268..160a00b0e 100644 --- a/server/src/controllers/notification-admin.controller.ts +++ b/server/src/controllers/notification-admin.controller.ts @@ -10,7 +10,7 @@ import { TemplateResponseDto, TestEmailResponseDto, } from 'src/dtos/notification.dto.js'; -import { ApiTag } from 'src/enum.js'; +import { ApiTag, Permission } from 'src/enum.js'; import { Auth, Authenticated } from 'src/middleware/auth.guard.js'; import { EmailTemplate } from 'src/repositories/email.repository.js'; import { NotificationAdminService } from 'src/services/notification-admin.service.js'; @@ -21,7 +21,7 @@ export class NotificationAdminController { constructor(private service: NotificationAdminService) {} @Post() - @Authenticated({ admin: true }) + @Authenticated({ permission: Permission.NotificationCreate, admin: true }) @Endpoint({ summary: 'Create a notification', description: 'Create a new notification for a specific user.', @@ -32,7 +32,7 @@ export class NotificationAdminController { } @Post('test-email') - @Authenticated({ admin: true }) + @Authenticated({ permission: Permission.NotificationCreate, admin: true }) @HttpCode(HttpStatus.OK) @Endpoint({ summary: 'Send test email', @@ -44,7 +44,7 @@ export class NotificationAdminController { } @Post('templates/:name') - @Authenticated({ admin: true }) + @Authenticated({ permission: Permission.NotificationCreate, admin: true }) @HttpCode(HttpStatus.OK) @Endpoint({ summary: 'Render email template',