patrick
62c4e742ab
security: 9 Findings aus Security-Audit behoben (CRITICAL + HIGH + MEDIUM)
...
CRITICAL:
- C-1: LDAP tls_verify Default False → True (MITM-Schutz)
- C-2: TOTP-Secret Fernet-verschlüsselt in DB (statt Plaintext)
- core/crypto.py: encrypt_value() / decrypt_value() helper
- Migration 0026: totp_secret VARCHAR(64→500), ldap tls_verify default=true
- _totp_plain() helper mit Legacy-Fallback für bestehende Werte
HIGH:
- H-1: Kiosk Nonce-Cache asyncio.Lock (Race Condition behoben)
- H-2: File-Upload-Limit 10 MB (import_kimai.py + users.py CSV-Import)
- H-3: CORS allow_methods/allow_headers explizit eingeschränkt (war *)
- H-4: TrustedHostMiddleware aktiviert wenn ALLOWED_HOSTS gesetzt
MEDIUM:
- M-1: IP-Logging nutzt X-Forwarded-For hinter nginx-Proxy
- M-4: Audit-Log für password_changed, totp_enabled, totp_disabled
- M-5: CalDAV verify_ssl in Production erzwungen (_effective_verify_ssl)
152/152 Tests grün
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 19:45:09 +02:00
patrick
7e19311d2a
feat: CALDAV_ALLOWED_CIDRS Whitelist für interne CalDAV/Nextcloud-Server
...
Interne Nextcloud-Instanzen im LAN können jetzt per .env-Variable
von der SSRF-Blockliste ausgenommen werden.
Beispiel in .env:
CALDAV_ALLOWED_CIDRS=192.168.1.0/24,10.10.5.50/32
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 12:53:22 +02:00
patrick
30828c69e9
feat: agent-02-kiosk Phase 2A - Auth endpoints (PIN/NFC/QR/List)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 12:49:09 +02:00
patrick
094863f94b
feat: agent-02-kiosk Phase 1 - NFC UID migration + session service
...
- Migration 0025: kiosk_nfc_uid column on users table with partial unique index per company
- User model: kiosk_nfc_uid field after personnel_number
- New service: kiosk_session_service.py (Redis-based 15min sessions)
- New core module: app/core/redis.py (sync Redis client with ping-test)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 12:45:47 +02:00
patrick
1db7164837
fix(security): SSRF-Schutz für CalDAV-URLs
...
Neue _validate_caldav_url() Funktion in caldav_service.py:
- Prüft Schema (nur http/https erlaubt)
- Blockiert private IP-Ranges (RFC 1918, Loopback, Link-local)
- DNS-Auflösung + Prüfung der aufgelösten IP (DNS-Rebinding-Schutz)
- Blockiert: 10/8, 172.16/12, 192.168/16, 127/8, 169.254/16, fc00::/7 etc.
Validierung in allen drei HTTP-Helpers (_http_put, _http_delete, _http_propfind)
sowie beim Speichern in caldav.py Router (company + user config) – doppelter Schutz.
Getestet: 8 böse URLs geblockt, 2 legitime URLs erlaubt (10/10 OK)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 12:39:59 +02:00
patrick
0f83d13c0c
feat(kiosk): Stufe 2 – Ed25519-Auth, CLI-Tool, neue KioskDevicesPage
...
2A – Backend Ed25519-Verifizierung:
- app/core/kiosk_security.py (NEU): verify_kiosk_request() Dependency
- Timestamp-Check (30s Drift), Nonce-Cache (Redis/In-Memory), IP-Whitelist
- Ed25519-Signatur über METHOD+PATH+TIMESTAMP+NONCE+sha256(BODY)
- PEM + OpenSSH Key-Format unterstützt
- app/routers/kiosk.py: approve/revoke Endpunkte, POST /heartbeat (Ed25519-signiert)
- app/services/kiosk_service.py: token-basierte Methoden entfernt, approve/revoke/heartbeat
- app/schemas/kiosk.py: KioskDeviceOut mit heartbeat_status, HeartbeatRequest/Response
2B – CLI-Tool:
- cli.py (NEU, 529 Zeilen): Typer-CLI mit kiosk add/list/approve/revoke/info
- Public-Key-Fingerprint (SHA256), Rich-Tabellen, CIDR-Validierung
- Direkter DB-Zugriff mit RLS-Bypass
2C – Frontend:
- KioskDevicesPage.tsx: Zwei-Tab-Layout (Wartet/Aktiv), Status-Ampel,
Auto-Refresh 30s, Ed25519-Workflow (kein Token mehr)
- Layout.tsx: KioskHealthBadge (online/total, 30s Refresh, nur COMPANY_ADMIN)
requirements.txt: typer>=0.12.0, rich>=13.7.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 12:13:46 +02:00
patrick
eb122802b2
fix: 8 pre-existing Test-Fehler behoben
...
1. Krankmeldungen an Wochenenden erlaubt (working_days=0 für SICK)
Medizinisch korrekt: Krankmeldungen können auch Wochenendtage umfassen.
Behebt: test_create_absence_sick_auto_approved, test_quick_sick_*,
test_pull_includes_today_absence_with_category, test_sick_stats_*
2. Self-Approval-Schutz in Tests berücksichtigt
abs_approver_headers / time_approver_headers: zweiter Admin je Company.
Behebt: test_approve_absence, test_balance_deducted_after_approve, test_approve_entry
3. test_export_invalid_format: "pdf" → "xml" (pdf ist jetzt valides Format)
Ergebnis: 134/134 passed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-23 22:51:50 +02:00
patrick
fbc04bc2c0
agent-07 phase 2: fix test isolation + CSV import UI
...
- Fix conftest.py: commit after each request in override_get_db so
preview_csv's rollback no longer wipes the shared registered_user
(root cause of 401 cascade across test_user_import + test_personnel_number)
- Fix limiter.enabled=False in client fixture (blocks rate-limit 429)
- Fix user_import_service: allow reactivation when personnel number
belongs to the same user being reactivated
- Fix test_personnel_number: use PATCH /companies/me (not /companies/{id})
and add try/finally cleanup for personnel_number_required flag
- Frontend UsersPage: add CSV import modal with template download,
preview/validation table, and guarded apply button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-23 21:07:32 +02:00
sysops
1fedd683e0
Initial commit – TimeMaster Zeiterfassung & HR-Tool
...
Stand: agent-06 (Audit-Log), agent-05 (Krankmeldung), agent-07 Phase 1 (Personalnummer),
Busylight-Pull-Integration, TOTP/2FA, Abwesenheiten, Zeiterfassung, Kiosk-Grundgerüst.
Migrations 0001–0023 deployed auf 192.168.1.137 + .164.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-23 20:03:27 +02:00