Commit graph

13 commits

Author SHA1 Message Date
Kundencenter
5ec8a526b3 fix(audit): audit_events auf DB-Ebene unveränderlich machen (append-only)
Nightbot-Befund #34 (Teil 1 von 2 – "eigene DB-Rolle für Audit ohne
UPDATE/DELETE"): eine echte separate DB-Rolle nur für Audit-Schreibzugriffe
ist mit dem bestehenden Muster (audit() schreibt oft in derselben
Transaktion wie die Fachaktion, die sie protokolliert, über dieselbe
Connection) nicht sauber vereinbar, ohne diese Atomarität zu verlieren
oder alle ~50 Tabellen einzeln neu zu berechtigen (MySQL/MariaDB kann
eine datenbankweite Berechtigung nicht durch eine engere Tabellen-
Berechtigung "überschreiben" – Rechte sind additiv, nicht spezifischer
gewinnt).

Stattdessen: BEFORE UPDATE/DELETE-Trigger auf audit_events, die beides
unabhängig vom verbindenden DB-Nutzer grundsätzlich verweigern (Migration
033). INSERT/SELECT bleiben uneingeschränkt möglich – genau das, was
audit()/verifyAuditChain() je brauchen. TRUNCATE bleibt technisch möglich
(feuert keine Trigger, betrifft nur die Testdatenbank-Zurücksetzung
zwischen Testdateien), DROP TABLE weiterhin auch – echte Kompromittierung
der DB-Zugangsdaten bleibt außerhalb dieser Verteidigungslinie, aber
versehentliche oder fehlerhafte Anwendungscode-Änderungen sind jetzt
ausgeschlossen.

test/core.test.ts angepasst: die bisherige Manipulationssimulation per
UPDATE ist jetzt selbst Teil des Tests (muss fehlschlagen); die Prüfung
"Hash-Kette erkennt Fälschung" simuliert stattdessen eine eingeschleuste
Fälschung per INSERT (weiterhin erlaubt).

Verifiziert: Testsuite (59/59, neuer Testfall für die Trigger-Ablehnung),
echte UPDATE/DELETE-Versuche gegen die Produktionsdatenbank beide
abgelehnt, Hash-Kette danach weiterhin intakt (192 Einträge), volles
Backup+Wiederherstellungstest gegen die echte Produktionsdatenbank
gefahren (Trigger werden korrekt mitgesichert/wiederhergestellt).

Aufbewahrungsfristen (DSGVO) und Export sind Teil desselben Tickets,
brauchen aber eine fachliche/rechtliche Entscheidung des Nutzers und
bleiben offen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 11:49:26 +02:00
Kundencenter
96df0c334a Rechnungen: Rabatt je Position 2026-09-28 11:01:19 +02:00
Kundencenter
e7e5f31ebe Rechnungen: Absender-/Empfängerdaten beim Ausstellen einfrieren, Statuswechsel atomar (behebt Codex-Fund #95) 2026-09-28 10:29:00 +02:00
Kundencenter
6fec6277f5 KeyHelp: Panel-Passwort neu vergeben und verschlüsselt hinterlegen (verblurrt wie Lizenzschlüssel) 2026-09-27 21:35:15 +02:00
Kundencenter
3a2864ee76 Rechnungen: Überblick über fällige/überfällige Rechnungen und Verträge 2026-09-27 21:19:48 +02:00
Kundencenter
5efe37ecc0 Hosting-Produkte: Staffelpreise nach Laufzeit (1/3/6/12/24 Monate) 2026-09-27 18:35:34 +02:00
Kundencenter
e0fd57532d Rechnungen: Positionen auch aus der Domain-Aufstellung übernehmen (Verkaufspreis) 2026-09-27 18:23:31 +02:00
Kundencenter
6f9efb91dc Rechnungen: Positionen direkt aus Produkt oder Vertrag übernehmen 2026-09-27 16:51:19 +02:00
Kundencenter
a1472617b9 Tickets: Bezug zu Ressource oder Domain wählen, Verknüpfung direkt aus der Domain-Aufstellung 2026-09-27 16:40:14 +02:00
Kundencenter
43dc5bc827 Rechnungsmodul: Entwurf/Ausstellen/Bezahlt/Storno, PDF, Firmenstammdaten 2026-09-27 09:05:13 +02:00
Kundencenter
012f0aa0db Ticket-Anhänge: Bilder/PDF hochladen und anzeigen (geprüft anhand der Dateikennung) 2026-09-27 08:53:27 +02:00
Kundencenter
ca5b48ab47 Support-Tickets: Modul, Oberfläche, Discord-Benachrichtigung 2026-09-27 08:36:18 +02:00
Kundencenter
4763548bfb Stand vor Einführung des Nacht-Agenten 2026-09-27 00:51:32 +02:00