M5: Mitgliederverwaltung tenant- und rollenbasiert umstellen

- mitarbeiterverwalten.php war rein ueber Legacy-Admin gesperrt und haette
  neue SaaS-Mandanten ausgeschlossen; jetzt Rollen-/Legacy-Fallback wie in
  kaffeeliste.php (owner/admin).
- Anlegen/Bearbeiten/Aktivieren/Deaktivieren spiegeln transaktional nach
  participants (ledger_mirror_legacy_participant neu ergaenzt), damit
  Ledger-Ansichten sofort den aktuellen Mitgliederstand zeigen.
- Gespeicherte XSS-Luecke behoben: Name/E-Mail waren in Formular und Liste
  ungeschuetzt ausgegeben, jetzt ueber saas_html().
- Admin-Rollenvergabe bleibt bewusst Legacy-only (kein automatischer
  Login-Account ohne Einladungsflow); dokumentiert als offener Punkt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 23:49:33 +02:00
co-authored by Claude Sonnet 5
parent 968a55f442
commit de3dcee7ec
3 changed files with 138 additions and 41 deletions
+45 -2
View File
@@ -127,12 +127,52 @@ Alle drei Flows wurden gegen die Remote-Dev-Datenbank live per HTTP getestet
`letzteneintraege.php`) und anschließend wieder auf den Ausgangsstand
zurückgesetzt.
## Fortsetzung: Mitgliederverwaltung
Umgesetzte Dateien:
```text
mitarbeiterverwalten.php
app/ledger.php
```
Umfang:
- Zugriff nutzte bisher ausschließlich `checkKaffeelisteAdmin` und hätte neue
SaaS-Mandanten ohne Legacy-Mitarbeiterzeile ausgeschlossen. Jetzt gilt die
gleiche Rollen-/Fallback-Logik wie in `kaffeeliste.php`, mit den Rollen
`owner` und `admin` (nicht `treasurer`, da Mitgliederpflege sensibler ist
als reine Zahlungsvorgänge).
- Anlegen, Bearbeiten, Aktivieren und Deaktivieren schreiben weiterhin zuerst
in `kl_Mitarbeiter` und spiegeln danach in derselben Transaktion über die
neue Funktion `ledger_mirror_legacy_participant()` nach `participants`.
Ledger-Ansichten (Dashboard, Kaffeeliste, Teilnehmerauswertung) sehen neue
oder geänderte Mitglieder damit sofort, ohne auf einen manuellen Lauf von
`scripts/backfill-default-tenant.php` zu warten.
- Eine gespeicherte-XSS-Lücke wurde behoben: Name und E-Mail wurden beim
Bearbeiten-Formular und in der Mitgliederliste bisher ungeschützt
ausgegeben (nur `paypalname` war escaped). Beide Stellen nutzen jetzt
`saas_html()`.
- Live gegen die Dev-Datenbank getestet: Anlegen mit einem
HTML/Skript-Payload im Namen (korrekt escaped in der Ausgabe, korrekt
gespiegelt in `participants`), Deaktivieren (spiegelt `active = 0`).
Bewusst nicht umgesetzt:
- Der Haken "Administrator" bleibt ein reines Legacy-Feld auf
`kl_Mitarbeiter.admin` und wird nicht automatisch in eine
`tenant_memberships`-Rolle übersetzt. Das würde einen Login-Account ohne
Einladung/Passwort-Setzung anlegen, was ein eigenes, sauber zu
bauendes Einladungs-Flow braucht (E-Mail-Versand, Token, Passwortsetzung).
Admin-Rollen für neue SaaS-Nutzer laufen bis dahin weiter über
`scripts/backfill-default-tenant.php` oder die Registrierung.
## Noch offen
- Eigene PayPal-/Zahlungsbereich als eigenständiger App-Screen (aktuell nur im
Dashboard integriert).
- Mitgliederverwaltung tenant- und rollenbasiert umsetzen
(`mitarbeiterverwalten.php` ist noch nicht angefasst).
- Einladungs-Flow, um bestehenden Teilnehmern nachträglich einen
Login-Account mit `tenant_memberships`-Rolle zuzuweisen.
- Hinweise als tenant-spezifische Notices umsetzen.
- Export, Mail und Jahresprozesse bleiben M6-Themen.
@@ -144,3 +184,6 @@ zurückgesetzt.
- HTTP-Smoke: grün mit 23 geprüften Seiten.
- Live-Test der Schreibflows gegen die Dev-DB: Sammelstriche, Sammeleinzahlung
und Storno beider Buchungsarten erfolgreich geprüft.
- Live-Test der Mitgliederverwaltung gegen die Dev-DB: Anlegen (inklusive
XSS-Payload-Check), Deaktivieren, participants-Spiegelung erfolgreich
geprüft.