187 lines
6.0 KiB
JavaScript
187 lines
6.0 KiB
JavaScript
// Delivery = static assets (__LAB_DELIVERY_HOST__, may include a path).
|
|
// API / C2 = __LAB_EXFIL__ (host + ports only, no asset path).
|
|
(function (g) {
|
|
if (!g) return;
|
|
|
|
function trimSlash(s) {
|
|
return String(s || "").replace(/\/+$/, "");
|
|
}
|
|
|
|
function ensureSlashPath(p) {
|
|
p = String(p || "");
|
|
if (!p) return "";
|
|
return p.charAt(0) === "/" ? p : "/" + p;
|
|
}
|
|
|
|
function joinBase(base, path) {
|
|
base = trimSlash(base);
|
|
path = String(path || "");
|
|
if (!path) return base;
|
|
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(path)) return path;
|
|
if (path.charAt(0) !== "/") path = "/" + path;
|
|
return base + path;
|
|
}
|
|
|
|
function hostOnly(raw) {
|
|
return String(raw || "")
|
|
.replace(/^https?:\/\//, "")
|
|
.split("/")[0]
|
|
.split(":")[0];
|
|
}
|
|
|
|
function defaultExfil() {
|
|
var domain = hostOnly(g.__LAB_EXFIL_DOMAIN__);
|
|
return {
|
|
host: domain,
|
|
domain: domain,
|
|
http_port: 443,
|
|
https_port: 443,
|
|
tls: false,
|
|
prefer_https: false,
|
|
stats_url: "",
|
|
stats_url_direct: "",
|
|
delivery_stats_url: "",
|
|
};
|
|
}
|
|
|
|
function inferDeliveryHost() {
|
|
try {
|
|
if (g.__LAB_DELIVERY_HOST__) return trimSlash(g.__LAB_DELIVERY_HOST__);
|
|
} catch (e0) {}
|
|
try {
|
|
var path = g.location && g.location.pathname ? String(g.location.pathname) : "";
|
|
var chained = path.match(/^(.*\/next-chain)(?:\/|$)/);
|
|
if (chained && g.location.origin && g.location.origin !== "null") {
|
|
return trimSlash(g.location.origin) + chained[1];
|
|
}
|
|
} catch (eBoot) {}
|
|
try {
|
|
var cfg = g.NEWS2_CONFIG || {};
|
|
if (cfg.deliveryHost) return trimSlash(cfg.deliveryHost);
|
|
if (cfg.deliveryPath) {
|
|
var originFromCfg = g.location && g.location.origin ? trimSlash(g.location.origin) : "";
|
|
return trimSlash(originFromCfg + ensureSlashPath(cfg.deliveryPath));
|
|
}
|
|
} catch (e1) {}
|
|
try {
|
|
if (!g.location || !g.location.origin || g.location.origin === "null") return "";
|
|
var origin = trimSlash(g.location.origin);
|
|
var path = String(g.location.pathname || "/");
|
|
var m = path.match(/^(.*\/next-chain)(?:\/|$)/);
|
|
if (m) return origin + m[1];
|
|
return origin;
|
|
} catch (e2) {}
|
|
return "";
|
|
}
|
|
|
|
function applyExfil(ex) {
|
|
var cur = g.__LAB_EXFIL__ && g.__LAB_EXFIL__.host ? g.__LAB_EXFIL__ : defaultExfil();
|
|
if (!ex || !ex.host) return cur;
|
|
g.__LAB_EXFIL__ = {
|
|
host: hostOnly(ex.host) || cur.host,
|
|
domain: hostOnly(ex.domain || ex.host) || cur.domain,
|
|
http_port: ex.http_port != null ? Number(ex.http_port) : cur.http_port,
|
|
https_port: ex.https_port != null ? Number(ex.https_port) : cur.https_port,
|
|
tls: ex.tls != null ? !!ex.tls : !!cur.tls,
|
|
prefer_https: ex.prefer_https != null ? !!ex.prefer_https : !!cur.prefer_https,
|
|
stats_url: ex.stats_url || cur.stats_url || "",
|
|
stats_url_direct: ex.stats_url_direct || cur.stats_url_direct || "",
|
|
delivery_stats_url: ex.delivery_stats_url || cur.delivery_stats_url || "",
|
|
};
|
|
return g.__LAB_EXFIL__;
|
|
}
|
|
|
|
function apiOrigin(ex) {
|
|
ex = ex || g.__LAB_EXFIL__ || defaultExfil();
|
|
var host = hostOnly(ex.host);
|
|
var pageHost = "";
|
|
var pageHttps = false;
|
|
try {
|
|
pageHttps = !!(g.location && g.location.protocol === "https:");
|
|
pageHost = hostOnly(g.location && g.location.hostname);
|
|
} catch (ePage) {}
|
|
var sameHost = !!(host && pageHost && host === pageHost);
|
|
var tls = !!(ex.tls || ex.prefer_https || (pageHttps && sameHost));
|
|
var port = Number(tls ? ex.https_port || 443 : ex.http_port || 80);
|
|
var scheme = tls ? "https" : "http";
|
|
var origin = scheme + "://" + host;
|
|
if (!((scheme === "https" && port === 443) || (scheme === "http" && port === 80) || !port)) {
|
|
origin += ":" + port;
|
|
}
|
|
return origin;
|
|
}
|
|
|
|
function ensureHosts() {
|
|
if (!g.__LAB_EXFIL__ || !g.__LAB_EXFIL__.host) g.__LAB_EXFIL__ = defaultExfil();
|
|
var d = inferDeliveryHost();
|
|
if (d) g.__LAB_DELIVERY_HOST__ = d;
|
|
return { delivery: g.__LAB_DELIVERY_HOST__ || "", exfil: g.__LAB_EXFIL__ };
|
|
}
|
|
|
|
function applyNews2Config() {
|
|
var cfg = g.NEWS2_CONFIG || {};
|
|
if (cfg.deliveryHost) {
|
|
g.__LAB_DELIVERY_HOST__ = trimSlash(cfg.deliveryHost);
|
|
} else if (cfg.deliveryPath) {
|
|
try {
|
|
g.__LAB_DELIVERY_HOST__ = trimSlash(trimSlash(g.location.origin) + ensureSlashPath(cfg.deliveryPath));
|
|
} catch (e) {}
|
|
}
|
|
if (cfg.exfil) applyExfil(cfg.exfil);
|
|
ensureHosts();
|
|
}
|
|
|
|
g.labTrimSlash = trimSlash;
|
|
g.labJoinBase = joinBase;
|
|
g.labInferDeliveryHost = inferDeliveryHost;
|
|
g.labDeliveryHost = function () {
|
|
ensureHosts();
|
|
return trimSlash(g.__LAB_DELIVERY_HOST__ || "");
|
|
};
|
|
g.labDeliveryUrl = function (path) {
|
|
return joinBase(g.labDeliveryHost(), path);
|
|
};
|
|
g.labApiOrigin = function () {
|
|
ensureHosts();
|
|
return apiOrigin(g.__LAB_EXFIL__);
|
|
};
|
|
g.labApiUrl = function (path) {
|
|
return joinBase(g.labApiOrigin(), path);
|
|
};
|
|
g.labApplyExfil = applyExfil;
|
|
g.labEnsureHosts = ensureHosts;
|
|
g.labApplyNews2Config = applyNews2Config;
|
|
|
|
function persistChannelCode(code) {
|
|
code = String(code || "").trim().slice(0, 64);
|
|
if (!code) return "";
|
|
g.__LAB_CHANNEL_CODE__ = code;
|
|
try {
|
|
if (g.sessionStorage) g.sessionStorage.setItem("lab_channel_code", code);
|
|
} catch (e0) {}
|
|
try {
|
|
if (g.localStorage) g.localStorage.setItem("lab_channel_code", code);
|
|
} catch (e1) {}
|
|
return code;
|
|
}
|
|
|
|
function readChannelCode() {
|
|
try {
|
|
var path = (g.location && g.location.pathname) || "";
|
|
var m = String(path).match(/\/channel\/([0-9A-Za-z]\.[0-9A-Za-z]\.[0-9A-Za-z]{2})\//i);
|
|
if (m && m[1]) return persistChannelCode(m[1].toUpperCase());
|
|
} catch (e3) {}
|
|
return "";
|
|
}
|
|
|
|
g.labChannelCode = function () {
|
|
if (g.__LAB_CHANNEL_CODE__) return String(g.__LAB_CHANNEL_CODE__);
|
|
return readChannelCode();
|
|
};
|
|
|
|
ensureHosts();
|
|
try {
|
|
g.labChannelCode();
|
|
} catch (eCh) {}
|
|
})(typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : null);
|