Skip to main content

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 *)

RouteSessionCenter wenn kein centerIdHauptaufruferRisiko & Hinweis
GET /api/content/eventsneinalle Events im Systemree-carree-event-banner-section-config, content-selector-dialog (mit Filter publicOnWebsite + meist centerId), Demo-Skripthoch: unauthentifiziert; ohne ?centerId= volle Tabelle. Mit centerId nur dieses Center. Für Website/Dialog typischerweise immer centerId.
GET /api/content/newsneinalle NewsRee-Carree, Goldbeck-Hero (centerId+published), content-selector-dialog, Demo-Skripthoch wie oben. published=true reduziert inhaltlich, nicht mandantenrechtlich.
GET /api/content/offersneinalle AngeboteRee-Carree, content-selector-dialog, Demo-Skripthoch wie oben.
GET /api/content/jobsneinalle Jobscontent-selector-dialog, Demo-Skripthoch wie oben.
GET /api/content/servicesneinalle Servicescontent-selector-dialog, Demo-Skripthoch wie oben.
GET /api/content/shop-chainsneinalle ShopChains inkl. LocationsDemo-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)

RouteSessionCenter-/Scope-LogikHauptaufruferRisiko & Hinweis
GET /api/content/metricsja (ohne Session: 401, außer künftig anderweitig dokumentiert)mergeSessionCenterScopeIntoListParams + pickCenterWhereFragment/dashboard/content (Cookie), MCP optional /api/content/metricsniedrig nach Fix.
GET /api/content/recentja (ohne Session: 401)wie oben/dashboard/contentniedrig nach Fix.
GET /api/content/plannerrequireSessiongetCenterIdsForUser + Query centerId / organizationId/dashboard/content/plannerniedrig
GET /api/content/draftsrequireSessiongetCenterIdsForUserPendingDraftsSection, Workflow-Pageniedrig
GET/PUT/DELETE …/drafts/[draftId]SessionZugriff über Draft/Center (Route prüft)Workflow, Pending Draftsniedrig (Details in Route)
POST …/customer-touchpoint-suggestionSessionWorkflowniedrig
POST /api/content/reclassifySessionTransaktion prüft EntitätenContent-Reclassify-Dialogniedrig

Sonstige POST/Admin

RouteSessionBemerkungRisiko
POST /api/content/drafts/retry-approvedjaVerarbeitet 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/eventsnewsoffersjobs

Abweichung / Bug im Frontend (außerhalb /api/content/)

BefundOrtEmpfehlung
Falscher Pfad /api/content/hot-picks existiert nichteditor-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 — mit mergeSessionCenterScope bzw. äquivalentem Angebot-Filter.

Der Namespace /api/content/… (GET legacy) bleibt nicht automatisch gleich sicher — bewusst oder technische Schuld.


Empfohlene nächste Schritte (kurz)

  1. Produktion: GET /api/content/shop-chains und anonyme GET ohne centerId bewerten — ggf. API-Key, IP-Allowlist oder Deprecation zugunsten nur noch centerId+öffentliche Filter.
  2. editor-dashboard: Hot-Picks-URL korrigieren.
  3. 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