framework
Version:
The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.
31 lines • 1.56 kB
JavaScript
/**
* Loopback-address helpers, shared by the daemon (deciding whether a bind gates behind the
* token, #1051) and the RPC mount (rejecting a rebound `Host`). A leaf module on purpose:
* `daemon.ts` imports the dashboard, so the mount cannot import these back out of it.
*/
/** The `127.0.0.0/8` loopback range, in dotted-quad form. */
const LOOPBACK_V4 = /^127(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
/**
* True when `host` is a loopback address the browser reaches without leaving the machine (#1051).
* A bind-all (`0.0.0.0`, `::`) or a routable address is not, and gates behind the shared token.
*
* The IPv4 check matches the whole `127.0.0.0/8` range but only as an address: a bare
* `startsWith('127.')` also accepts a *registrable name* like `127.evil.com`, which is exactly the
* rebound `Host` the DNS-rebinding guard exists to reject (it can resolve to `127.0.0.1`).
*/
export function isLoopbackHost(host) {
return host === 'localhost' || host === '::1' || host === '[::1]' || LOOPBACK_V4.test(host);
}
/**
* The hostname a `Host` header names, with the port dropped. Keeps the bracketed IPv6 form
* (`[::1]:4200` → `[::1]`), which splitting on the first colon would mangle.
*/
export function hostnameFromHostHeader(header) {
if (header.startsWith('[')) {
const close = header.indexOf(']');
return close === -1 ? header : header.slice(0, close + 1);
}
const colon = header.indexOf(':');
return colon === -1 ? header : header.slice(0, colon);
}
//# sourceMappingURL=loopback-host.js.map