docs: TESTING.md mit Check-Listen für Security + Email-Log-System
Strukturierter Test-Katalog für manuelle Abnahmetests vor einem Release. Security-System (10 Abschnitte): - Login + Rate-Limiting - Passwort-Reset-Flow (Mitarbeiter + Portal) - Rate-Limiting Passwort-Reset - Berechtigungen (RBAC) - Portal-Isolation (DSGVO-kritisch) - Session-Invalidation - Audit-Log - DSGVO-Features (Export, Löschanfragen, Einwilligungen) - Verschlüsselte Credentials - DSGVO-Einwilligung sperrt Tabs für Mitarbeiter Email-Log-System (5 Abschnitte): - Email-Log-Seite (UI, Filter, Suche, Pagination) - Alle 6 Kontexte durchspielen: consent-link, authorization-request, customer-email, birthday-greeting, birthday-greeting-auto, password-reset - Fehlgeschlagener Versand wird geloggt (Test mit falschem SMTP-Passwort) - Details-Modal mit SMTP-Details - Automatisches Logging (Kontext, triggeredBy) Außerdem: Neue Kontexte in EmailLogs.tsx CONTEXT_LABELS ergänzt (birthday-greeting, birthday-greeting-auto, password-reset). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fcf4ecc324
commit
62debf19d0
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
## 🔜 Offen
|
||||
|
||||
### Email Log & System testen
|
||||
- Senden testen
|
||||
- Empfangen testen
|
||||
|
||||
### Security System testen
|
||||
### Manuelle Tests (vor Release durchklicken)
|
||||
Checklisten für Security + Email-Log-System stehen in **[docs/TESTING.md](../docs/TESTING.md)**.
|
||||
Einmal komplett durchlaufen vor v1.0.0-Release.
|
||||
|
||||
### 🚀 SaaS-Ausbau: Instance-per-Customer + Admin-Portal + GoCardless
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
# Manueller Test-Katalog (v1.0.0)
|
||||
|
||||
Checklisten für manuelle Abnahmetests vor einem Release. Durchläuft die kritischen
|
||||
Features Schritt für Schritt. Geschätzte Dauer für einen kompletten Durchlauf: ~60 Minuten.
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security-System
|
||||
|
||||
### 1. Login & Rate-Limiting
|
||||
|
||||
- [ ] **Mitarbeiter-Login** mit korrekten Credentials → Erfolgreich
|
||||
- [ ] **Mitarbeiter-Login** mit falschem Passwort → Fehlermeldung "Ungültige Anmeldedaten"
|
||||
- [ ] **Portal-Login** mit Kunden-E-Mail + Passwort → Erfolgreich ins Portal
|
||||
- [ ] **Rate-Limit Login**: 10× falsch nacheinander versuchen → Nach 10. Versuch: "Zu viele
|
||||
Login-Versuche. Bitte in 15 Minuten erneut versuchen."
|
||||
- [ ] **Rate-Limit zählt erfolgreiche Logins nicht**: 5× falsch, dann 1× korrekt, dann wieder
|
||||
5× falsch → immer noch erlaubt (weil erfolgreiche nicht zählen)
|
||||
|
||||
### 2. Passwort-Reset-Flow
|
||||
|
||||
- [ ] Auf Login-Seite: Link **"Passwort vergessen?"** sichtbar
|
||||
- [ ] Klick öffnet `/password-reset/request`
|
||||
- [ ] **Unbekannte E-Mail** eingeben → Trotzdem "E-Mail gesendet"-Bestätigung
|
||||
(User-Enumeration-Schutz: Backend verrät nicht, ob Email existiert)
|
||||
- [ ] **Bekannte Mitarbeiter-E-Mail** eingeben, Typ "Mitarbeiter" wählen → Reset-Mail geht raus
|
||||
- [ ] Reset-Link aus Mail öffnen → Formular "Neues Passwort"
|
||||
- [ ] **Passwörter stimmen nicht überein** → Fehlermeldung
|
||||
- [ ] **Passwort < 6 Zeichen** → Fehlermeldung
|
||||
- [ ] Gültiges Passwort setzen → "Passwort geändert", Redirect zu /login
|
||||
- [ ] **Neuer Login** mit dem neuen Passwort → Funktioniert
|
||||
- [ ] **Alter Session** (falls vorher eingeloggt) → Wurde gekickt, muss neu einloggen
|
||||
- [ ] **Reset-Link ein zweites Mal nutzen** → Fehlermeldung "Ungültiger oder bereits verwendeter Link"
|
||||
- [ ] **Reset-Link nach 2h+** nutzen → Fehlermeldung "Der Link ist abgelaufen"
|
||||
- [ ] Gleicher Flow für **Portal-Kunden** (Typ "Kunde" wählen)
|
||||
|
||||
### 3. Rate-Limiting Passwort-Reset
|
||||
|
||||
- [ ] 5× Reset-Anfrage für dieselbe E-Mail senden → OK
|
||||
- [ ] 6. Anfrage innerhalb einer Stunde → "Zu viele Passwort-Reset-Anfragen"
|
||||
|
||||
### 4. Berechtigungen (RBAC)
|
||||
|
||||
- [ ] **Admin**-User: kann Benutzer, Rollen, Einstellungen verwalten
|
||||
- [ ] **Mitarbeiter**-User: kann Kunden/Verträge bearbeiten, **keine** User-Verwaltung
|
||||
- [ ] **Mitarbeiter (Lesen)**: alles sichtbar, aber Buttons "Bearbeiten/Löschen" fehlen
|
||||
- [ ] **Portal-Kunde**: sieht **nur eigene** Verträge + Daten, nicht die anderer Kunden
|
||||
|
||||
### 5. Portal-Isolation (wichtig für DSGVO)
|
||||
|
||||
- [ ] Als Portal-Kunde A einloggen
|
||||
- [ ] In der URL manuell `/customers/999` eintippen (anderer Kunde) → Zugriff verweigert
|
||||
- [ ] `/contracts/999` (fremder Vertrag) → Zugriff verweigert
|
||||
- [ ] API-Call via Browser-Devtools `GET /api/customers/999` → 403 Forbidden
|
||||
- [ ] Nur mit **Vollmacht** (RepresentativeAuthorization) kann Kunde A die Daten von B sehen
|
||||
|
||||
### 6. Session-Invalidation
|
||||
|
||||
- [ ] Eingeloggt als Mitarbeiter, in 2 Browser-Tabs
|
||||
- [ ] Admin ändert Rolle des Mitarbeiters (User-Verwaltung)
|
||||
- [ ] Nächster Request im Tab → wird zum Login redirectet (tokenInvalidatedAt greift)
|
||||
|
||||
### 7. Audit-Log
|
||||
|
||||
- [ ] Einstellungen → Audit-Protokoll öffnen
|
||||
- [ ] Kunde anlegen → Eintrag mit Typ CREATE erscheint
|
||||
- [ ] Kunden-Feld ändern (z.B. Geburtsort) → UPDATE-Eintrag mit Vorher/Nachher-Details
|
||||
- [ ] Kunde löschen → DELETE-Eintrag
|
||||
- [ ] DSGVO-Export herunterladen → EXPORT-Eintrag
|
||||
- [ ] Filter nach Benutzer funktioniert
|
||||
- [ ] Filter nach Aktion funktioniert
|
||||
- [ ] Details-Modal zeigt Vorher/Nachher-Werte
|
||||
|
||||
### 8. DSGVO-Features
|
||||
|
||||
- [ ] Kunde einlegen → DSGVO-Tab
|
||||
- [ ] Datenexport ausführen → JSON-Datei mit allen Daten des Kunden
|
||||
- [ ] Löschanfrage erstellen → erscheint im DSGVO-Dashboard (Admin)
|
||||
- [ ] Anonymisierung ausführen → Kundendaten werden anonymisiert, aktive Verträge bleiben
|
||||
- [ ] Einwilligungen (alle 4 Typen) können pro Kunde gesetzt/widerrufen werden
|
||||
- [ ] PDF-Upload als Alternative zu Online-Einwilligungen → Haken werden auf GRANTED gesetzt
|
||||
- [ ] PDF löschen → Haken werden auf WITHDRAWN gesetzt
|
||||
|
||||
### 9. Verschlüsselte Credentials
|
||||
|
||||
- [ ] Ein Portal-Passwort (z.B. eines Anbieter-Zugangs) speichern
|
||||
- [ ] In der DB (z.B. via Prisma Studio oder DB-GUI) nachschauen:
|
||||
`portalPasswordEncrypted` darf **nicht im Klartext** sichtbar sein
|
||||
- [ ] Portal-Passwort in der UI anzeigen → wird korrekt entschlüsselt
|
||||
|
||||
### 10. DSGVO-Einwilligung Mitarbeiter
|
||||
|
||||
- [ ] Als Mitarbeiter Kunde öffnen OHNE Einwilligung → Tabs Zähler/Verträge/Bankkarten/Ausweise/Email gesperrt
|
||||
- [ ] Nach Einwilligung (alle 4 Haken oder PDF) → Tabs wieder zugänglich
|
||||
|
||||
---
|
||||
|
||||
## ✉ Email-Log-System
|
||||
|
||||
### 1. Email-Log-Seite öffnen
|
||||
|
||||
- [ ] Einstellungen → **Email-Protokoll** öffnen
|
||||
- [ ] Statistik-Cards werden angezeigt: Gesamt, Erfolgreich, Fehlgeschlagen, Letzte 24h
|
||||
- [ ] Log-Liste zeigt vergangene Versendungen
|
||||
- [ ] Filter: **Erfolgreich/Fehlgeschlagen**
|
||||
- [ ] Filter: **Kontext** (Datenschutz-Link, Vollmacht-Anfrage, Kunden-E-Mail, Geburtstagsgruß, Passwort-Reset)
|
||||
- [ ] Suche nach Empfänger-E-Mail oder Betreff
|
||||
- [ ] Pagination (Seite 1, 2, 3 …)
|
||||
- [ ] Klick auf Eintrag → Details-Modal mit SMTP-Info, Message-ID, ggf. Fehlermeldung
|
||||
|
||||
### 2. Erfolgreicher Versand loggen – alle Kontexte durchspielen
|
||||
|
||||
Für jeden Kontext: Aktion im CRM durchführen → danach im Email-Log prüfen,
|
||||
ob der Eintrag erstellt wurde.
|
||||
|
||||
#### Datenschutz-Link
|
||||
- [ ] Kunde öffnen → Einwilligungen/Datenschutz-Tab → "Link per Email senden"
|
||||
- [ ] Log-Eintrag mit Kontext "Datenschutz-Link", Empfänger = Kunden-E-Mail, Status ✓
|
||||
|
||||
#### Vollmacht-Anfrage
|
||||
- [ ] Kunde A mit Vertreter B → Vollmachten-Tab → "Anfrage per Email senden"
|
||||
- [ ] Log-Eintrag mit Kontext "Vollmacht-Anfrage"
|
||||
|
||||
#### Kunden-E-Mail (via Email-Client)
|
||||
- [ ] Kunde öffnen → Email-Tab → Mail verfassen und senden
|
||||
- [ ] Log-Eintrag mit Kontext "Kunden-E-Mail"
|
||||
|
||||
#### Geburtstagsgruß (manuell)
|
||||
- [ ] Kunde mit Geburtsdatum → Cake-Button → "Gruß jetzt senden" → Email
|
||||
- [ ] Log-Eintrag mit Kontext "Geburtstagsgruß (manuell)"
|
||||
|
||||
#### Geburtstagsgruß (automatisch)
|
||||
- [ ] Test-Kunde anlegen mit Geburtsdatum = heute
|
||||
- [ ] Auto-Geburtstagsgruß aktivieren (Cake-Button → Checkbox + Kanal "Email")
|
||||
- [ ] Server neu starten (Cron macht Catch-up nach 30s)
|
||||
- [ ] Nach ~1 Min: Log-Eintrag mit Kontext "Geburtstagsgruß (automatisch)"
|
||||
|
||||
#### Passwort-Reset
|
||||
- [ ] Logout → "Passwort vergessen?" → eigene Admin-E-Mail eingeben
|
||||
- [ ] Log-Eintrag mit Kontext "Passwort-Reset"
|
||||
|
||||
### 3. Fehlgeschlagener Versand loggen
|
||||
|
||||
- [ ] Temporär SMTP-Passwort ungültig machen (Einstellungen → Provider bearbeiten)
|
||||
- [ ] Beliebige E-Mail-Aktion auslösen (z.B. Datenschutz-Link senden)
|
||||
- [ ] Log-Eintrag mit Status ✗ und Fehlermeldung ("SMTP-Authentifizierung fehlgeschlagen")
|
||||
- [ ] Im Browser: Toast-Benachrichtigung mit Fehler erscheint
|
||||
- [ ] Passwort wieder korrigieren
|
||||
|
||||
### 4. Details-Modal
|
||||
|
||||
- [ ] Klick auf erfolgreichen Eintrag: Zeigt Absender, Empfänger, Betreff, SMTP-Server/Port/Verschlüsselung, Message-ID, ggf. SMTP-Server-Antwort
|
||||
- [ ] Klick auf fehlgeschlagenen Eintrag: Zusätzlich klare Fehlermeldung
|
||||
- [ ] Kunden-Link im Modal: bei customerId → klickbar zum Kunden
|
||||
|
||||
### 5. Automatisches Logging
|
||||
|
||||
- [ ] SMTP-Server, Port, Verschlüsselung werden bei jedem Versand geloggt
|
||||
- [ ] Kontext wird korrekt mitgegeben (nicht "unknown")
|
||||
- [ ] triggeredBy zeigt die auslösende User-E-Mail (nicht "cron" bei manuellen Aktionen)
|
||||
- [ ] Bei automatischen Aktionen (Cron): triggeredBy = "cron"
|
||||
|
||||
---
|
||||
|
||||
## Wie benutzen?
|
||||
|
||||
1. Diese Datei öffnen
|
||||
2. Von oben nach unten durchklicken, Häkchen setzen (oder im Editor durch `- [x]`)
|
||||
3. Gefundene Bugs in GitHub Issues oder direkt als Korrektur-Commit einbauen
|
||||
|
||||
Bei frisch geladener Datenbank (z.B. Dev-System): vorher 2-3 Test-Kunden mit vollständigen
|
||||
Stammdaten + mindestens 1 Email-Provider-Konfiguration anlegen.
|
||||
|
|
@ -13,6 +13,9 @@ const CONTEXT_LABELS: Record<string, string> = {
|
|||
'consent-link': 'Datenschutz-Link',
|
||||
'authorization-request': 'Vollmacht-Anfrage',
|
||||
'customer-email': 'Kunden-E-Mail',
|
||||
'birthday-greeting': 'Geburtstagsgruß (manuell)',
|
||||
'birthday-greeting-auto': 'Geburtstagsgruß (automatisch)',
|
||||
'password-reset': 'Passwort-Reset',
|
||||
};
|
||||
|
||||
export default function EmailLogs() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue