fix(security): Rechteprüfung deny by default, API-Keys nur auf freigegebenen Routen

- PermissionsGuard lehnt Routen ohne @RequirePermissions/@AllowAnyAuthenticated
  ab. API-Keys umgehen keine Rechteprüfung mehr, sondern gelten nur auf
  Routen mit @AllowApiKey (Paperless-Webhook, externer Upload, checksum,
  Agent-Routen des Etikettendrucks).
- Rechte für 24 bisher offene Routen ergänzt, u.a. paperless/documents
  (nur Admin), paperless/documents/:id und Kontonummern (Posteingang/
  manuell), webhook/status (Admin). routen-rechte.spec.ts prüft alle Routen.
- Etiketten-Agent: printed/error nur für abgeholte, offene Jobs (bedingtes
  Update, sonst 409) – ein gedruckter Job kann seine Nummer nicht mehr
  freigeben. Feldwerte nur aus den Eingabefeldern der Vorlage ({number}
  nicht vorgebbar) und URL-kodiert in GET-/Callback-URLs.
- PUT paperless/inbox/:id ignoriert Freigabe (CF15) und Zahlung (CF16)
  ohne die jeweilige Rolle (Funktionstrennung).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bjoernpoettkerandClaude Opus 5.5 committed 2026-11-04 10:46:43 +01:00
1 parent de9cb09bcd
commit 3f98dfd98f
21 files changed
+699 -51

No files matched your search

+3 -1
View File
@@ -12,7 +12,9 @@ Alle Endpunkte erfordern einen Bearer Token (JWT oder API-Key):
Authorization: Bearer {token}
```
`/jobs/next`, `/jobs/:id/image`, `/jobs/:id/printed` und `/jobs/:id/error` benötigen **keine** spezifische Permission (nur gültigen Token). `POST /jobs` und `POST /preview` erfordern `VIEW_SCANNER`.
`/events`, `/jobs/next`, `/jobs/:id/image`, `/jobs/:id/printed` und `/jobs/:id/error` sind die Agent-Routen: Sie nehmen einen **API-Key** an (`X-API-Key`, `?apiKey=` oder `Authorization: Bearer pm_…`); Benutzer mit JWT brauchen dort `MANAGE_SETTINGS`. `POST /jobs` und `POST /preview` erfordern `VIEW_SCANNER` und nehmen **keinen** API-Key an.
`printed` und `error` werden nur für vom Agenten abgeholte, noch offene Jobs angenommen, sonst `409 Conflict`. Ein wiederholtes `printed` bzw. `error` für einen bereits so abgeschlossenen Job ist ein No-op (kein zweiter Callback).
---