Startblocker aus d9fecb6: die Compose-Dateien lesen seither
${NACHSUCHE_JWT_SECRET} (bzw. DROHNENFUEHRER_/STOEBERHUNDE_), die .env-Dateien
definieren aber weiterhin JWT_SECRET. Compose ersetzte die unbekannte Variable
still durch einen Leerstring, config/env.js beendete den Prozess daraufhin mit
Exit-Code 1 — mit restart: unless-stopped ein Crash-Loop. Nachgewiesen mit
`docker compose config` (JWT_SECRET: "") und einem Startversuch.
- Compose nutzt jetzt ${..._JWT_SECRET:?...}: fehlt der Wert, bricht compose
mit einer Meldung ab, statt ihn stillschweigend zu leeren.
- Die .env-Dateien (nicht versioniert) tragen die korrekten Namen und je App
ein EIGENES 32-Byte-Secret. Vorher stand in allen drei derselbe 16-Zeichen-
Wert, wodurch die App-Trennung aus d9fecb6 wirkungslos war.
FOLGE: alle laufenden Admin-Sitzungen und Fuehrer-Tokens sind ungueltig,
alle muessen sich einmal neu anmelden.
- Fuehrer-Tokens tragen jetzt app: config.appName, und handlerAuth.js sowie
die umbenannten Varianten pruefen den Claim. Vorher trugen sie nur
{ id, role } — die app-Pruefung in middleware/auth.js lief bei ihnen ins
Leere, weil sie an `decoded.app &&` haengt.
Geprueft: Fuehrer-Token aus App A gegen /me von App B -> 403, gegen die
eigene -> 200.
- APP_URL steht in Compose wieder auf ${APP_URL:-}. Der Default aus der
letzten Runde hat die Warnung aus config/env.js unterdrueckt, die auf eine
fehlende Konfiguration hinweisen sollte.
- .env.example dokumentiert die neuen Namen, den openssl-Aufruf und dass
CORS_ORIGIN/APP_URL produktiv nicht auf localhost stehen duerfen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Der Geocode-Cache war nur auf dem Erfolgspfad begrenzt. Die beiden
Negativ-Pfade (cache.set(key, null)) schrieben ungebremst — über den
öffentlichen GET /api/public/geocode genügten erfundene Postleitzahlen,
um Speicher und die alle 60 s geschriebene Cache-Datei beliebig wachsen
zu lassen. Bei NODE_OPTIONS=--max_old_space_size=256 eine reale Grenze.
Alle Schreibpfade laufen jetzt über rememberInCache(); loadCache()
beschneidet eine bereits gewachsene Datei auf das Limit.
Geprüft: eine künstlich auf 5000 Einträge aufgeblähte Cache-Datei wird
beim Start auf 1000 reduziert.
- Der Cache war trotz Kommentar kein LRU, sondern ein FIFO: ein Treffer
hat den Eintrag nicht ans Ende gerückt, häufig genutzte Adressen flogen
zuerst raus. Treffer werden jetzt neu einsortiert.
- /api/public/geocode bekommt einen eigenen Limiter (20/15 min). Der
Endpunkt löst ausgehende Nominatim-Anfragen aus und teilt sich mit dem
Geocoding im Admin-Bereich die globale Wartezeit von 1100 ms.
Geprüft: Anfragen 21-24 liefern 429.
- resetPassword prüfte 6 Zeichen, das Admin-Schema verlangt 12. Passwörter
dazwischen kamen durch und scheiterten erst an der Mongoose-Validierung
— beim Nutzer kam "Serverfehler" (500) an. Jetzt 400 mit klarer Meldung.
- APP_URL wird aktiv gesetzt statt auskommentiert, und der Rückfallwert
hängt den Unterpfad an. Vorher fiel appUrl auf CORS_ORIGIN zurück, und
der Link in der Reset-Mail zeigte auf das Portal statt in die App.
Geprüft: erzeugte URL lautet .../nachsuche/passwort-zuruecksetzen?token=…
- Die beim Zusammenführen verlorengegangene Platzhalter-Prüfung für
JWT_SECRET ist wieder da (fängt auch CHANGE_ME_IN_PRODUCTION).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>