diff --git a/backend/DEVLOG.md b/backend/DEVLOG.md index 036e970..282ed9e 100644 --- a/backend/DEVLOG.md +++ b/backend/DEVLOG.md @@ -63,3 +63,16 @@ Keine Commits in dieser Session. - backend/migrations/versions/0047_kiosk_device_token_hash_index.py | 35 +++++++++++++++++++++++++++++++++++ --- +## 2026-11-03 22:09 – 22:09 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** timemaster + +### Commits +Keine Commits in dieser Session. + +### Geänderte Dateien +- DEVLOG.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/app/DEVLOG.md | 17 +++++++++++++++++ +- backend/app/routers/DEVLOG.md | 15 +++++++++++++++ + +--- diff --git a/backend/app/services/report_service.py b/backend/app/services/report_service.py index a75e090..8b2f272 100644 --- a/backend/app/services/report_service.py +++ b/backend/app/services/report_service.py @@ -3,6 +3,7 @@ import csv import io from collections import defaultdict from datetime import date, datetime, time, timedelta +from html import escape as _esc from decimal import Decimal from uuid import UUID @@ -323,6 +324,24 @@ def _check_arbzg_day(entry: TimeEntry) -> list[str]: return warnings + +def _deny_fetch(url: str, *args, **kwargs): + # Nutzerdaten landen im HTML; externe/lokale Ressourcen (file://, http://) dürfen nie geladen werden. + if url.startswith("data:"): + from weasyprint import default_url_fetcher + return default_url_fetcher(url) + raise ValueError(f"Ressourcenzugriff blockiert: {url[:40]}") + + +def _csv_safe(v): + if v is None: + return "" + if not isinstance(v, str): + return str(v) + s = v + return "'" + s if s and s[0] in ("=", "+", "-", "@", "\t", "\r") else s + + class ReportService: # ── Employee Dashboard ─────────────────────────────────────────────────── @@ -806,7 +825,7 @@ class ReportService: