fix: DSGVO-Rolle sieht Menüpunkte in Einstellungen wieder

System-Block in Settings.tsx war komplett in
hasPermission('settings:update') gewickelt. DSGVO-User haben aber nur
audit:* und gdpr:* Perms – kein settings:update – und sahen damit
weder DSGVO-Dashboard, Datenschutzerklärung, Vollmacht-Vorlage,
Impressum, Website-Datenschutz, E-Mail-Versandlog noch Audit-Log.

Outer-Check auf (settings:update || audit:read || gdpr:admin)
erweitert. Innere Per-Card-Checks bleiben unverändert, sodass jeder
User nur das sieht, wofür er Perms hat.

Backend-API mit reinem DSGVO-Token gegengetestet: alle 9 Endpoints
liefern 200 – Routes hatten kein Permission-Problem.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 08:44:48 +02:00
parent 6ae815393e
commit 95541e8ac4
2 changed files with 26 additions and 1 deletions
+19
View File
@@ -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
+7 -1
View File
@@ -88,7 +88,13 @@ export default function Settings() {
</div>
{/* 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')) && (
<div className="mb-8">
<h2 className="text-lg font-semibold mb-4 text-gray-700">System</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">