All checks were successful
Container-Image bauen und veröffentlichen / build-and-push (push) Successful in 1m17s
Weiterleitungen hingen am containerinternen Port 3000: Die Middleware baute sie aus req.nextUrl.origin. Sie wertet jetzt X-Forwarded-Host und -Proto aus, ersatzweise den Host-Header. NEXTAUTH_URL ist damit optional und wird nicht mehr auf localhost:3000 vorbelegt. Der Container legt beim ersten Start selbst einen Admin an. Ohne ADMIN_PASSWORD wird ein Zufallspasswort erzeugt und einmalig ins Log geschrieben; bisher musste seed-admin von Hand nachgeholt werden. Ein mit anderem NEXTAUTH_SECRET verschlüsseltes Cookie erzeugte bei jedem Request einen JWTSessionError samt Stacktrace. Die Middleware löscht das Cookie jetzt beim Umleiten, der Logger meldet den Fall in einer Zeile. Die Prüfung nutzt das type-Feld, da Klassennamen im Produktions-Build minifiziert sind. Getestet auf Port 8080: Weiterleitung nach localhost:8080/auth/signin, Passwort im Erststart-Log, veraltetes Cookie mit Max-Age=0 entfernt, keine Stacktraces mehr. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
117 lines
4.0 KiB
Markdown
117 lines
4.0 KiB
Markdown
# Syncova Policies
|
||
|
||
Verwaltung und Veröffentlichung von Datenschutzerklärungen nach DSGVO (Art. 12ff.).
|
||
Öffentliche Übersicht für Betroffene, geschützter Admin-Bereich zur Pflege.
|
||
|
||
Next.js 15 (App Router) · React 19 · Tailwind CSS 4 · shadcn/ui · Prisma + SQLite · Auth.js
|
||
|
||
---
|
||
|
||
## Schnellstart (lokal)
|
||
|
||
```bash
|
||
npm install
|
||
cp .env.example .env # NEXTAUTH_SECRET eintragen (siehe unten)
|
||
npx prisma migrate deploy
|
||
npm run seed-admin # legt den ersten Admin an und zeigt das Passwort einmalig
|
||
npm run dev
|
||
```
|
||
|
||
Die Anwendung läuft anschließend auf http://localhost:3000, der Admin-Bereich
|
||
unter `/admin`.
|
||
|
||
### Umgebungsvariablen
|
||
|
||
| Variable | Pflicht | Bedeutung |
|
||
|---|---|---|
|
||
| `NEXTAUTH_SECRET` | ja | Signiert die Session-Token. Erzeugen mit `node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"` |
|
||
| `NEXTAUTH_URL` | nein | Nur nötig, wenn ein Reverse-Proxy keine `X-Forwarded-*`-Header setzt. Sonst erkennt die Anwendung Host und Port selbst – ein fester Wert erzwingt Weiterleitungen auf genau diesen Port. |
|
||
| `DATABASE_URL` | ja | SQLite-Pfad. Lokal `file:./dev.db`, im Container `file:/app/data/syncova.db` |
|
||
| `ADMIN_EMAIL` | nein | Vorgabe für `seed-admin` / `reset-admin` |
|
||
| `ADMIN_NAME` | nein | Anzeigename des Admin-Kontos |
|
||
| `ADMIN_PASSWORD` | nein | Leer lassen für ein generiertes Zufallspasswort |
|
||
|
||
> `.env` ist absichtlich nicht versioniert – sie enthält das Session-Secret.
|
||
> Ebenso wenig die SQLite-Datei, die Benutzerkonten und Passwort-Hashes enthält.
|
||
|
||
---
|
||
|
||
## Betrieb per Docker
|
||
|
||
```bash
|
||
docker run -d --name syncova-policies \
|
||
-p 3000:3000 \
|
||
-e NEXTAUTH_SECRET="$(node -e "console.log(require('crypto').randomBytes(32).toString('base64'))")" \
|
||
-e NEXTAUTH_URL="https://datenschutz.example.de" \
|
||
-v syncova-data:/app/data \
|
||
git.jfritzsche.de/jf/syncova-policies:latest
|
||
```
|
||
|
||
Oder mit Compose:
|
||
|
||
```bash
|
||
export NEXTAUTH_SECRET="…"
|
||
export NEXTAUTH_URL="https://datenschutz.example.de"
|
||
docker compose up -d
|
||
```
|
||
|
||
Beim Start wendet der Container ausstehende Migrationen selbst an
|
||
(`prisma migrate deploy`). Die Datenbank liegt im Volume unter `/app/data` –
|
||
**ohne dieses Volume gehen alle Daten beim Neustart verloren.**
|
||
|
||
Ersten Admin-Zugang anlegen:
|
||
|
||
```bash
|
||
docker exec -it syncova-policies node scripts/seed-admin.js
|
||
```
|
||
|
||
Passwort zurücksetzen:
|
||
|
||
```bash
|
||
docker exec -it syncova-policies node scripts/reset-admin.js --email admin@example.de
|
||
```
|
||
|
||
---
|
||
|
||
## Datenpflege
|
||
|
||
Datenschutzerklärungen werden normalerweise im Admin-Bereich gepflegt. Für
|
||
Massenimporte gibt es zwei Wege:
|
||
|
||
| Befehl | Zweck |
|
||
|---|---|
|
||
| `npm run import-policy -- data/policies/<datei>.json` | Einzelne Erklärung aus JSON importieren (`--update` überschreibt) |
|
||
| `npm run analyze-pdfs` | PDFs in `data/import/` analysieren, ohne zu schreiben |
|
||
| `npm run import-pdfs` | Alle PDFs aus `data/import/` importieren (`--dry-run`, `--public`) |
|
||
|
||
Der PDF-Import ist auf die Merkblatt-Vorlage des Amtes Leezen zugeschnitten
|
||
(`scripts/lib/pdf-policy.js`). Er vergleicht den Textbaustein-Teil jedes
|
||
Dokuments gegen ein Referenzdokument und meldet jede Abweichung, statt sie
|
||
stillschweigend zu übernehmen. Importierte Datensätze werden am Titel erkannt
|
||
und aktualisiert, nicht dupliziert.
|
||
|
||
---
|
||
|
||
## Veröffentlichung des Images
|
||
|
||
`.gitea/workflows/publish-image.yml` baut bei jedem Push auf `main` sowie bei
|
||
`v*`-Tags ein Image und lädt es in die Gitea-Registry.
|
||
|
||
Voraussetzung: im Repository unter **Settings → Actions → Secrets** ein Secret
|
||
`REGISTRY_TOKEN` mit einem Token hinterlegen, das `write:package` darf.
|
||
|
||
---
|
||
|
||
## Projektstruktur
|
||
|
||
```
|
||
app/ Routen (öffentlich, /admin, /auth, /api)
|
||
components/ UI-Komponenten; components/ui = shadcn/ui
|
||
hooks/ SWR-Datenzugriff, Theme
|
||
lib/ Prisma/Auth-Helfer, Markdown, Formatierung
|
||
prisma/ Schema und Migrationen
|
||
scripts/ Admin- und Importskripte
|
||
data/import/ Quell-PDFs für den Massenimport
|
||
data/policies/ Aufbereitete Datensätze als JSON
|
||
```
|