DEV1.0: Initial commit - Workflow Portal with security fixes

- Backend: Express.js + PostgreSQL/SQLite with LDAP/AD integration
- Frontend: React 18 + Vite + TailwindCSS/DaisyUI
- Security fixes applied (2026-07 + 2026-08):
  - LDAP injection prevention, CSRF protection, HttpOnly cookies
  - Session hashing (SHA-256), account lockout, rate limiting
  - Input validation (zod), file upload security, CSP/HSTS headers
  - V3: express-rate-limit updated (ip-address SSRF fix)
  - V4: postcss updated (nanoid DoS fix)
  - V5: Rate-limit on /health endpoint
  - V6: Session rotation on login (session fixation prevention)
  - V9: Task values array limit (DoS prevention)
  - V10: Frontend XSS audit completed
- Docker: Multi-stage build, non-root user, PostgreSQL + backup service
This commit is contained in:
Kühn
2026-08-24 09:45:28 +02:00
commit 6be1791c62
103 changed files with 12253 additions and 0 deletions

165
info.md Normal file
View File

@@ -0,0 +1,165 @@
# Workflow Portal – Dokumentation
## Übersicht
Das Workflow Portal ist eine Web-Anwendung zur Verwaltung von Arbeitsvorlagen und Aufgaben, mit integrierter Active Directory / LDAP-Anbindung für die Nutzerverwaltung.
---
## Architektur
| Komponente | Technologie | Port |
|---|---|---|
| **Backend** | Express.js + SQLite3 + ldapjs | 5000 |
| **Frontend** | React 18 + Vite + TailwindCSS + DaisyUI | 5173 |
| **Prisma Studio** | Prisma v5.22.0 | 5555 |
| **Datenbank** | SQLite (`backend/data/workflow.db`) | – |
---
## Nutzerarten
### Lokale Nutzer
- Werden manuell im Portal angelegt
- Anmeldung mit **E-Mail + Passwort**
- Vollständig bearbeitbar (Name, E-Mail, Passwort, Rolle, Status)
- Können gelöscht werden
### Active Directory Nutzer
- Werden automatisch aus dem AD/LDAP synchronisiert
- Anmeldung mit **AD-Benutzeranmeldename (sAMAccountName) + AD-Passwort**
- Die Authentifizierung erfolgt direkt gegen den LDAP-Server
- **Bearbeitbar im Portal:** Rolle (admin/user) und Status (aktiv/inaktiv)
- **Schreibgeschützt:** Name, E-Mail, Anmeldename, Passwort (werden aus dem AD synchronisiert)
- **Nicht löschbar** im Portal – müssen im AD entfernt werden
> **Wichtig:** Lokal geänderte Rollen und Status werden beim nächsten LDAP-Sync **nicht** überschrieben. Name, E-Mail und Anmeldename werden jedoch bei jedem Sync aktualisiert.
---
## LDAP-Konfiguration
Die LDAP-Einstellungen werden über Umgebungsvariablen in der `.env`-Datei konfiguriert:
| Variable | Beschreibung | Beispiel |
|---|---|---|
| `LDAP_SERVER` | Hostname des LDAP-Servers | `PIDC02.seatle.intra` |
| `LDAP_PORT` | Port (389=LDAP, 636=LDAPS) | `636` |
| `LDAP_SEARCH_BASE` | Suchbasis für Nutzer | `DC=SEATLE,DC=INTRA` |
| `LDAP_DOMAIN` | Domäne (für Referenz) | `SEATLE` |
| `LDAP_IGNORE_CERT_ERRORS` | Zertifikatsprüfung überspringen | `true` / `false` |
| `LDAP_BIND_USER` | Service-Account (user@domain) | `MustermannM@seatle.intra` |
| `LDAP_BIND_PASSWORD` | Passwort des Service-Accounts | `Verwaltung1!` |
| `LDAP_SYNC_INTERVAL` | Sync-Intervall in ms (Standard: 300000 = 5 Min) | `300000` |
| `LDAP_FILTER` | LDAP-Suchfilter (leer = Standard) | leer |
| `LDAP_ATTRIBUTES` | LDAP-Attribute (kommagetrennt) | `mail,displayName,memberOf,distinguishedName,sAMAccountName` |
---
## Anmeldung
### Lokaler Admin
- **E-Mail:** `admin@workflow.local`
- **Passwort:** `1337`
### AD-Nutzer
- **Anmeldename:** sAMAccountName aus dem AD (z.B. `MustermannM`)
- **Passwort:** Das AD-Passwort des Nutzers
- Die Anmeldung erfolgt per LDAP-Bind direkt gegen den AD-Server
### Status-basierte Zugangsbeschränkung
- **aktiv:** Anmeldung erlaubt
- **inaktiv:** Anmeldung wird blockiert (gilt für lokale UND AD-Nutzer)
---
## Rollen
| Rolle | Berechtigungen |
|---|---|
| `admin` | Vollzugriff: Vorlagen erstellen/bearbeiten, Nutzerverwaltung, alle Aufgaben einsehen |
| `user` | Eingeschränkter Zugriff: Zugewiesene Vorlagen ausfüllen, eigene Aufgaben einsehen |
---
## LDAP-Sync Verhalten
Der Sync läuft automatisch alle 5 Minuten (konfigurierbar über `LDAP_SYNC_INTERVAL`).
### Was synchronisiert wird:
- **Neue AD-Nutzer** → werden in der Datenbank angelegt (Status: aktiv, Rolle: abgeleitet aus AD-Gruppen)
- **Bestehende AD-Nutzer** → Name und Anmeldename werden aktualisiert
- **Entfernte AD-Nutzer** → werden aus der Datenbank gelöscht (wenn sie nicht mehr im AD gefunden werden)
### Was NICHT überschrieben wird:
- **Rolle** (admin/user) – lokal geänderte Rollen bleiben erhalten
- **Status** (aktiv/inaktiv) – lokal geänderte Status bleiben erhalten
### Rollen-Ableitung aus AD-Gruppen:
- Nutzer in einer Admin-Gruppe (`admin`, `Domain Admins`, `Domänen-Admins`) → Rolle `admin`
- Alle anderen → Rolle `user`
---
## Docker
### Container starten
```bash
docker compose up -d --build
```
### Container stoppen
```bash
docker compose down
```
### Backend-Logs anzeigen
```bash
docker compose logs backend --tail 50
```
### Datenbank zurücksetzen
```bash
docker compose down
rm backend/data/workflow.db
docker compose up -d --build
```
---
## API-Endpunkte
### Auth
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| POST | `/api/auth/login` | Anmeldung (E-Mail/Username + Passwort) |
| POST | `/api/auth/register` | Neuen lokalen Nutzer registrieren |
### Nutzer
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET | `/api/users` | Alle Nutzer auflisten |
| POST | `/api/users` | Neuen lokalen Nutzer anlegen |
| PUT | `/api/users/:id` | Nutzer bearbeiten (AD: nur Rolle/Status) |
| DELETE | `/api/users/:id` | Lokalen Nutzer löschen (AD-Nutzer: 403) |
### AD-Status
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET | `/api/ad/status` | LDAP-Konfigurationsstatus |
### Vorlagen & Aufgaben
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| GET/POST | `/api/templates` | Vorlagen auflisten/erstellen |
| GET/PUT/DELETE | `/api/templates/:id` | Vorlage abrufen/ändern/löschen |
| GET/POST | `/api/tasks` | Aufgaben auflisten/erstellen |
| PUT | `/api/tasks/:id` | Aufgabe aktualisieren |
---
## Sicherheitshinweise
- **LDAP_IGNORE_CERT_ERRORS=true** deaktiviert die Zertifikatsprüfung. In Produktion sollte das CA-Zertifikat des LDAP-Servers im Container installiert werden.
- Passwörter werden als Klartext in der SQLite-Datenbank gespeichert (nur für lokale Nutzer). Für Produktion sollte bcrypt o.ä. verwendet werden.
- AD-Passwörter werden **nicht** gespeichert – die Authentifizierung erfolgt direkt per LDAP-Bind.