Opening the web app over the Mac's Wi-Fi address (an insecure context) crashed Connect because crypto.randomUUID is unavailable there, and the MCP OAuth redirect, Composio/Pipedream return and noVNC link all pointed at WEB_ORIGIN (127.0.0.1). The API now derives these URLs from the request's browser origin when it is loopback or a private network, the same hosts CORS already trusts, and falls back to WEB_ORIGIN otherwise. Claude-Session: https://claude.ai/code/session_01KWEAjTw26eRf3ZXTXfRjmD Co-authored-by: Claude <noreply@anthropic.com>
31 lines
1.4 KiB
TypeScript
31 lines
1.4 KiB
TypeScript
/** Hosts the API already trusts as browser origins: loopback and private networks. */
|
|
export function isPrivateOrLocalHost(host: string): boolean {
|
|
if (isLoopbackHost(host)) return true;
|
|
if (host.endsWith(".local")) return true;
|
|
if (/^192\.168\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
|
|
if (/^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
|
|
if (/^172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
|
|
if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.\d{1,3}\.\d{1,3}$/.test(host)) return true;
|
|
return false;
|
|
}
|
|
|
|
export function isLoopbackHost(host: string): boolean {
|
|
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
|
|
}
|
|
|
|
/** The web origin that browser-facing URLs (OAuth returns, screen links) should
|
|
* point at for this request. A browser opened over a loopback or private-network
|
|
* address gets its own origin back so a phone on the LAN is not sent to
|
|
* 127.0.0.1; any other caller gets the configured WEB_ORIGIN. */
|
|
export function requestWebOrigin(origin: string | undefined, webOrigin: string): string {
|
|
if (!origin) return webOrigin;
|
|
try {
|
|
const url = new URL(origin);
|
|
if (url.protocol !== "http:" && url.protocol !== "https:") return webOrigin;
|
|
if (url.origin === new URL(webOrigin).origin) return url.origin;
|
|
return isPrivateOrLocalHost(url.hostname) ? url.origin : webOrigin;
|
|
} catch {
|
|
return webOrigin;
|
|
}
|
|
}
|