import prisma from '../lib/prisma.js'; import { SYSTEMROLLEN } from '../config/rechte-katalog.js'; /** * Prueft beim Start, ob die gesetzlich gebundenen Rechte ueberhaupt jemand * ausueben kann (Pentest R189-01). * * Hintergrund: `gdpr:export`, `gdpr:delete` und `gdpr:admin` haengen an den * Rollen DSGVO und Developer – nicht an der Admin-Rolle. Nach einem frischen * Seed war keine der beiden einem Konto zugewiesen. Ergebnis: Eine Auskunft * nach Art. 15 oder eine Loeschung nach Art. 17 konnte NIEMAND ausfuehren, * obwohl mehrere „Admin"-Konten existierten. Ein Ausfall mit Fristwirkung, * ausgeloest durch nichts weiter als eine Neuinstallation. * * Der Seed weist das Recht jetzt zu – aber nur bei NEUINSTALLATION. Auf einer * laufenden Datenbank aendert er nichts, und niemand merkt es, bis es darauf * ankommt. Deshalb diese Wache: Sie erkennt die ABWESENHEIT einer Faehigkeit, * so wie der Heartbeat das Ausbleiben eines Dienstkontos erkennt. * * Bewusst nur eine Meldung, keine automatische Vergabe: Rechte zu verteilen, * ohne dass ein Mensch es veranlasst hat, waere der groessere Fehler. */ /** Rechte, deren Fehlen ein rechtliches und kein technisches Problem ist. */ const PFLICHTRECHTE: Array<{ resource: string; action: string; wofuer: string }> = [ { resource: 'gdpr', action: 'export', wofuer: 'Auskunft nach Art. 15 DSGVO' }, { resource: 'gdpr', action: 'delete', wofuer: 'Löschung nach Art. 17 DSGVO' }, { resource: 'audit', action: 'read', wofuer: 'Prüfung des Audit-Protokolls' }, // Ohne dieses Recht laesst sich keine Rolle mehr anlegen oder aendern - die // Rechtevergabe waere eingefroren. Kein Rechtsproblem wie die beiden // darueber, aber dieselbe Bauart: eine Faehigkeit, deren Fehlen erst // auffaellt, wenn man sie braucht. { resource: 'roles', action: 'manage', wofuer: 'Pflege der Rollen und Rechte' }, ]; export async function pruefePflichtrechte(): Promise { try { const fehlend: string[] = []; for (const recht of PFLICHTRECHTE) { const traeger = await prisma.user.count({ where: { isActive: true, roles: { some: { role: { permissions: { some: { permission: { resource: recht.resource, action: recht.action }, }, }, }, }, }, }, }); if (traeger === 0) { fehlend.push(`${recht.resource}:${recht.action} (${recht.wofuer})`); } } // Zweite Wache: Stimmen die Systemrollen noch? // // Die versteckten Rollen werden ueber ihren NAMEN gefunden // (`findFirst({ where: { name: 'DSGVO' } })`). Fehlt eine, oder ist ihr // isSystem-Flag von Hand entfernt worden, laeuft der Notfallpfad ins // Leere - lautlos. Das hier ist die Meldung, die es dann geben soll. const rollenHinweise: string[] = []; for (const spec of SYSTEMROLLEN) { const rolle = await prisma.role.findUnique({ where: { name: spec.name } }); if (!rolle) { rollenHinweise.push(`Systemrolle „${spec.name}" fehlt.`); } else if (!rolle.isSystem) { rollenHinweise.push( `Systemrolle „${spec.name}" ist nicht als Systemrolle gekennzeichnet – ` + 'sie ist damit über die Rollenverwaltung änderbar.', ); } } if (rollenHinweise.length > 0) { console.warn( '\n' + '========================================================================\n' + ' ACHTUNG: Die Systemrollen stimmen nicht mit dem Katalog überein:\n' + rollenHinweise.map((h) => ` – ${h}\n`).join('') + '\n' + ' Beheben: npx tsx prisma/sync-roles.ts\n' + '========================================================================\n', ); } if (fehlend.length === 0) return; console.warn( '\n' + '========================================================================\n' + ' ACHTUNG: Für folgende Rechte gibt es KEIN aktives Konto:\n' + fehlend.map((f) => ` – ${f}\n`).join('') + '\n' + ' Das ist kein Fehler der Anwendung, sondern eine Lücke in der\n' + ' Rechtevergabe – und sie fällt erst auf, wenn eine Frist läuft.\n' + '\n' + ' Beheben: In der Benutzerverwaltung bei einem verantwortlichen Konto\n' + ' den Haken „DSGVO-Zugriff" setzen (Audit-Protokoll lesen und\n' + ' Datenschutz-Verwaltung). Für Eingriffe am Protokoll – versiegeln,\n' + ' aufräumen, Aufbewahrung ändern – zusätzlich „Audit-Betrieb".\n' + '\n' + ' Geht das nicht, weil niemand mehr die nötigen Rechte hat: Rechte\n' + ' lassen sich über die Oberfläche nur weitergeben, nicht erschaffen.\n' + ' Für die Erstvergabe gibt es den Weg über die Kommandozeile:\n' + ' docker compose exec backend \\\n' + ' npx tsx prisma/rolle-zuweisen.ts DSGVO\n' + ' („--liste" zeigt die vorhandenen Rollen.)\n' + '========================================================================\n', ); } catch (err) { // Eine Wache darf den Start nicht verhindern. Aber schweigen darf sie // auch nicht: „nicht geprüft" ist nicht dasselbe wie „nichts gefunden". console.warn( '[Pflichtrechte] Prüfung nicht möglich – der Zustand der Rechtevergabe ist ' + 'damit UNBEKANNT, nicht in Ordnung:', err instanceof Error ? err.message : err, ); } }