/** Pure EDITOR_ORIGIN validation (no Worker bindings), so it unit-tests under bun. */
function within(host: string, domain: string | undefined): boolean {
const base = (domain ?? "")
.trim()
.toLowerCase()
.replace(/^\.+|\.+$/g, "");
return base !== "" && (host === base || host.endsWith(`.${base}`));
}
/**
* Why an EDITOR_ORIGIN is unsafe, or null. It must be its own host: never the forge host (cookies and
* pages), and never under SITES_DOMAIN, where user content could frame or impersonate it.
*/
export function editorOriginProblem(raw: string, forgeHost: string, domains: { sites?: string }): string | null {
let origin: URL;
try {
origin = new URL(raw);
} catch {
return "EDITOR_ORIGIN is not a valid URL";
}
const host = origin.hostname.toLowerCase();
if (host === forgeHost.toLowerCase()) return "EDITOR_ORIGIN must not be the forge host";
if (within(host, domains.sites)) return "EDITOR_ORIGIN must not be under SITES_DOMAIN (user content)";
if (origin.protocol !== "https:" && !within(host, "localhost")) return "EDITOR_ORIGIN must use https";
return null;
}