consumeRateLimit bekommt IPv6-Adressen als /64-Praefix (rateLimitSubject):
ein Anschluss hat meist ein ganzes /64 und koennte sonst durch Adresswechsel
jedes Limit umgehen. better-auth bekommt weiter die einzelne Adresse und
normalisiert sie selbst auf /64 (ipv6Subnet, Standard 64).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Traefik vertraut seit 2026-10-12 den weitergeleiteten Headern aus
Cloudflare-Netzen. Wer eine eigene Cloudflare-Zone auf den Server zeigen
laesst, konnte damit X-Real-IP und den ersten X-Forwarded-For-Eintrag
faelschen und die Rate-Limits (Buchung, Kontakt, Login, 2FA) umgehen.
- clientIp: Gegenstelle ist der letzte X-Forwarded-For-Eintrag (von Traefik
angehaengt); CF-Connecting-IP nur, wenn sie eine Cloudflare-Edge ist.
- better-auth liest nur noch x-artista-client-ip, den der Auth-Endpunkt
per withClientIp setzt (ein mitgeschickter Wert wird ersetzt).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Eine Mail an eine Adresse ohne Mailserver (SMTP 556, nullMX) wurde bis zu
8-mal erneut versendet und liess jeden Worker-Lauf mit Exit-Code 1 enden;
das SMTP-Fehlerlog enthielt dabei die Empfaengeradresse.
- SMTP-Antworten 5xx markieren die Mail sofort als FAILED, 4xx und
Verbindungsfehler bleiben wiederholbar.
- Adressen werden aus Log und lastError entfernt.
- Worker-CronJob: backoffLimit 0 (kein zweiter Pod je Fehlschlag) und
ttlSecondsAfterFinished 1 Tag, damit Fehler-Pods nicht stehen bleiben.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Gleiche Prüfung wie bei der Buchung: mindestens 6 Zeichen, nur Ziffern, Leerzeichen und + ( ) / -.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Vor dem 01.11.2026 gilt dann der Early-Bird-Preis. Fehlt eine Freigabe, bleibt die Vorschau.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Neuer Abschnitt nach den Fragen, im Menü als Erstgespräch. Anfrage geht als E-Mail an die Veranstalter-Adresse (Admin) bzw. ADMIN_NOTIFY_EMAIL, sofort zugestellt, sonst über den Worker wiederholt. Gleicher Schutz wie die Buchung: nur JSON von der eigenen Seite, Rate Limit (5/h je IP), Prüfung auf dem Server, Honeypot gegen Bots, doppeltes Absenden ergibt eine Mail. Keine automatische Mail an die angegebene Adresse (sonst Missbrauch für Spam an Dritte).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Befunde aus dem Sicherheits-Review des vorherigen Commits:
- Gerät eine Buchung in "Prüfung nötig" (Rückbuchung, Doppelzahlung ...),
wird der Stripe-Plan beendet und offene Rechnungen storniert. Nach
Bestätigung legt der Worker einen neuen Plan für die offenen Raten an.
Vorher zog Stripe auch bei Buchungen in Prüfung weiter ein.
- Vor dem Anlegen wird bei Stripe nach einem laufenden Plan der Buchung
gesucht; der Idempotenzschlüssel enthält Generation und Start. Verhindert
einen zweiten Plan nach verlorener ID und die Rückgabe des alten,
beendeten Plans nach einer Prüfung.
- Start bei bereits verstrichener Fälligkeit deterministisch am nächsten
9-Uhr-Termin, letzte Rate bleibt am Stichtag.
- Rückbuchungs-Event meldet die betroffene Buchung zurück.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- ReviewsSection (Server Component) mit Durchschnitt, zugaenglichen
Sternen, Initialen statt Profilbildern, relativer Zeit, Links zur
Rezension und zum Maps-Eintrag sowie Hinweis "Rezensionen von Google"
- lange Texte optisch gekuerzt, "Weiterlesen" mit aria-expanded
- ohne Daten ausgeblendet; in Entwicklung/Staging ein Einrichtungshinweis
- Laden parallel zu loadPublicPage, Fehler blenden nur den Abschnitt aus
- Links aus der API-Antwort nur zu HTTPS-Google-Hosts (safeGoogleUrl)
- Linkstile und Browser-Oberflaechen (Scrollbar, Caret, Unterstreichung)
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>