Schritt 28 — CSRF-Schutz (Double Submit Cookie Pattern): - server/middleware/csrf.js: generiert 32-Byte-Token, speichert in Session + Cookie; validiert X-CSRF-Token-Header auf POST/PUT/PATCH/DELETE via timingSafeEqual - server/auth.js: CSRF-Token beim Login erzeugen und als Cookie setzen - public/api.js: getCsrfToken() liest Cookie; apiFetch() sendet Header auf state-ändernden Requests automatisch Schritt 29 — Globaler Rate-Limiter: - server/index.js: apiLimiter (300 req/min/IP) auf allen /api/-Routen; ergänzt den bestehenden loginLimiter (5 req/min) Schritt 27 — Zentralisierte Eingabe-Validierung: - server/middleware/validate.js: str(), oneOf(), date(), time(), num(), color(), collectErrors() mit einheitlichen Längengrenzen (MAX_TITLE=200, MAX_TEXT=5000) - server/routes/tasks.js: validateTaskInput() nutzt nun validate.js Schritt 31 — Frontend Error Boundary: - public/router.js: window.onerror + unhandledrejection-Handler zeigen Toast Schritt 33 — README.md: - Setup-Anleitung (Docker + Node.js), Nginx-Config, User-Verwaltung, Umgebungsvariablen-Referenz, Backup, Sicherheitsübersicht Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Oikos — Selbstgehosteter Familienplaner
Oikos ist eine self-hosted Progressive Web App für Familien. Sie läuft vollständig auf deinem eigenen Server — keine Cloud-Abhängigkeiten, keine Datenweitergabe.
Features
- Dashboard — Begrüßung, Wetter-Widget, anstehende Termine, dringende Aufgaben, Essen, Pinnwand
- Aufgaben — Listenansicht (Kategorie/Fälligkeit), Kanban-Board, Teilaufgaben, Swipe-Gesten, wiederkehrende Aufgaben
- Einkaufslisten — Mehrere Listen, Kategorien, Essensplan-Integration
- Essensplan — Wochenansicht, Zutatenverwaltung, Übertrag auf Einkaufsliste
- Kalender — Monats-/Wochen-/Tages-/Agenda-Ansicht, Familienfarben, wiederkehrende Termine
- Pinnwand — Farbige Sticky Notes mit Markdown-Light
- Kontakte — Wichtige Kontakte mit Kategorie-Filter, tel:/mailto:/Maps-Links
- Budget — Einnahmen/Ausgaben, Monatsauswertung, CSV-Export
- PWA — Offline-fähig, installierbar auf iOS/Android/Desktop
Voraussetzungen
- Docker & Docker Compose (empfohlen) oder Node.js ≥ 20
- Ein Linux-Server hinter Nginx Reverse Proxy mit SSL (empfohlen)
Schnellstart mit Docker (empfohlen)
1. Repository klonen
git clone https://github.com/ulsklyc/oikos.git
cd oikos
2. Umgebungsvariablen konfigurieren
cp .env.example .env
Pflichtfelder in .env anpassen:
SESSION_SECRET=ein-langer-zufaelliger-string-min-32-zeichen
DB_ENCRYPTION_KEY=ein-starkes-passwort-fuer-die-datenbank
Optional: Wetter-Widget aktivieren
OPENWEATHER_API_KEY=dein-api-key-von-openweathermap.org
OPENWEATHER_CITY=Berlin
3. Starten
docker compose up -d
Die App ist unter http://localhost:3000 erreichbar.
4. Erster Login
Beim ersten Start wird automatisch ein Admin-Account erstellt:
Benutzername: admin
Passwort: admin
Passwort sofort ändern! → Einstellungen → Passwort ändern
Ohne Docker (direkt mit Node.js)
npm install
cp .env.example .env
# .env anpassen (siehe oben)
npm start
Entwicklungsmodus (Auto-Reload):
npm run dev
Nginx Reverse Proxy
Beispiel-Konfiguration für Nginx Proxy Manager oder direktes Nginx:
server {
listen 443 ssl;
server_name oikos.deine-domain.de;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Die Datei nginx.conf.example im Repository enthält eine vollständige Konfiguration.
Familienmitglieder verwalten
Neue Mitglieder können nur Admins anlegen:
- Einstellungen → Familienmitglieder → + Neu
- Benutzername, Anzeigename, Passwort, Avatarfarbe und Rolle festlegen
- Login-Daten dem Familienmitglied mitteilen
Umgebungsvariablen — Referenz
| Variable | Pflicht | Standard | Beschreibung |
|---|---|---|---|
PORT |
— | 3000 |
Server-Port |
NODE_ENV |
— | development |
production für Deployment |
SESSION_SECRET |
✓ | — | Langer Zufalls-String (≥ 32 Zeichen) |
DB_PATH |
— | ./oikos.db |
Pfad zur SQLite-Datenbankdatei |
DB_ENCRYPTION_KEY |
— | — | SQLCipher-Schlüssel (leer = keine Verschlüsselung) |
OPENWEATHER_API_KEY |
— | — | API-Key von openweathermap.org |
OPENWEATHER_CITY |
— | Berlin |
Stadtname für Wetter-Abfrage |
OPENWEATHER_UNITS |
— | metric |
metric = °C, imperial = °F |
OPENWEATHER_LANG |
— | de |
Sprache der Wetterbeschreibungen |
RATE_LIMIT_WINDOW_MS |
— | 60000 |
Login Rate-Limit Fenster (ms) |
RATE_LIMIT_MAX_ATTEMPTS |
— | 5 |
Max. Login-Versuche pro Fenster |
Sicherheit
- Sessions sind
httpOnly,SameSite=Strictund in ProduktionSecure - CSRF-Schutz via Double Submit Cookie auf allen zustandsändernden Requests
- Passwörter mit bcrypt (Cost Factor 12) gehasht
- Globaler Rate-Limiter auf allen API-Endpoints (300 req/min)
- Strikter Login-Rate-Limiter (5 Versuche/Minute)
- Content Security Policy via Helmet
- Datenbank optional mit SQLCipher verschlüsselt
Datensicherung
Die gesamte Datenbank liegt in einer einzigen Datei:
# Backup
cp /data/oikos.db /backup/oikos-$(date +%Y%m%d).db
# Docker-Volume sichern
docker run --rm -v oikos_data:/data -v $(pwd):/backup \
alpine tar czf /backup/oikos-backup.tar.gz /data
Tests ausführen
npm test
Die Tests verwenden In-Memory-SQLite und benötigen keine laufende App-Instanz.
Lizenz
Privates Projekt — nicht für den öffentlichen Einsatz lizenziert.