Audit: Namespace /api/content/*
Stand: interne Bestandsaufnahme nach dem Refactor der Session-/Center-Listen (/api/news, /api/events, …).
Ziel: transparenz, welche Routen öffentlich halb-offen sind und wo ohne centerId ggf. alle Datensätze sichtbar werden.
Legende Risiko: „niedrig“ = erwartetes Verhalten oder Session geschützt; „mittel/hoch“ = Datenabfluss möglich ohne Authentifizierung oder ohne Center-Parameter.
GET-Listen (klassischer „Content-API“-Stil, CORS *)
| Route | Session | Center wenn kein centerId | Hauptaufrufer | Risiko & Hinweis |
|---|---|---|---|---|
GET /api/content/events | nein | alle Events im System | ree-carree-event-banner-section-config, content-selector-dialog (mit Filter publicOnWebsite + meist centerId), Demo-Skript | hoch: unauthentifiziert; ohne ?centerId= volle Tabelle. Mit centerId nur dieses Center. Für Website/Dialog typischerweise immer centerId. |
GET /api/content/news | nein | alle News | Ree-Carree, Goldbeck-Hero (centerId+published), content-selector-dialog, Demo-Skript | hoch wie oben. published=true reduziert inhaltlich, nicht mandantenrechtlich. |
GET /api/content/offers | nein | alle Angebote | Ree-Carree, content-selector-dialog, Demo-Skript | hoch wie oben. |
GET /api/content/jobs | nein | alle Jobs | content-selector-dialog, Demo-Skript | hoch wie oben. |
GET /api/content/services | nein | alle Services | content-selector-dialog, Demo-Skript | hoch wie oben. |
GET /api/content/shop-chains | nein | alle ShopChains inkl. Locations | Demo-Skript (create-cms-demo-data.js) | sehr hoch für produktive URL: globale Kettenliste ohne Session. |
Design-Hinweis: Diese Endpoints sind historisch embeddings-/widget-freundlich (CORS, kein Login). Mandantentrennung erfolgt nur über ?centerId= — wer den Parameter weglässt, sieht systemweit.
Dashboard-gebunden (Session + Center-Logik)
| Route | Session | Center-/Scope-Logik | Hauptaufrufer | Risiko & Hinweis |
|---|---|---|---|---|
GET /api/content/metrics | ja (ohne Session: 401, außer künftig anderweitig dokumentiert) | mergeSessionCenterScopeIntoListParams + pickCenterWhereFragment | /dashboard/content (Cookie), MCP optional /api/content/metrics | niedrig nach Fix. |
GET /api/content/recent | ja (ohne Session: 401) | wie oben | /dashboard/content | niedrig nach Fix. |
GET /api/content/planner | requireSession | getCenterIdsForUser + Query centerId / organizationId | /dashboard/content/planner | niedrig |
GET /api/content/drafts | requireSession | getCenterIdsForUser | PendingDraftsSection, Workflow-Page | niedrig |
GET/PUT/DELETE …/drafts/[draftId] | Session | Zugriff über Draft/Center (Route prüft) | Workflow, Pending Drafts | niedrig (Details in Route) |
POST …/customer-touchpoint-suggestion | Session | — | Workflow | niedrig |
POST /api/content/reclassify | Session | Transaktion prüft Entitäten | Content-Reclassify-Dialog | niedrig |
Sonstige POST/Admin
| Route | Session | Bemerkung | Risiko |
|---|---|---|---|
POST /api/content/drafts/retry-approved | ja | Verarbeitet alle Drafts mit Status APPROVED (kein Center-Filter in der WHERE-Klausel) — bewusst Admin-Werkzeug; ggf. später nach Center einschränken. | mittel (Operativ: zu breit) |
| `POST /api/content/events | news | offers | jobs |
Abweichung / Bug im Frontend (außerhalb /api/content/)
| Befund | Ort | Empfehlung |
|---|---|---|
Falscher Pfad /api/content/hot-picks existiert nicht | editor-dashboard.tsx (Hot-Picks-Statistik) | Auf /api/hot-picks umstellen (oder Alias nur wenn bewusst gewünscht). Aktuell sehr wahrscheinlich 404 / leere Daten. |
Abgleich mit geschützten Listen-APIs
Für eingeloggte Bearbeitung nutzt das Dashboard überwiegend:
/api/news,/api/events,/api/offers,/api/jobs,/api/shops,/api/services— mitmergeSessionCenterScopebzw. äquivalentem Angebot-Filter.
Der Namespace /api/content/… (GET legacy) bleibt nicht automatisch gleich sicher — bewusst oder technische Schuld.
Empfohlene nächste Schritte (kurz)
- Produktion:
GET /api/content/shop-chainsund anonyme GET ohnecenterIdbewerten — ggf. API-Key, IP-Allowlist oder Deprecation zugunsten nur nochcenterId+öffentliche Filter. - editor-dashboard: Hot-Picks-URL korrigieren.
- Optional: Öffentliche Lesenden unter z. B.
/api/public/centers/[id]/…zusammenführen und/api/content/*GET schrittweise abschalten oder nur noch mit Signatur.
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/api-content-namespace-audit