diff --git a/docs/todo.md b/docs/todo.md index 5f3eed49..e42a0f9f 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -97,6 +97,25 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung ## ✅ Erledigt +- [x] **🐛 DSGVO-Rolle: Menüpunkte in den Einstellungen unsichtbar** + - Symptom: User mit ausschließlich DSGVO-Rolle sah keinerlei + Karten unter Einstellungen → System (DSGVO-Dashboard, + Datenschutzerklärung, Vollmacht-Vorlage, Impressum, + Website-Datenschutz, E-Mail-Versandlog, Audit-Protokoll). + - Ursache: Der gesamte System-Block in `frontend/src/pages/Settings.tsx` + war in `hasPermission('settings:update')` eingewickelt. DSGVO + hat aber nur `audit:*` und `gdpr:*` Perms – kein `settings:update`. + - Fix: Outer-Check erweitert auf + `settings:update || audit:read || gdpr:admin`. Jede Karte hat + weiterhin ihren eigenen feingranularen Check; für DSGVO-User + erscheinen nur die DSGVO-/Audit-Karten. + - Backend-API mit reiner DSGVO-Rolle (kein Admin) live durchgetestet: + `/api/gdpr/dashboard`, `/api/audit-logs`, `/api/email-logs`, + `/api/gdpr/privacy-policy`, `/api/gdpr/authorization-template`, + `/api/gdpr/imprint`, `/api/gdpr/website-privacy-policy`, + `/api/gdpr/consents/overview`, `/api/gdpr/deletions` → alle 200. + Backend war nicht das Problem. + - [x] **🛡️ Login-Rate-Limit jetzt pro (IP + Email)-Tupel** - Vorher reine IP-basierte Sperre, was zwei Schwächen hatte: a) Familie hinter NAT: Max vertippt sich → Nina kommt nicht rein diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index 5f50e00b..1ed0b244 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -88,7 +88,13 @@ export default function Settings() { {/* System-Einstellungen */} - {hasPermission('settings:update') && ( + {/* + Outer-Check umfasst BEWUSST `settings:update`, `audit:read` und + `gdpr:admin`, sonst sieht die DSGVO-Rolle (nur audit/gdpr-Perms, kein + `settings:update`) die DSGVO-/Audit-Karten gar nicht. Jede Karte + innerhalb hat ihren eigenen feingranularen Check. + */} + {(hasPermission('settings:update') || hasPermission('audit:read') || hasPermission('gdpr:admin')) && (

System