/** Безопасный внутренний путь для post-login/post-pin редиректа (без open redirect). */ export function isSafeInternalRedirect(path: string): boolean { if (!path.startsWith('/') || path.startsWith('//')) return false; if (path.includes('://')) return false; return true; } export function readPostAuthRedirect(search: string): string | null { if (typeof window === 'undefined') return null; const redirect = new URLSearchParams(search).get('redirect'); if (!redirect || !isSafeInternalRedirect(redirect)) return null; return redirect; } /** * Куда перейти после успешного ввода PIN на auth-страницах. * null — остаться на текущей странице (OAuth consent, основное приложение). */ export function resolvePostPinAuthRedirect(pathname: string, search = ''): string | null { if (pathname.startsWith('/auth/oauth/authorize')) { return null; } if (pathname.startsWith('/auth/login') || pathname.startsWith('/auth/register')) { return readPostAuthRedirect(search) ?? '/'; } if (pathname.startsWith('/auth/')) { return '/'; } return null; }