Lumi/scripts/verify-overlay-web-documents.js
2026-07-19 12:15:43 +02:00

76 lines
3.3 KiB
JavaScript

const assert = require("assert");
const {
injectDocumentCss,
loadInjectedOverlayDocument,
TRANSPARENT_WEBSITE_GUARD
} = require("../src/services/overlay-web-documents");
const { OBS_BROWSER_DEFAULT_CSS } = require("../src/services/obs-browser-defaults");
async function run() {
const injected = injectDocumentCss(
"<!doctype html><html><head><title>Alerts</title></head><body><div class=\"alert\">Hello</div></body></html>",
"https://alerts.example/widgets/main/",
".alert { font-size: 64px; }"
);
assert(injected.includes('<base href="https://alerts.example/widgets/main/">'));
assert(injected.includes('<style id="lumi-obs-browser-css">'));
assert(injected.includes(OBS_BROWSER_DEFAULT_CSS));
assert(injected.includes(TRANSPARENT_WEBSITE_GUARD));
assert(injected.includes(".alert { font-size: 64px; }"));
assert(injected.indexOf("lumi-obs-browser-css") > injected.indexOf("<title>Alerts</title>"), "website CSS must be appended after the website head content like OBS");
assert(injected.includes('window.addEventListener("load",apply,{once:true})'), "website CSS must be re-applied when the main document finishes loading like OBS");
assert(injected.includes("new MutationObserver(schedule)"), "late-loading alert apps must not be able to remove the transparency/CSS guard");
assert(injected.includes('setProperty(\"background-color\",\"rgba(0, 0, 0, 0)\",\"important\")'));
const opaqueAllowed = injectDocumentCss(
"<html><head></head><body></body></html>",
"https://alerts.example/widget",
"body { background: white; }",
{ forceTransparentBackground: false }
);
assert(!opaqueAllowed.includes(TRANSPARENT_WEBSITE_GUARD));
const withBase = injectDocumentCss(
'<html><head><base href="../assets/"></head><body></body></html>',
"https://alerts.example/widgets/main/",
""
);
assert(withBase.includes('<base href="https://alerts.example/widgets/assets/">'));
assert.strictEqual((withBase.match(/<base\b/gi) || []).length, 1);
let fetched = null;
const loaded = await loadInjectedOverlayDocument("https://alerts.example/widget", "body { color: white; }", {
resolveHost: async () => ["93.184.216.34"],
fetchImpl: async (url, options) => {
fetched = { url, options };
return new Response("<html><head></head><body>Widget</body></html>", {
status: 200,
headers: { "Content-Type": "text/html; charset=utf-8" }
});
}
});
assert.strictEqual(fetched.url, "https://alerts.example/widget");
assert.strictEqual(fetched.options.redirect, "manual");
assert(loaded.html.includes(OBS_BROWSER_DEFAULT_CSS));
assert(loaded.html.includes("body { color: white; }"));
let privateFetchAttempted = false;
await assert.rejects(
loadInjectedOverlayDocument("http://127.0.0.1:8080/alerts", "", {
fetchImpl: async () => {
privateFetchAttempted = true;
throw new Error("must not fetch");
}
}),
/Private and local website addresses/
);
assert.strictEqual(privateFetchAttempted, false, "CSS injection must not turn Lumi into a private-network proxy");
console.log("Overlay website document verification passed: OBS-default CSS injection, custom selectors, base URLs, bounded public fetching, and private-network blocking.");
}
run().catch((error) => {
console.error(error);
process.exit(1);
});