const MAX_RETURN_PATH = 2048;
const SIGN_IN_PATHS = ["/login", "/signup", "/logout", "/forgot-password", "/reset-password"];
/**
* A same-origin path to return to after signing in, or null. Only plain absolute paths are accepted, so a
* `next` value can never send the user to another site (`//evil`, `/\evil`, `https:…`, control characters).
*/
export function safeReturnPath(raw: unknown): string | null {
if (typeof raw !== "string" || raw.length === 0 || raw.length > MAX_RETURN_PATH) return null;
if (!raw.startsWith("/") || raw.startsWith("//") || raw.startsWith("/\\")) return null;
if (/[\u0000-\u001f\u007f\\]/.test(raw)) return null;
const path = raw.split(/[?#]/, 1)[0] ?? "";
if (SIGN_IN_PATHS.some((prefix) => path === prefix || path.startsWith(`${prefix}/`))) return null;
return raw;
}
export type ReturnSearch = { next?: string };
/** `validateSearch` for sign-in pages: keeps `next` only when it's a safe path. */
export function returnSearch(search: Record<string, unknown>): ReturnSearch {
const next = safeReturnPath(search.next);
return next ? { next } : {};
}