// Open-redirect protection: only allow http(s) URLs whose host is explicitly allowed. // Provider "requires_action" URLs are validated before navigation. export function isSafeExternalUrl(url: string, allowedHosts: readonly string[]): boolean { let u: URL try { u = new URL(url) } catch { return false } if (u.protocol !== 'https:' && u.protocol !== 'http:') return false return allowedHosts.some( (h) => u.hostname === h || u.hostname.endsWith(`.${h}`), ) } /** Relative in-app paths are always safe (no host); reject protocol-relative //evil. */ export function isSafeInternalPath(path: string): boolean { return path.startsWith('/') && !path.startsWith('//') }