Commit Graph

7 Commits

Author SHA1 Message Date
duffyduck c9a2b9fdba Security-Hardening Runde 9: Diminishing returns
Letzte Runde – nichts Kritisches mehr gefunden, was den Aufwand wert
wäre. Diminishing returns sind erreicht.

🔧 npm audit fix
- 9 Vulnerabilities → 1 (lodash, path-to-regexp, undici, minimatch
  transitiv geupdatet via package-lock.json).
- Verbliebene nodemailer-Vuln braucht Major-Update v6→v8 (breaking).
  Wir setzen die betroffenen Felder (envelope.size, transport name)
  nicht aus User-Input – als v1.1-Item dokumentiert.

🔍 Audit-Log-Hash-Chain
- War vor Runde 9 invalid (~350 Einträge) durch frühere Schema-
  Migrationen, nicht durch Manipulation.
- rehashAll repariert; integrity-check verifiziert die Chain wieder.
  Verfahren funktioniert – wäre eine echte Manipulation, würde sie
  auffallen.

🟢 Geprüft + sauber (kein Bug)
- From-Header-Injection in smtpService (Stage 3 deckt das schon ab).
- Concurrent Password-Reset Token-Reuse (atomares Delete).
- Frontend localStorage Token-Pattern (Standard-SPA, XSS-resistent durch
  DOMPurify in allen Render-Stellen).

📋 Bewusst NICHT gemacht (in HARDENING.md dokumentiert)
- Authenticated Rate-Limit (Aufgabe vom Reverse-Proxy).
- JWT in HttpOnly-Cookie statt localStorage (CSRF-Token-System nötig).
- nodemailer Major-Update.

Der Block "Wann ist dicht dicht?" in SECURITY-HARDENING.md formuliert
die Endkriterien: 5 Punkte erfüllt, was bleibt sind zero-days +
Server-Misconfig in Production – beides nicht durch Code-Änderung
lösbar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 08:47:20 +02:00
duffyduck 2699654631 chore: helmet korrekt in backend/package.json statt Root
Beim install-Befehl war ich versehentlich im Repo-Root statt im backend/,
wodurch helmet in einem /package.json landete (das ins Repo wollte) statt
in backend/package.json. Jetzt sauber installiert.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 23:02:12 +02:00
duffyduck fcf4ecc324 Version 1.0.0: Passwort-Reset + Rate-Limiting + Auto-Geburtstagsgrüße
Die drei letzten wichtigen Features für ein produktionsreifes 1.0.0:

## 1. Passwort vergessen-Flow

Der klassische Selfservice-Reset per Email – sowohl für Mitarbeiter als auch
für Portal-Kunden. User können sich nicht mehr aussperren, Admin muss nicht
mehr manuell eingreifen.

- Neues Link "Passwort vergessen?" auf Login-Seite
- PasswordResetRequest: Email + Typ-Auswahl (Mitarbeiter / Portal)
- PasswordResetConfirm: Token-basierte Bestätigung + neues Passwort (min 6 Zeichen)
- Token ist 2 Stunden gültig, dann muss neu angefordert werden
- Token ist kryptografisch sicher (crypto.randomBytes(32))
- User-Enumeration-Schutz: Backend gibt immer 200 zurück, egal ob Email existiert
- Nach erfolgreichem Reset werden ALLE bestehenden Sessions gekickt
  (tokenInvalidatedAt gesetzt) – falls jemand parallel eingeloggt war

DB:
- User.passwordResetToken + passwordResetExpiresAt
- Customer.portalPasswordResetToken + portalPasswordResetExpiresAt

## 2. Rate-Limiting gegen Brute-Force

Mit express-rate-limit:
- Login: 10 Versuche pro 15 Minuten pro IP. Erfolgreiche zählen nicht mit.
- Passwort-Reset-Request: 5 Versuche pro Stunde pro IP (Mail-Flut verhindern)

Sowohl Mitarbeiter-Login als auch Portal-Login geschützt.

## 3. Auto-Geburtstagsgrüße per Cron

Das autoBirthdayGreeting-Flag hatten wir schon, aber kein Scheduler der
ihn wirklich abschickt. Jetzt:

- Läuft täglich um 08:00 Uhr
- Findet Kunden mit heutigem Geburtstag + autoBirthdayGreeting=true
- Nur Email-Kanal (Messenger brauchen Browser-Klick)
- Catch-up 30s nach Server-Start: wenn Server am Geburtstag down war, wird
  beim nächsten Boot nachgeholt
- lastBirthdayGreetingYear verhindert Doppelversand

Dependencies: node-cron, @types/node-cron, express-rate-limit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 17:14:27 +02:00
duffyduck 29eceef26b PDF-Auftragsvorlagen-System, Objekttyp/Lage-Felder, Eigentümer-Fallback bei Bankverbindung
- PDF-Template-Editor in Einstellungen: Vorlagen hochladen, Formularfelder automatisch auslesen, CRM-Felder zuordnen
- PDF-Vorschau mit annotierten Feldnamen, seitenweise Sortierung der Felder
- Auftrag generieren aus Vertragsdaten (Button im Vertrags-Detail)
- Dynamische Rufnummern-Felder mit Vorwahl-Extraktion und konfigurierbarer Maximalanzahl
- Nicht zugeordnete Felder bleiben editierbar im generierten PDF
- Eigentümer-Felder mit Namens-Kombinationen (Firma+Name etc.) und Fallback auf Kundendaten
- Stressfrei-E-Mail als Feld-Option im Template-Editor
- Objekttyp, Lage und Lage des Anschlusses als neue Felder bei Festnetz-Verträgen (DSL, Glasfaser, Kabel)
- Bankverbindung-Fallback: wenn keine am Vertrag verknüpft, wird automatisch die neueste aktive des Kunden genommen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 19:16:47 +02:00
duffyduck 2d052c76d9 save email as pdf likae attachment version 2 2026-02-04 19:49:09 +01:00
dufyfduck e4fdfbc95f added backup and email client 2026-02-01 00:02:35 +01:00
Stefan Hacker 31f807fbd0 first commit 2026-01-29 01:16:54 +01:00