Theseus: tell add-ons which name system served the page

A page message carried only an origin, and a bns:// page is shown as
https://. The same name can be one site on BNS and another on the ordinary
web (BNS carries registrations under ICANN TLDs on purpose), so an add-on
that files permissions by origin could not tell the two apart. The call
context now carries `registry: "bns" | "web"`, also across the sandbox
boundary, and api.features.pageRegistry says the host provides it.
This commit is contained in:
Local Dev 2026-10-05 23:40:14 +02:00
parent 7cc66ce680
commit 99a5923f42
2 changed files with 7 additions and 4 deletions

View file

@ -776,7 +776,7 @@ class AddonHost {
const timer = setTimeout(() => { waiting.delete(cid); callScopes.delete(cid); rej(new Error(`"${m.name}" timed out`)); }, SANDBOX_CALL_MS);
if (timer.unref) timer.unref();
waiting.set(cid, { resolve: res, reject: rej, timer });
send({ t: "call", id: cid, name: m.name, payload, ctx: ctx ? { from: ctx.from, origin: ctx.origin, tabId: ctx.tabId } : {} });
send({ t: "call", id: cid, name: m.name, payload, ctx: ctx ? { from: ctx.from, origin: ctx.origin, tabId: ctx.tabId, registry: ctx.registry } : {} });
}));
} else if (m.t === "res") {
const w = waiting.get(m.id);
@ -843,7 +843,7 @@ class AddonHost {
return {
// What this host can do beyond the documented surface, so an add-on
// can tell "the user switched it off" from "this Theseus is too old".
features: Object.freeze({ pageInjectPolicy: true, vaultPin: !!this._vaultPin }),
features: Object.freeze({ pageInjectPolicy: true, vaultPin: !!this._vaultPin, pageRegistry: true }),
// Metadata the add-on may want to reflect on
id: manifest.id,
folder,

View file

@ -6286,7 +6286,7 @@ function routeWizUri(uri, pageUrl, tabId) {
return false;
}
const send = () => addonHost
.dispatch("aegis", "wcConnectFromPage", { uri: u }, { from: "page", origin: origin || "unknown site", tabId })
.dispatch("aegis", "wcConnectFromPage", { uri: u }, { from: "page", origin: origin || "unknown site", tabId, registry: /^bns:/i.test(String(pageUrl || "")) ? "bns" : "web" })
.catch((err) => console.log("[wiz] pairing failed:", err?.message || err));
// A wallet that starts on first use is woken by the link itself.
if (addonHost.isDormant("aegis")) {
@ -6316,7 +6316,10 @@ ipcMain.handle("addon-page-msg", async (e, addonId, msg, payload) => {
if (!addonHost.pageAllowed(id, url)) throw new Error(`add-on "${id}" is not injected on this page`);
const origin = pageOriginOf(url);
if (!origin) throw new Error("opaque origin");
return addonHost.dispatch(id, String(msg), payload, { from: "page", origin, tabId: tab.id });
// `registry` says which name system served the page: the same name can be
// one site on BNS and another on the ordinary web, and `origin` alone
// (bns:// shown as https://) cannot tell an add-on which it is talking to.
return addonHost.dispatch(id, String(msg), payload, { from: "page", origin, tabId: tab.id, registry: /^bns:/i.test(url) ? "bns" : "web" });
});
// Synchronous — the inject preload has to know what to run before the page's
// own scripts start. Decided against the sender's committed URL; the href the