9482424ade
57.7 (Consent-Hash ohne TTL): - Neues Feld Customer.consentHashExpiresAt + Migration 20260601300000_consent_hash_ttl mit IF NOT EXISTS. Bestandsdaten bekommen NOW()+30d als Default, damit frische Versand-Links nicht sofort sterben. - TTL-Konstante CONSENT_HASH_TTL_DAYS = 30 in consent-public.service. - getCustomerByConsentHash + grantAllConsentsPublic liefern null bzw. klare Fehlermeldung bei Ablauf; consentHashExpiresAt wird nicht in der Response durchgereicht (kein Oracle "unbekannt vs. abgelaufen"). - ensureConsentHash erneuert Hash + Frist, sobald der alte abgelaufen ist – Versand neuer Links bleibt friction-frei. - consentHashExpiresAt in SENSITIVE_CUSTOMER_FIELDS (sanitize), damit der Standard-Customer-Endpoint kein Workflow-Info leakt. 57.8 (Zip-Slip / Zip-Bomb): - Reject zusätzlich: leere Entry-Namen, Backslashes (Cross-OS- Confusion), Home-Dir-Expansion (`~`), explizite `..`-Segmente schon im Original-Namen (vor path.resolve). - Zip-Slip-Check auf path.relative umgestellt – robuster als startsWith(prefix + sep), insbesondere bei nested Resolution. - Zip-Bomb-Schutz: 500 MB pro Entry + 5 GB Gesamt-Uncompressed- Limit; bei Überschreitung Abbruch mit klarer Meldung. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>