First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
const net = require("node:net");
|
||||
|
||||
const normalizeHost = (host) => {
|
||||
let raw = String(host ?? "").trim().toLowerCase();
|
||||
if (!raw) return "";
|
||||
|
||||
if (raw.startsWith("[")) {
|
||||
const end = raw.indexOf("]");
|
||||
if (end !== -1) {
|
||||
return raw.slice(1, end).trim();
|
||||
}
|
||||
}
|
||||
|
||||
const colonCount = (raw.match(/:/g) || []).length;
|
||||
if (colonCount === 1) {
|
||||
const idx = raw.lastIndexOf(":");
|
||||
const maybePort = raw.slice(idx + 1);
|
||||
if (/^\d+$/.test(maybePort)) {
|
||||
raw = raw.slice(0, idx);
|
||||
}
|
||||
}
|
||||
|
||||
return raw;
|
||||
};
|
||||
|
||||
const resolveHosts = (env = process.env) => {
|
||||
const host = String(env.HOST ?? "").trim();
|
||||
if (host) return [host];
|
||||
return ["127.0.0.1", "::1"];
|
||||
};
|
||||
|
||||
const resolveHost = (env = process.env) => {
|
||||
const hosts = resolveHosts(env);
|
||||
return hosts[0] ?? "127.0.0.1";
|
||||
};
|
||||
|
||||
const isIpv4Loopback = (value) => value.startsWith("127.");
|
||||
|
||||
const isIpv6Loopback = (value) => {
|
||||
if (value === "::1" || value === "0:0:0:0:0:0:0:1") return true;
|
||||
if (!value.startsWith("::ffff:")) return false;
|
||||
const mapped = value.slice("::ffff:".length);
|
||||
return net.isIP(mapped) === 4 && isIpv4Loopback(mapped);
|
||||
};
|
||||
|
||||
const isPublicHost = (host) => {
|
||||
const normalized = normalizeHost(host);
|
||||
if (!normalized) return false;
|
||||
|
||||
if (normalized === "localhost") return false;
|
||||
if (normalized === "0.0.0.0" || normalized === "::") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ipVersion = net.isIP(normalized);
|
||||
if (ipVersion === 4) {
|
||||
return !isIpv4Loopback(normalized);
|
||||
}
|
||||
if (ipVersion === 6) {
|
||||
return !isIpv6Loopback(normalized);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const assertPublicHostAllowed = ({ host, studioAccessToken }) => {
|
||||
if (!isPublicHost(host)) return;
|
||||
|
||||
const token = String(studioAccessToken ?? "").trim();
|
||||
if (token) return;
|
||||
|
||||
const normalized = normalizeHost(host) || String(host ?? "").trim() || "(unknown)";
|
||||
throw new Error(
|
||||
`Refusing to bind Studio to public host "${normalized}" without STUDIO_ACCESS_TOKEN. ` +
|
||||
"Set STUDIO_ACCESS_TOKEN or bind HOST to 127.0.0.1/::1/localhost."
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
resolveHosts,
|
||||
resolveHost,
|
||||
isPublicHost,
|
||||
assertPublicHostAllowed,
|
||||
};
|
||||
Reference in New Issue
Block a user