Commit Graph

6 Commits

Author SHA1 Message Date
thomas 718d84a545 fix(backend): Seeding beendet nicht mehr den Server, Routing und Shutdown korrigiert
- REGRESSION aus d9fecb6: server.js ruft seed.js seit dem Wechsel von
  exec('node seed.js') auf require('./seed') im selben Prozess auf.
  seedDatabase() endet aber mit mongoose.connection.close() und
  process.exit(0) – auf einer frischen Datenbank hat sich der Server damit
  unmittelbar nach dem Seeding selbst beendet. Verbindungsabbau und Exit
  macht jetzt nur noch der CLI-Aufruf (npm run seed); zusätzlich verbindet
  seed.js nicht erneut, wenn die Verbindung bereits steht.
- Seeding hing an User.countDocuments(). Die Seed-Liste ist bewusst leer,
  die Bedingung war also bei jedem Start wahr, und seed.js hat die Config
  per findOneAndUpdate überschrieben: App-Name, Regeln und Texte des
  Admins gingen bei jedem Neustart verloren. Bedingung hängt jetzt an
  Admin und Config, die Config wird nur noch angelegt, nie überschrieben.
- DELETE /api/users/bulk war nicht erreichbar: die Route stand hinter
  /users/:id, Express hat den Pfad an deleteUser mit id="bulk" gegeben
  (CastError -> 404). Bulk-Routen stehen jetzt davor.
- getAdminActivity rief mongoose.Types.ObjectId() ohne new auf. Seit
  bson 5 ist das eine echte Klasse, der Endpunkt lief immer in einen
  500er. Ungültige IDs liefern jetzt 400 statt 500.
- connectDB beendete den Prozess mit process.exit(1), womit die
  Retry-Schleife in server.js toter Code war. Jetzt wird geworfen.
- geocode.js rief in seinen Signal-Handlern process.exit(0) und hat den
  Graceful Shutdown mittendrin abgeschnitten. Der Cache wird nur noch
  geschrieben; das Beenden gehört server.js, das jetzt auch SIGINT
  behandelt und einen Timeout hat.
- errorHandler stand vor dem Static-/SPA-Fallback und war damit nicht
  mehr letzte Middleware.
- Jagdsprache in seed.js: "Verbreiten Sie den Standort und den Anschuss"
  -> "Verbrechen". Da der Seed die Config anlegt, ist das der Text, den
  die Nutzer sehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 08:09:53 +02:00
thomas 4b61db82fd security: Rechte-Eskalation über Handler-Tokens schließen
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>
2026-08-25 08:09:34 +02:00
User d9fecb6914 security: implement audit fixes and backend optimizations
- L-03: PasswordReset.js minLength 6 -> 12 for all 3 apps
- B-01: PLZ geocoding proxy endpoint (GET /api/public/geocode) in all 3 backends;
  frontend PublicUserList now uses backend instead of direct Nominatim calls
- B-02: type filter server-side via onRefetch useEffect; removed redundant local
  available/type filters from PublicUserList useMemo
- audit fixes: app-specific JWT secrets, bcrypt cost 12, LRU geocode cache,
  auth middleware app-claim check, nginx CSP script-src cleanup,
  nginx.conf renamed to nginx.conf.dev, geocode-cache Docker volume
- add mailer.js utility (password reset emails)
2026-05-03 11:20:45 +02:00
thomas 770b0b1d38 Fix app labels: replace Nachsuchen with app-specific names in drohnenfuehrer and stoeberhunde
- drohnenfuehrer: all Nachsuchenführer/Hundeführer labels replaced with Drohnenführer
- stoeberhunde: all Nachsuchenführer/Hundeführer labels replaced with Stöberhundeführer
- Fixed backend config, controllers, logger, env, package.json, seed.js
- Fixed frontend components: Header, UserList, UserForm, PublicUserList, HandlerLogin, AdminPanel, RulesDisplay
- Fixed Dockerfiles (PUBLIC_URL), nginx configs, podman-compose.yml, CONTAINER.md, docs
- Fixed service worker registration path: /sw.js -> ./sw.js
- Fixed portal/index.html
2026-05-03 08:24:28 +02:00
User 6c4d55bdf0 Audit- und Produktionsfixes: sichere Handler-Set-Passwort-Flow, PII-Schutz, sichere Cookies, Upload-MIME-Whitelist, Health-Endpoint, Graceful Shutdown, HSTS/CSP, Seed-Datenbereinigung und Log-Rotation 2026-05-02 22:54:46 +02:00
thomas 5eb14a7826 init: Jagd Apps Heidekreis – Portal, Nachsuche, Drohnenführer, Stöberhunde 2026-05-02 17:31:20 +02:00