const OAUTH_RETURN_COOKIE = 'shahi_google_oauth_return_to'; const DEFAULT_RETURN_PATH = '/account'; const SAFE_PATH_PATTERN = /^\/[a-zA-Z0-9/_-]*$/; export function getOAuthReturnCookieName(): string { return OAUTH_RETURN_COOKIE; } /** Only same-origin relative paths (optionally with query) are allowed after OAuth. */ export function sanitizeOAuthReturnPath(value: string | null | undefined): string { if (!value) return DEFAULT_RETURN_PATH; const trimmed = value.trim(); if (!trimmed.startsWith('/') || trimmed.startsWith('//') || trimmed.includes('://')) { return DEFAULT_RETURN_PATH; } const withoutHash = trimmed.split('#')[0] ?? trimmed; const queryIndex = withoutHash.indexOf('?'); const pathname = queryIndex === -1 ? withoutHash : withoutHash.slice(0, queryIndex); const search = queryIndex === -1 ? '' : withoutHash.slice(queryIndex); if (!pathname || !SAFE_PATH_PATTERN.test(pathname)) { return DEFAULT_RETURN_PATH; } return `${pathname}${search}`; }