From af84ffc379b44fbdada525ab973ba7b58efdde2a Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 May 2026 23:48:37 +0200 Subject: [PATCH] fix(notifications): guard against null notificationId in dismiss action Casting null to string caused PATCH to fire against /api/notifications/null/read when the field was absent. Added an early-return fail(400) and a test that submitting an empty form returns 400 without calling the API. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/routes/aktivitaeten/+page.server.ts | 3 ++- frontend/src/routes/aktivitaeten/page.server.spec.ts | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/routes/aktivitaeten/+page.server.ts b/frontend/src/routes/aktivitaeten/+page.server.ts index 940cedb6..aacab562 100644 --- a/frontend/src/routes/aktivitaeten/+page.server.ts +++ b/frontend/src/routes/aktivitaeten/+page.server.ts @@ -71,7 +71,8 @@ export async function load({ fetch, url }) { export const actions = { 'dismiss-notification': async ({ request, fetch }) => { const data = await request.formData(); - const notificationId = data.get('notificationId') as string; + const notificationId = data.get('notificationId') as string | null; + if (!notificationId) return fail(400, { error: 'Ungültige Benachrichtigungs-ID' }); const api = createApiClient(fetch); const result = await api.PATCH('/api/notifications/{id}/read', { params: { path: { id: notificationId } } diff --git a/frontend/src/routes/aktivitaeten/page.server.spec.ts b/frontend/src/routes/aktivitaeten/page.server.spec.ts index fbff2670..63ee881b 100644 --- a/frontend/src/routes/aktivitaeten/page.server.spec.ts +++ b/frontend/src/routes/aktivitaeten/page.server.spec.ts @@ -185,6 +185,13 @@ function makeActionEvent(formData: FormData): any { } describe('aktivitaeten/actions — dismiss-notification', () => { + it('returns fail(400, { error }) and does NOT call PATCH when notificationId is missing', async () => { + const result = await actions['dismiss-notification'](makeActionEvent(new FormData())); + + expect(result).toMatchObject({ status: 400 }); + expect(mockApi.PATCH).not.toHaveBeenCalled(); + }); + it('calls PATCH /api/notifications/{id}/read with the form-supplied notificationId', async () => { mockApi.PATCH.mockResolvedValue({ response: { ok: true }, data: {} }); const fd = new FormData();