# Übersicht: Verschlüsselung personenbezogener Daten & Security-Informationen

## 📋 Inhaltsverzeichnis
1. [Verschlüsselte Daten](#verschlüsselte-daten)
2. [Verschlüsselungstechnologie](#verschlüsselungstechnologie)
3. [Authentifizierung & Autorisierung](#authentifizierung--autorisierung)
4. [API-Endpunkte & Zugriffsschutz](#api-endpunkte--zugriffsschutz)
5. [Rollen & Berechtigungen](#rollen--berechtigungen)
6. [Session-Management](#session-management)
7. [Umgebungsvariablen](#umgebungsvariablen)
8. [Dateisystem-Struktur](#dateisystem-struktur)
9. [Externe Dependencies](#externe-dependencies)
10. [Sicherheitsrichtlinien](#sicherheitsrichtlinien)

---

## ✅ Verschlüsselte Daten

### Kritische Dateien mit personenbezogenen Daten:

1. **users.json** - Benutzerdaten
   - E-Mail-Adressen
   - Namen
   - Passwort-Hashes (bcrypt)
   - Rollen (Array)
   - Telefonnummern
   - Aktivierungsstatus

2. **members.json** - Mitgliederdaten
   - Namen
   - E-Mail-Adressen
   - Telefonnummern
   - Adressen
   - Geburtsdaten
   - Notizen

3. **newsletter-posts.json** - Newsletter-Posts
   - Empfängerlisten (E-Mail-Adressen)
   - Post-Inhalte
   - Metadaten

4. **newsletter-subscribers.json** - Newsletter-Abonnenten
   - E-Mail-Adressen
   - Namen
   - Bestätigungsstatus
   - Abonnement-Gruppen
   - Tokens (Bestätigung, Abmeldung)

5. **sessions.json** - Session-Tokens
   - User-IDs
   - JWT-Tokens
   - Erstellungs- und Ablaufzeiten

6. **membership-applications/*.json** - Mitgliedschaftsanträge
   - Vollständige Antragsdaten (verschlüsselt als `encryptedData`)
   - Persönliche Informationen
   - Kontaktdaten

### ⚠️ Enthält personenbezogene Daten, aber weniger kritisch:

1. **config.json** - Konfigurationsdatei
   - E-Mail-Adressen von Vorstand und Website-Verantwortlichem
   - Diese sind öffentliche Kontaktdaten, die auf der Website angezeigt werden
   - Könnte optional verschlüsselt werden, ist aber nicht kritisch

### ✅ Keine personenbezogenen Daten:

- **news.json** - Nur Autor-Name, keine E-Mail
- **newsletter-groups.json** - Nur Metadaten (Gruppenname, Typ, etc.)
- **galerie-metadata.json** - Keine personenbezogenen Daten
- **termine.json** - Nur öffentliche Termine
- **mannschaften.csv** - Öffentliche Mannschaftsinformationen

---

## 🔐 Verschlüsselungstechnologie

### Algorithmus & Konfiguration:

- **Algorithmus**: AES-256-GCM (AEAD, Stand der Technik)
- **Schlüsselableitung**: PBKDF2 mit SHA-512
- **Iterationen**: 100.000 Runden
- **Salt-Länge**: 32 Bytes (zufällig pro Verschlüsselung)
- **IV-Länge**: 12 Bytes (zufällig pro Verschlüsselung)
- **Auth-Tag**: 16 Bytes (GCM)
- **Format**: `v2:` + Base64-kodiert (Salt + IV + Auth-Tag + Ciphertext)
- **Rückwärtskompatibilität**: bestehende, ältere Daten ohne Prefix werden weiterhin entschlüsselt (legacy AES-256-CBC)

### Verschlüsselungsschlüssel:

- **Umgebungsvariable**: `ENCRYPTION_KEY`
- **Standardwert (Development)**: `local_development_encryption_key_change_in_production`
- **⚠️ WICHTIG**: Muss in Produktion geändert werden!
- **Speicherort**: `.env` Datei (nicht in Git)

### Verschlüsselungsfunktionen:

- `encrypt(text, password)` - Verschlüsselt einen Text
- `decrypt(encryptedData, password)` - Entschlüsselt einen Text
- `encryptObject(obj, password)` - Verschlüsselt ein JSON-Objekt
- `decryptObject(encryptedData, password)` - Entschlüsselt ein JSON-Objekt

**Datei**: `server/utils/encryption.js`

---

## 🔑 Authentifizierung & Autorisierung

### Passwort-Hashing:

- **Algorithmus**: bcrypt
- **Rounds**: 10
- **Bibliothek**: `bcryptjs` v2.4.3

### JWT-Tokens:

- **Bibliothek**: `jsonwebtoken` v9.0.2
- **Algorithmus**: HS256 (HMAC SHA-256)
- **Secret**: `JWT_SECRET` aus Umgebungsvariablen
- **Standardwert (Development)**: `harheimertc-secret-key-change-in-production`
- **Gültigkeitsdauer**: 7 Tage
- **Payload**: `{ id, email, roles }`

### Cookie-Konfiguration:

- **Name**: `auth_token`
- **HttpOnly**: `true` (verhindert JavaScript-Zugriff)
- **Secure**: `true` in Produktion (konfigurierbar via `COOKIE_SECURE`)
- **SameSite**: `strict` in Produktion (konfigurierbar via `COOKIE_SAMESITE`)
- **MaxAge**: 7 Tage (604.800 Sekunden)

### Rate Limiting / Brute-Force-Schutz:

- **Login**: IP- und Account-basiertes Rate Limiting mit Lockout + Backoff (`/api/auth/login`)
- **Passwort-Reset**: IP- und Account-basiertes Rate Limiting (`/api/auth/reset-password`)
- **Newsletter**: Rate Limits für Subscribe/Unsubscribe/Check (`/api/newsletter/*`)

### Passwortprüfung (HaveIBeenPwned):

- Optional aktivierbar via `HIBP_ENABLED=true`
- Implementiert per k-Anonymity (Pwned Passwords „range“ API)

### Audit-Logging (Security Operations):

- Audit-Events werden als JSONL in `server/data/audit.log.jsonl` geschrieben (abschaltbar via `AUDIT_LOG_ENABLED=false`)
- Enthält u.a. Login-Erfolg/Fehlschlag, Passwort-Reset Requests, Rollenänderungen, User-Freischaltung/Deaktivierung/Ablehnung

### Authentifizierungs-Endpunkte:

- `POST /api/auth/login` - Login mit E-Mail/Passwort
- `POST /api/auth/logout` - Logout (löscht Session)
- `POST /api/auth/register` - Registrierung (erfordert Admin-Freischaltung)
- `POST /api/auth/reset-password` - Passwort-Reset
- `GET /api/auth/status` - Prüft aktuellen Auth-Status

### Passkeys (WebAuthn):

- **Ziel**: Passwortlose Anmeldung ohne zweiten Faktor (Passkey = starker Login am Gerät)
- **Registration** (nur für eingeloggte Nutzer im Profil):
  - `POST /api/auth/passkeys/registration-options`
  - `POST /api/auth/passkeys/register`
- **Login** (öffentlich):
  - `POST /api/auth/passkeys/authentication-options`
  - `POST /api/auth/passkeys/login`
- **Verwaltung**:
  - `GET /api/auth/passkeys/list`
  - `POST /api/auth/passkeys/remove`

### Passkey-Recovery (E-Mail-Link):

- **Ziel**: Wenn der Passkey verloren geht (neues Gerät/Crash), kann ein neuer Passkey **hinzugefügt** werden.
- **Sicherheitsannahme**: Zugriff auf das E-Mail-Postfach gilt als Recovery-Faktor (Account-Übernahme möglich bei kompromittierter Mailbox).
- **Ablauf**:
  - Request: `POST /api/auth/passkeys/recovery/request` (sendet Link; keine Account-Enumeration)
  - Options: `GET /api/auth/passkeys/recovery/options?token=...`
  - Complete: `POST /api/auth/passkeys/recovery/complete`
- **Eigenschaften**: Token ist kurzlebig (TTL), serverseitig nur gehasht gespeichert, one-time-use, rate-limited, audit-logged.

---

## 🛡️ API-Endpunkte & Zugriffsschutz

### Geschützte Routen:

- `/mitgliederbereich/*` - Erfordert Authentifizierung
- `/cms/*` - Erfordert Authentifizierung + spezifische Rollen

### Middleware:

**Datei**: `middleware/auth.js`

- Prüft Authentifizierung für geschützte Routen
- Rollenbasierte Zugriffskontrolle für CMS-Bereich
- Redirect zu `/login` bei fehlender Authentifizierung

### API-Endpunkt-Kategorien:

#### Öffentliche Endpunkte (keine Authentifizierung):
- `GET /api/news-public` - Öffentliche News
- `GET /api/termine` - Öffentliche Termine
- `GET /api/spielplaene` - Spielpläne
- `GET /api/galerie/list` - Galerie-Liste (mit Zugriffskontrolle)
- `GET /api/galerie/[id]` - Einzelbild (mit Zugriffskontrolle)
- `POST /api/newsletter/subscribe` - Newsletter-Anmeldung
- `GET /api/newsletter/confirm` - Newsletter-Bestätigung
- `GET /api/newsletter/unsubscribe` - Newsletter-Abmeldung
- `POST /api/newsletter/unsubscribe-by-email` - Abmeldung per E-Mail
- `GET /api/newsletter/groups/public-list` - Öffentliche Newsletter-Gruppen
- `GET /api/newsletter/check-subscription` - Prüft Abonnement-Status
- `POST /api/contact` - Kontaktformular

#### Authentifizierte Endpunkte (erfordern Login):

**Mitgliederbereich:**
- `GET /api/members` - Mitgliederliste (mit Rollenprüfung)
- `GET /api/profile` - Eigenes Profil
- `PUT /api/profile` - Profil bearbeiten
- `GET /api/news` - Interne News
- `POST /api/news` - News erstellen (admin/vorstand)
- `DELETE /api/news` - News löschen (admin/vorstand)

**CMS-Endpunkte (admin/vorstand):**
- `GET /api/cms/users/list` - Benutzerliste
- `POST /api/cms/users/approve` - Benutzer freischalten
- `POST /api/cms/users/update-role` - Rolle ändern
- `POST /api/cms/users/deactivate` - Benutzer deaktivieren
- `POST /api/cms/users/reject` - Registrierung ablehnen
- `PUT /api/config` - Konfiguration bearbeiten
- `POST /api/cms/save-csv` - CSV speichern
- `POST /api/cms/upload-spielplan-pdf` - Spielplan hochladen
- `POST /api/cms/satzung-upload` - Satzung hochladen
- `POST /api/members` - Mitglied hinzufügen/bearbeiten
- `DELETE /api/members` - Mitglied löschen
- `POST /api/members/bulk` - Bulk-Import
- `POST /api/personen/upload` - Personenbild hochladen
- `POST /api/galerie/upload` - Galeriebild hochladen
- `DELETE /api/galerie/[id]` - Galeriebild löschen
- `POST /api/termine-manage` - Termin erstellen/bearbeiten
- `DELETE /api/termine-manage` - Termin löschen
- `GET /api/termine-manage` - Termine verwalten
- `GET /api/membership/applications` - Mitgliedschaftsanträge
- `POST /api/membership/generate-pdf` - PDF generieren
- `GET /api/membership/download/[id]` - PDF herunterladen
- `PUT /api/membership/update-status` - Status aktualisieren

**Newsletter-Endpunkte (admin/vorstand/newsletter):**
- `GET /api/newsletter/groups/list` - Newsletter-Gruppen auflisten
- `POST /api/newsletter/groups/create` - Gruppe erstellen
- `GET /api/newsletter/groups/[id]/posts/list` - Posts auflisten
- `POST /api/newsletter/groups/[id]/posts/create` - Post erstellen und versenden
- `GET /api/newsletter/groups/[id]/subscribers/list` - Abonnenten auflisten
- `POST /api/newsletter/groups/[id]/subscribers/add` - Abonnent hinzufügen
- `POST /api/newsletter/groups/[id]/subscribers/remove` - Abonnent entfernen

### Zugriffskontrolle:

- **Helper-Funktionen**: `hasRole()`, `hasAnyRole()`, `hasAllRoles()` in `server/utils/auth.js`
- **Token-Validierung**: `getUserFromToken()` prüft JWT und lädt Benutzer
- **Rollenprüfung**: Alle geschützten Endpunkte prüfen Rollen vor Ausführung

---

## 👥 Rollen & Berechtigungen

### Verfügbare Rollen:

1. **mitglied** (Standard)
   - Zugriff auf Mitgliederbereich
   - Eigene Profilansicht und -bearbeitung
   - Mitgliederliste (ohne Kontaktdaten)
   - Interne News lesen

2. **vorstand**
   - Alle Mitglieder-Berechtigungen
   - Zugriff auf Kontaktdaten in Mitgliederliste
   - CMS-Zugriff (außer Benutzerverwaltung)
   - News erstellen/bearbeiten/löschen
   - Mitglieder verwalten
   - Termine verwalten
   - Galerie verwalten
   - Newsletter verwalten

3. **admin**
   - Alle Vorstand-Berechtigungen
   - Benutzerverwaltung
   - Rollenverwaltung
   - Konfiguration ändern
   - Mitgliedschaftsanträge verwalten

4. **newsletter**
   - Newsletter-Verwaltung (Gruppen, Posts, Abonnenten)
   - Kein Zugriff auf andere CMS-Funktionen
   - Kein Zugriff auf Mitgliederbereich (außer über Newsletter-Seite)

### Rollensystem:

- **Multi-Rollen-Support**: Benutzer können mehrere Rollen haben
- **Datenstruktur**: `roles: string[]` (Array von Rollen)
- **Migration**: Alte `role: string` wird automatisch zu `roles: [role]` migriert
- **Rollenprüfung**: `hasAnyRole(user, 'admin', 'vorstand')` prüft, ob Benutzer eine der Rollen hat

---

## 🔄 Session-Management

### Session-Speicherung:

- **Datei**: `server/data/sessions.json` (verschlüsselt)
- **Struktur**:
  ```json
  {
    "id": "session-id",
    "userId": "user-id",
    "token": "jwt-token",
    "createdAt": "ISO-timestamp",
    "expiresAt": "ISO-timestamp"
  }
  ```

### Session-Lebensdauer:

- **Gültigkeit**: 7 Tage
- **Ablauf**: Automatische Bereinigung abgelaufener Sessions
- **Logout**: Löscht Session aus Datei

### Session-Funktionen:

- `createSession(userId, token)` - Erstellt neue Session
- `deleteSession(token)` - Löscht Session
- `cleanExpiredSessions()` - Bereinigt abgelaufene Sessions

---

## 🌍 Umgebungsvariablen

### Erforderliche Variablen:

**Authentifizierung:**
- `JWT_SECRET` - Secret für JWT-Token-Signierung
  - Standard: `harheimertc-secret-key-change-in-production`
  - ⚠️ Muss in Produktion geändert werden!

**Verschlüsselung:**
- `ENCRYPTION_KEY` - Schlüssel für Datenverschlüsselung
  - Standard: `local_development_encryption_key_change_in_production`
  - ⚠️ Muss in Produktion geändert werden!

**E-Mail-Versand:**
- `SMTP_HOST` - SMTP-Server (Standard: `smtp.gmail.com`)
- `SMTP_PORT` - SMTP-Port (Standard: `587`)
- `SMTP_USER` - SMTP-Benutzername
- `SMTP_PASS` - SMTP-Passwort
- `SMTP_FROM` - Absender-E-Mail (Standard: `noreply@harheimertc.de`)

**Server-Konfiguration:**
- `NODE_ENV` - Umgebung (development/production)
- `PORT` - Server-Port (Standard: `3100`)
- `NUXT_PUBLIC_BASE_URL` - Basis-URL der Anwendung

### Konfigurationsdatei:

- **Datei**: `.env` (nicht in Git)
- **Beispiel**: `env.example`
- **⚠️ WICHTIG**: `.env` muss in `.gitignore` sein!

---

## 📁 Dateisystem-Struktur

### Datenverzeichnis:

```
server/data/
├── users.json                    # Verschlüsselt: Benutzerdaten
├── members.json                  # Verschlüsselt: Mitgliederdaten
├── sessions.json                 # Verschlüsselt: Session-Tokens
├── newsletter-subscribers.json   # Verschlüsselt: Newsletter-Abonnenten
├── newsletter-posts.json        # Verschlüsselt: Newsletter-Posts mit Empfängerlisten
├── newsletter-groups.json       # Unverschlüsselt: Newsletter-Gruppen-Metadaten
├── news.json                     # Unverschlüsselt: News (nur Autor-Name)
├── config.json                   # Unverschlüsselt: Konfiguration (öffentliche Kontaktdaten)
├── termine.json                  # Unverschlüsselt: Öffentliche Termine
├── galerie-metadata.json         # Unverschlüsselt: Galerie-Metadaten
├── membership-applications/      # Verschlüsselt: Mitgliedschaftsanträge
│   └── *.json
├── galerie/                      # Nicht öffentlich zugänglich
│   ├── originals/                # Originalbilder
│   └── previews/                 # Vorschaubilder (150x150px)
└── personen/                     # Nicht öffentlich zugänglich
    └── *.jpg/png                 # Personenbilder
```

### Upload-Verzeichnisse:

- **Galerie**: `server/data/galerie/originals/` und `server/data/galerie/previews/`
- **Personen**: `server/data/personen/`
- **PDFs**: `server/data/spielplaene/`, `server/data/satzung/`

### Zugriffsschutz:

- Upload-Verzeichnisse sind **nicht** direkt über Web-Server zugänglich
- Zugriff nur über API-Endpunkte mit Authentifizierung

---

## 📦 Externe Dependencies

### Sicherheitsrelevante Pakete:

**Authentifizierung & Verschlüsselung:**
- `bcryptjs` v2.4.3 - Passwort-Hashing
- `jsonwebtoken` v9.0.2 - JWT-Token-Generierung
- `crypto` (Node.js built-in) - Verschlüsselung

**E-Mail:**
- `nodemailer` v7.0.9 - E-Mail-Versand

**Datei-Upload:**
- `multer` v2.0.2 - Multipart-Form-Daten-Verarbeitung
- `sharp` v0.34.5 - Bildverarbeitung (Resize, EXIF-Korrektur)

**PDF:**
- `pdf-lib` v1.17.1 - PDF-Generierung
- `pdf-parse` v2.4.5 - PDF-Parsing

**Framework:**
- `nuxt` v4.1.3 - Vue.js Framework
- `vue` v3.5.22 - Frontend-Framework
- `pinia` v3.0.3 - State Management

### Sicherheits-Updates:

- Regelmäßige Updates empfohlen
- Prüfung auf bekannte Schwachstellen (npm audit)

---

## 🔒 Sicherheitsrichtlinien

### Passwort-Richtlinien:

- **Minimale Länge**: 6 Zeichen (empfohlen: mindestens 12)
- **Hashing**: bcrypt mit 10 Runden
- **Speicherung**: Nur Hash, niemals Klartext

### Token-Sicherheit:

- **HttpOnly Cookies**: Verhindert XSS-Angriffe
- **SameSite**: `lax` verhindert CSRF-Angriffe
- **Ablaufzeit**: 7 Tage (kann angepasst werden)

### Datenverschlüsselung:

- **At-Rest-Verschlüsselung**: Alle kritischen Daten verschlüsselt
- **Schlüsselverwaltung**: Schlüssel nur in `.env`, niemals in Git
- **Schlüsselrotation**: Regelmäßige Rotation empfohlen

### API-Sicherheit:

- **Authentifizierung**: Erforderlich für alle geschützten Endpunkte
- **Autorisierung**: Rollenbasierte Zugriffskontrolle
- **Input-Validierung**: Prüfung aller Eingaben
- **Rate Limiting**: Nicht implementiert (empfohlen für Produktion)

### Best Practices:

- ✅ Passwörter werden niemals im Klartext gespeichert
- ✅ Sensitive Daten sind verschlüsselt
- ✅ JWT-Tokens haben Ablaufzeit
- ✅ HttpOnly Cookies verhindern XSS
- ✅ Rollenbasierte Zugriffskontrolle
- ⚠️ Rate Limiting fehlt (empfohlen)
- ⚠️ HTTPS sollte in Produktion verwendet werden
- ⚠️ Secure-Flag für Cookies sollte in Production `true` sein

---

## 🧪 Test-Zugangsdaten

### Standard-Admin-Account:

**⚠️ NUR FÜR ENTWICKLUNG - MUSS IN PRODUKTION GEÄNDERT WERDEN!**

- **E-Mail**: `admin@harheimertc.de`
- **Passwort**: `admin123` (Standard, sollte geändert werden)
- **Rolle**: `admin`

### Passwort ändern:

```bash
node scripts/set-admin-password.js "neues-passwort"
```

### Test-Umgebung:

- **Development-Port**: `3100`
- **Base-URL**: `http://localhost:3100`
- **Standard-Secrets**: Siehe `env.example`

---

## 📝 Hinweise für Security-Tests

### Zu testende Bereiche:

1. **Authentifizierung**
   - Login/Logout-Funktionalität
   - Token-Validierung
   - Session-Management
   - Passwort-Reset-Mechanismus

2. **Autorisierung**
   - Rollenbasierte Zugriffskontrolle
   - API-Endpunkt-Zugriff
   - Frontend-Route-Zugriff
   - Multi-Rollen-Support

3. **Verschlüsselung**
   - Datenverschlüsselung/Entschlüsselung
   - Schlüsselverwaltung
   - Verschlüsselte Dateien

4. **Input-Validierung**
   - SQL-Injection (nicht relevant, keine DB)
   - XSS (Cross-Site-Scripting)
   - CSRF (Cross-Site-Request-Forgery)
   - File-Upload-Sicherheit

5. **Sensitive Daten**
   - Passwort-Hashing
   - Token-Sicherheit
   - Cookie-Konfiguration
   - Logging von sensiblen Daten

6. **API-Sicherheit**
   - Endpunkt-Zugriffskontrolle
   - Rate Limiting (fehlt)
   - Input-Sanitization
   - Error-Handling (keine sensiblen Informationen in Fehlermeldungen)

### Bekannte Limitierungen:

- ⚠️ Rate Limiting nicht implementiert
- ⚠️ HTTPS sollte in Produktion verwendet werden
- ⚠️ Secure-Flag für Cookies sollte in Production `true` sein
- ⚠️ Standard-Secrets müssen in Produktion geändert werden

---

**Letzte Aktualisierung**: 2024
**Verantwortlich**: Entwicklungsteam Harheimer TC
