From 156b0401b36ae4e95b5b68586d3f0e2d92232aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Tue, 30 Jun 2026 11:12:53 +0200 Subject: [PATCH] =?UTF-8?q?fix(auth):=20JWT=20nicht=20als=20API-Key=20pr?= =?UTF-8?q?=C3=BCfen=20(Bearer-Fallback=20nur=20f=C3=BCr=20pm=5F-Keys)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beim JWT-Ablauf fällt der JwtOrApiKeyGuard auf den ApiKeyGuard zurück. Dieser nahm bisher jedes Authorization-Bearer-Token als API-Key-Kandidaten – also auch das (abgelaufene) JWT – und loggte eine irreführende "Invalid API Key"-Warnung (samt JWT-Präfix). Der Bearer-Fallback akzeptiert nun nur noch Token mit dem API-Key-Präfix "pm_"; ein JWT wird ignoriert. Ergebnis bleibt 401 (Frontend re-authentifiziert), aber ohne irreführenden Log. Co-Authored-By: Claude Opus 4.8 --- paperless-backend/src/auth/api-key.guard.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/paperless-backend/src/auth/api-key.guard.ts b/paperless-backend/src/auth/api-key.guard.ts index fad19c5..c34531a 100644 --- a/paperless-backend/src/auth/api-key.guard.ts +++ b/paperless-backend/src/auth/api-key.guard.ts @@ -28,12 +28,19 @@ export class ApiKeyGuard implements CanActivate { if (apiKey) source = 'apiKey query param'; } - // Fallback to Authorization: Bearer (used by SSE clients that can't set X-API-Key) + // Fallback to Authorization: Bearer (used by SSE clients that can't set + // X-API-Key). Nur akzeptieren, wenn das Token wie ein API-Key aussieht + // (Präfix "pm_"). Ein (abgelaufenes) JWT als Bearer-Token wird hier ignoriert, + // statt es fälschlich als API-Key zu prüfen – das vermeidet die irreführende + // "Invalid API Key"-Warnung beim normalen JWT-Ablauf. if (!apiKey) { const auth: string | undefined = request.headers['authorization']; if (auth?.startsWith('Bearer ')) { - apiKey = auth.slice(7); - source = 'Authorization: Bearer'; + const token = auth.slice(7); + if (token.startsWith('pm_')) { + apiKey = token; + source = 'Authorization: Bearer'; + } } }