Ergänzt die Absicherung aus 8384ad9/d9fecb6 um die Lücken, die dort offen
geblieben sind.
- authenticateToken prüft jetzt die Rolle. Der C-01-Fix vergleicht nur
`decoded.app`, und genau den Claim tragen Handler-Tokens nicht
({ id, role: 'handler' }) – `if (decoded.app && ...)` lief bei ihnen
also ins Leere. Ein eingeloggter Hundeführer konnte seinen Bearer-Token
weiterhin gegen /api/users, /api/config und /api/audit-logs schicken und
hatte volle Admin-Rechte. Admin-Tokens tragen zusätzlich role: 'admin';
Tokens ohne role bleiben bis zum Ablauf gültig, niemand wird ausgeloggt.
- Logout wird als LOGOUT protokolliert statt als LOGIN, und die Route
liest den Benutzernamen über attachUserIfPresent (neu). Vorher lag gar
keine Auth-Middleware auf /logout, der Eintrag lautete immer "unknown".
- forgotPassword sucht case-insensitive wie der Login. Ein als "Thorsten"
angelegtes Konto konnte sich als "thorsten" anmelden, aber kein Passwort
zurücksetzen.
- CSV-Export escaped führende =, +, -, @ (neues utils/csv.js, von
userController und auditController gemeinsam genutzt). Ein Name wie
=HYPERLINK(...) wurde sonst von Excel als Formel ausgeführt.
- Massen-Operationen filtern soft-deleted Einträge; der pre(/^find/)-Hook
des Modells greift bei updateMany nicht.
- Die öffentliche Liste liefert wieder phone, landline, address und photo.
Die UI zeigt diese Felder seit jeher an, die API lieferte sie seit dem
PII-Commit nicht mehr – Anrufen war öffentlich nicht mehr möglich.
E-Mail, Hashes und Invite-Felder bleiben ausgeschlossen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Docker: bind all backend/frontend ports to 127.0.0.1 only (was 0.0.0.0)
- Docker: add shared jagd-network; portal uses container names instead of host ports
- Fix: set-password endpoints now require valid invite token (drohnenfuehrer, stoeberhunde)
- Fix: auth cookie secure flag enabled in production
- Fix: password reset token no longer logged in production
- Add: inviteLimiter (10/15min) on set-password routes in all three apps
- Add: importUsers capped at 500 entries to prevent DoS
- Refactor: rename handler -> drohnenfuehrer/stoeberhundefuehrer across all apps