Theme
Peacock-Admin auf deinesite.com/peacock-cms
WordPress hat /wp-admin. Peacock hat /peacock-cms — eine Drop-in-Admin-UI, die auf jeder Seite läuft, in die du Peacock eingebunden hast. Ein zweiter Script-Tag, eine URL, fertig.
Wann brauchst du das?
Wenn du Redakteur:innen einen In-Place-Edit-Workflow geben willst, ohne sie zu peacock-cms.webhoch.com/admin/ zu schicken. Inhalte direkt auf der eigenen Domain pflegen, sessionStorage-Login, kein zusätzlicher Tab.
Falls Editor-Power-User aber den vollen Builder brauchen (Drag-and-Drop, AI-Co-Pilot, Approval-Workflow, Audit-Log) — den gibt's nur auf der zentralen Instanz unter peacock-cms.webhoch.com/admin/. Die Per-Site-Admin verlinkt dorthin und du wechselst per Tab.
Setup
Ein Script-Tag, direkt neben dem embed.js-Tag:
html
<!-- Bestehender Embed (für die öffentliche Lese-Sicht) -->
<script src="https://peacock-cms.webhoch.com/embed.js"
data-peacock-api="https://peacock-cms.webhoch.com"
data-peacock-space="dein-space-slug"
defer></script>
<!-- NEU: Per-Site-Admin -->
<script src="https://peacock-cms.webhoch.com/peacock-admin.js"
data-peacock-api="https://peacock-cms.webhoch.com"
data-peacock-space="dein-space-slug"
data-peacock-mount-path="/peacock-cms"
defer></script>Das war's. Solange du auf einer normalen URL bist (z.B. /about, /, /products/123), bleibt das Script inaktiv — null DOM- Footprint. Sobald jemand /peacock-cms aufruft, übernimmt das Script die Seite mit der Admin-UI.
Konfiguration
| Attribut | Pflicht | Default | Was es macht |
|---|---|---|---|
data-peacock-api | ✓ | — | Basis-URL der Peacock-Instanz (z.B. https://peacock-cms.webhoch.com). |
data-peacock-space | ✓ | — | Slug des Spaces, dessen Inhalte du verwalten willst. |
data-peacock-mount-path | — | /peacock-cms | URL-Pfad, ab dem die Admin-UI das Page-Rendering übernimmt. Beispiele: /admin, /cms, /redaktion. |
Was die Admin-UI kann
| Sicht | URL | Was geht |
|---|---|---|
| Login | /peacock-cms (ohne Token) | Sanctum-Bearer-Token einfügen. Wird in sessionStorage gespeichert (Tab-scoped, kein localStorage). |
| Dashboard | /peacock-cms | Übersicht: Stories-Liste · Link zum vollen zentralen Editor |
| Stories-Liste | /peacock-cms/stories | Alle Stories des Spaces. Klick öffnet Editor. |
| Editor | /peacock-cms/edit/<uuid> | JSON-Editor für den Content. Speichern + Publish-Button. |
Token-Quelle
Der Token kommt aus dem zentralen Peacock-Admin (nicht aus der Per-Site-Admin selbst — die ist read-only auf User-Management). So gehst du vor:
- Im zentralen Admin (
https://peacock-cms.webhoch.com/admin/) einloggen. - Token ausstellen — Closed-Pre-Alpha-Pfad:bash
docker exec peacock-api php artisan tinker >>> $space = App\Models\Space::where('slug', 'dein-space')->first(); >>> echo $space->issueToken('per-site-editor', ['*'])->plainTextToken; - Mindestens
editor-Rolle auf den Ziel-Space gewähren (Phase 17 RBAC). - Token kopieren, in
/peacock-cmseinfügen.
Eine "Settings → API Tokens"-UI für Self-Service-Erstellung landet nach dem Public-Launch; aktuell ist der Tinker-Pfad authoritative.
Der Token wandert dann nicht über den Server zurück — er bleibt im sessionStorage des Browsers. Beim Tab-Schließen ist er weg; das ist die bewusste Trade-off-Entscheidung (Tab-scoped statt persistent für reduziertes Exfiltrations-Risiko bei kompromittierten Endgeräten).
CSP-Header für die Host-Seite
Wenn deine Seite eine Content-Security-Policy setzt (was sie für SEO-kritische Seiten sollte), muss die Per-Site-Admin die Verbindung zur zentralen Peacock-API durchgelassen bekommen. Minimaler Eintrag:
nginx
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' https://peacock-cms.webhoch.com 'unsafe-inline';
connect-src 'self' https://peacock-cms.webhoch.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' data:;
frame-ancestors 'self';
";Die connect-src-Direktive ist die wichtigste — ohne sie schlagen alle fetch()-Aufrufe der Admin-UI gegen die zentrale API stillschweigend fehl. 'unsafe-inline' für style-src braucht's für die per-JavaScript injizierten Admin-Styles; die kommen aus peacock-admin.js (kein Network- Content) und sind durch die SRI/Origin-Kontrolle der Script-Source geschützt.
Per-Container CSP-Test
Nach dem Setzen der CSP: lade domain/peacock-cms und prüf in DevTools → Console nach Refused to ...-Meldungen. Jede einzelne ist ein fehlender CSP-Direktiv-Eintrag.
Sicherheits-Modell
| Vector | Schutz |
|---|---|
| XSS auf der Host-Seite | Admin nutzt nur textContent / createElement, kein innerHTML aus Network-Daten. |
| Session-Hijack | Token-Storage sessionStorage ist origin-scoped + tab-scoped. Andere Tabs / andere Sites haben keinen Zugriff. |
| CSRF auf POSTs | Sanctum-Bearer-Token statt Cookies — kein CSRF-Vektor. |
| Token-Leak in URL | Token wird nie in der URL geschickt — immer im Authorization: Bearer-Header. |
| MITM | Über HTTPS — das data-peacock-api-Attribut muss eine https://-URL sein, sonst läuft der Browser ins Mixed Content-Blocking. |
| Compromised CDN-Origin | SRI auf dem Script-Tag empfohlen (siehe Integration-Guide). |
Wie unterscheidet sich das vom zentralen Admin?
| Feature | Per-Site (/peacock-cms) | Zentral (/admin/) |
|---|---|---|
| Stories listen + editieren | ✅ | ✅ |
| Publish | ✅ | ✅ |
| JSON-Editor | ✅ | ✅ |
| Drag-and-Drop-Builder | ❌ → öffnet zentralen Tab | ✅ |
| AI-Co-Pilot | ❌ → öffnet zentralen Tab | ✅ |
| Audience Segments + Variants | ❌ | ✅ |
| Workflow + Approval | ❌ | ✅ |
| Comments + Presence | ❌ | ✅ |
| Audit-Log | ❌ | ✅ |
| Settings + API-Token-Verwaltung | ❌ | ✅ |
| Bundle-Größe | ~12 KB Vanilla-JS | ~282 KB React-SPA |
Die Per-Site-Admin ist eine bewusst minimalistische Schicht für Inline-Edits. Der zentrale Admin ist die Powertool-Variante. Beide reden mit derselben API.
Live-Demo
Auf der Peacock-Marketing-Seite ist die Admin-UI eingebaut: lade peacock-cms.webhoch.com/peacock-cms — mit gültigem Token siehst du die echte Editor-Sicht. Ohne Token siehst du die Login-Seite und kannst die UI-Patterns inspizieren.
Häufige Stolpersteine
„Ich rufe /peacock-cms auf, sehe aber die normale Seite."
- Das Script lädt nur asynchron (
defer) — bei sehr langsamen Netzwerken kann es Sekunden dauern, bis es greift. - Browser-DevTools: ist
peacock-admin.jsim Network-Tab? Status 200? Wenn 404, prüfe diesrc-URL. - Konsole: tippt
peacock-adminetwas Verdächtiges in die Konsole? Bei fehlendemdata-peacock-spacewürde die Konsole „missing data-peacock-api or data-peacock-space" loggen.
„Login geht — aber die Stories-Liste ist leer."
- Token hat zu wenig Rechte. Prüfe in
Settings → API Tokensim zentralen Admin, ob der Token auf den richtigen Space miteditor-Rolle oder höher hängt. - Browser-DevTools → Network:
GET /v1/spaces/<slug>/stories— Status 401 oder 403 sind die häufigsten Fehlerklassen.
„Mein Speichern-Button gibt 403."
- Du hast
viewer-Rolle. Für Schreibzugriff brauchst dueditoroderadminauf den Space (Phase-17-RBAC).