feat: globales HTTP-Access-Log und Exception-Logging
Backend Image / build-and-push (push) Successful in 2m50s
Frontend Image / build-and-push (push) Successful in 2m22s

Bisher waren 4xx-Fehler (falsches Passwort, Validierungsfehler,
fehlende Berechtigung) im Log komplett unsichtbar - Nest loggt
standardmaessig nur unbehandelte 5xx-Fehler. Ein Login, das aus
Infra-Gruenden fehlschlaegt (siehe TLS/Cloudflare-Vorfall), war dadurch
allein aus den Logs nicht diagnostizierbar.

- AllExceptionsFilter (global): loggt jede Exception mit Methode/Pfad/
  Status (4xx als warn, 5xx als error mit Stacktrace). Client-Antwort
  bleibt unveraendert - HttpExceptions liefern weiter exakt ihren
  bisherigen Body, unbehandelte Fehler weiter nur eine generische
  500-Meldung ohne interne Details.
- requestLoggerMiddleware (global): eine Zeile pro Request (Methode,
  Pfad, Status, Dauer), damit auch erfolgreiche Requests im Log
  auftauchen - vorher gab's dafuer gar keine Spur.
- AuthService.login()/verifyMfaAndLogin(): konkrete Ursache pro
  Fehlschlag (unbekannter User, deaktiviert, falsches Passwort,
  falscher MFA-Code) zusaetzlich zum bestehenden Audit-Log-Eintrag.

Nirgends werden Passwoerter, Tokens oder Request-Bodies geloggt - nur
Methode, Pfad, Status, Dauer und die (bereits client-sichere)
Fehlermeldung.

Verifiziert: tsc/eslint clean, 304/304 Tests (7 neu), Build clean.
This commit is contained in:
Nick Szaunig committed 2026-08-27 07:29:51 +02:00
1 parent 05876838b0
commit ce3a0c44ac
7 files changed
+269 -5

No files matched your search

@@ -0,0 +1,31 @@
import { Logger } from '@nestjs/common';
import type { NextFunction, Request, Response } from 'express';
const logger = new Logger('HTTP');
/**
* One line per request in stdout/kubectl logs: method, path, status, and
* timing - never the body/headers, so passwords and tokens never end up in
* logs. Without this, a normal (non-error) request leaves zero trace,
* which makes "did the request even arrive?" the hardest question to
* answer when something looks broken from outside the cluster.
*/
export function requestLoggerMiddleware(
req: Request,
res: Response,
next: NextFunction,
): void {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
const line = `${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`;
if (res.statusCode >= 500) {
logger.error(line);
} else if (res.statusCode >= 400) {
logger.warn(line);
} else {
logger.log(line);
}
});
next();
}