/** * Ruecksprungziel nach der Anmeldung (/konto?next=/patenschaft). * * Nur Pfade dieser Seite: "//host" und "/\host" werten Browser als Adresse * auf einem fremden Host — ein ungeprueftes next waere eine offene * Weiterleitung, mit der ein Link auf wabenhain.com nach dem Login auf eine * nachgebaute Seite fuehrt (dieselbe Regel wie redirectWithinSite in * lib/redirect.ts). Steuerzeichen und Leerraum fallen ebenfalls durch, weil * Browser sie beim Aufloesen teils entfernen und so aus "/ /host" wieder * "//host" machen. */ const MAX_NEXT_LENGTH = 200; export function safeNextPath(value: unknown): string | null { if (typeof value !== "string") return null; if (value.length === 0 || value.length > MAX_NEXT_LENGTH) return null; if (!value.startsWith("/") || value.startsWith("//") || value.startsWith("/\\")) return null; if (/[\s\\\p{Cc}]/u.test(value)) return null; return value; } /** Login-Seite mit erhaltenem Ruecksprungziel, z.B. fuer Fehlermeldungen. */ export function loginPathWithNext(next: string | null): string { return next ? `/konto?next=${encodeURIComponent(next)}` : "/konto"; }