feat: redesign CMS and unify German admin UI

This commit is contained in:
2026-09-17 16:51:24 +02:00
parent a2b3e99174
commit 7ec0c51ff5
129 changed files with 952 additions and 550 deletions
+7 -7
View File
@@ -1,4 +1,4 @@
# Security-Audit — 17.09.2026
# Security-Audit - 17.09.2026
Geprüfter Commit: `cb30eca`. Ergebnis: **ein Befund hoher Priorität (P1), fünf Befunde mittlerer Priorität (P2)** sowie Hinweise zu Abhängigkeiten. Keine Behebung vorgenommen.
@@ -8,7 +8,7 @@ Quellcodeprüfung von Payload-Zugriffsregeln, Kunden-/Admin-Authentifizierung, B
`npm test`: 5/5 Tests bestanden. Zusätzlich wurden die unveränderten Route Handler für Stornierung, Meeting-Beitritt, Token-Austausch und Buchungsanfragen isoliert ausgeführt, mit simulierter Datenbank und simuliertem LiveKit. Keine Produktivzugriffe, echten E-Mails oder Datenänderungen. Diese Prüfungen belegen die Handler-Logik, nicht das Verhalten eines realen Reverse-Proxys oder Video-Servers. Produktionskonfiguration, Git-Historie und laufende Infrastruktur waren nicht Gegenstand eines Penetrationstests.
## 1. P1 — Interne Buchungsnotizen gelangen in den Kundenbrowser
## 1. P1 - Interne Buchungsnotizen gelangen in den Kundenbrowser
**Stellen:** `lib/booking/queries.ts:12`, `app/(frontend)/konto/termine/page.tsx:27`, `app/(frontend)/konto/page.tsx:46`, `collections/BookingRequests.ts:364`.
@@ -24,7 +24,7 @@ Die Kontoseiten übergeben das gesamte Ergebnis als `booking` an die Client Comp
**Regressionstest:** Eine Buchung mit einer eindeutigen internen Testnotiz anlegen; die Notiz darf weder in HTML noch in einer RSC-Antwort des Kundenkontos vorkommen.
## 2. P2 — Stornierung widerruft den privaten Meeting-Zugang nicht
## 2. P2 - Stornierung widerruft den privaten Meeting-Zugang nicht
**Stellen:** `app/(payload)/api/booking/[id]/cancel/route.ts:29`, `app/(payload)/api/meetings/[slug]/join/route.ts:49`, `collections/BookingRequests.ts:229`.
@@ -36,7 +36,7 @@ Die Stornierung setzt nur den Buchungsstatus. Der verknüpfte Online-Event und s
**Behebung:** Für private Events bei jedem Join und Connect eine weiterhin bestätigte, passend verknüpfte Buchung verlangen. Bei Stornierung bestehende Sitzungen widerrufen; gegebenenfalls aktive Teilnehmer über LiveKit entfernen.
## 3. P2 — Token-Austausch umgeht das Meeting-Ende
## 3. P2 - Token-Austausch umgeht das Meeting-Ende
**Stelle:** `app/(payload)/api/meetings/[slug]/connect/route.ts:27`.
@@ -48,7 +48,7 @@ Die Stornierung setzt nur den Buchungsstatus. Der verknüpfte Online-Event und s
**Behebung:** Dieselbe serverseitige Zugangsprüfung für Join und Connect verwenden. Token-Laufzeiten am erlaubten Meeting-Ende begrenzen und einen Sitzungs-/Berechtigungsstand für Widerrufe prüfen. Die beabsichtigte Admin-Testzimmer-Ausnahme separat behandeln.
## 4. P2 — Krankheits- und Urlaubsgründe sind öffentlich abrufbar
## 4. P2 - Krankheits- und Urlaubsgründe sind öffentlich abrufbar
**Stelle:** `collections/AvailabilityOverrides.ts:17`.
@@ -60,7 +60,7 @@ Die Collection erlaubt anonymes Lesen aller Dokumente. Das Feld `reason` enthäl
**Behebung:** Collection-Lesen auf Admins beschränken oder mindestens den Grund schützen. Der bestehende serverseitige Slot-Endpunkt kann weiterhin ausschließlich verfügbare Zeiten herausgeben.
## 5. P2 — Registrierung und E-Mail-Wechsel umgehen die Versandlimits
## 5. P2 - Registrierung und E-Mail-Wechsel umgehen die Versandlimits
**Stellen:** `collections/Customers.ts:84`, `collections/Customers.ts:46`.
@@ -72,7 +72,7 @@ Die öffentliche Kundenerstellung löst unmittelbar eine Bestätigungs-E-Mail au
**Behebung:** Erstellung und E-Mail-Änderung vor dem Versand zentral pro IP, Konto und Zieladresse begrenzen. Regeln auf Collection-/Hook-Ebene oder einem exklusiven, geschützten Einstiegspunkt durchsetzen, sodass REST und GraphQL sie nicht umgehen können.
## 6. P2 — Ein bestätigtes Konto kann beliebig viele identische Buchungsanfragen erzeugen
## 6. P2 - Ein bestätigtes Konto kann beliebig viele identische Buchungsanfragen erzeugen
**Stellen:** `app/(payload)/api/booking/request/route.ts:75`, `collections/BookingRequests.ts:163`.