* feat(channels): add guided setup flows * test(channels): preserve setup config values * fix(channels): reflect saved setup state * refactor(channels): simplify setup state metadata * fix(channels): harden setup lifecycle * refactor(channels): centralize setup contracts * fix(channels): route setup actions through webui shim * fix(channels): adapt settings for compact screens * fix(models): preserve default preset display * feat(models): add curated Codex catalog * fix(webui): stop attached gateway on interrupt * fix(webui): simplify apps catalog * docs(webui): clarify apps and runtime features * feat(settings): add guided capability setup * fix(webui): harden setup and managed services * test: keep managed runtime checks portable * test: scope POSIX runtime coverage * fix(webui): simplify file settings * feat(files): bundle document reading * fix(webui): harden setup request boundaries * fix(webui): prevent channel setup status squeeze * fix(settings): group provider compatibility aliases * refactor(settings): remove redundant setup surfaces * fix(webui): harden guided setup lifecycle * fix(webui): preserve channel setup compatibility
16 lines
543 B
TypeScript
16 lines
543 B
TypeScript
export function isLoopbackHost(host: string): boolean {
|
|
let normalized = host.trim().toLowerCase();
|
|
if (normalized.endsWith(".")) normalized = normalized.slice(0, -1);
|
|
if (normalized.startsWith("[") && normalized.endsWith("]")) {
|
|
normalized = normalized.slice(1, -1);
|
|
}
|
|
if (normalized === "localhost" || normalized === "::1") return true;
|
|
|
|
const octets = normalized.split(".");
|
|
return (
|
|
octets.length === 4 &&
|
|
octets[0] === "127" &&
|
|
octets.every((octet) => /^\d{1,3}$/.test(octet) && Number(octet) <= 255)
|
|
);
|
|
}
|