import { sanitizeNext } from "@/lib/frontend/authRedirect"; export const MUST_CHANGE_PASSWORD_GATE_PARAM = "mustChangePasswordGate"; export const MUST_CHANGE_PASSWORD_GATE_VALUE = "1"; export const MUST_CHANGE_PASSWORD_NEXT_PARAM = "next"; export const PROFILE_PATH = "/profile"; function normalizePathname(pathname) { if (typeof pathname !== "string") return "/"; const trimmed = pathname.trim(); if (!trimmed) return "/"; return trimmed.startsWith("/") ? trimmed : `/${trimmed}`; } function readParam(searchParams, key) { if (!searchParams) return null; if (typeof searchParams.get === "function") { const value = searchParams.get(key); return typeof value === "string" ? value : null; } const raw = searchParams[key]; if (Array.isArray(raw)) { return typeof raw[0] === "string" ? raw[0] : null; } return typeof raw === "string" ? raw : null; } function extractPathname(path) { if (typeof path !== "string" || !path.trim()) return null; try { return new URL(path, "http://localhost").pathname; } catch { return null; } } export function isProfilePath(pathname) { const normalizedPathname = normalizePathname(pathname); return ( normalizedPathname === PROFILE_PATH || normalizedPathname.startsWith(`${PROFILE_PATH}/`) ); } export function sanitizeMustChangePasswordNext(nextValue) { const safeNext = sanitizeNext(nextValue); if (!safeNext) return null; const nextPathname = extractPathname(safeNext); if (!nextPathname) return null; if (isProfilePath(nextPathname)) return null; return safeNext; } export function shouldRedirectToProfileForPasswordChange({ pathname, mustChangePassword, }) { return mustChangePassword === true && !isProfilePath(pathname); } export function buildMustChangePasswordRedirectUrl(nextValue) { const params = new URLSearchParams(); params.set(MUST_CHANGE_PASSWORD_GATE_PARAM, MUST_CHANGE_PASSWORD_GATE_VALUE); const safeNext = sanitizeMustChangePasswordNext(nextValue); if (safeNext) { params.set(MUST_CHANGE_PASSWORD_NEXT_PARAM, safeNext); } return `${PROFILE_PATH}?${params.toString()}`; } export function parseMustChangePasswordGateParams(searchParams) { const gateMarker = readParam(searchParams, MUST_CHANGE_PASSWORD_GATE_PARAM); const rawNext = readParam(searchParams, MUST_CHANGE_PASSWORD_NEXT_PARAM); return { isGateMarker: gateMarker === MUST_CHANGE_PASSWORD_GATE_VALUE, next: sanitizeMustChangePasswordNext(rawNext), }; } export function resolveMustChangePasswordResumePath({ pathname, searchParams, mustChangePassword, }) { if (mustChangePassword === true) return null; if (!isProfilePath(pathname)) return null; const parsed = parseMustChangePasswordGateParams(searchParams); if (!parsed.isGateMarker) return null; if (!parsed.next) return null; return parsed.next; }