diff --git a/main.js b/main.js index cb43245..e001f2b 100644 --- a/main.js +++ b/main.js @@ -2647,6 +2647,52 @@ ipcMain.handle("collision-set-policy", (_e, p) => { return settings.collisionPolicy; }); ipcMain.handle("collision-reset", () => { collisions = { byName: {}, byTld: {} }; saveCollisions(); return true; }); +// Ariadne's Thread system-wide resolver — installed by AriadneResolver-Setup.exe +// as two Windows Scheduled Tasks ("BNS Resolver Daemon" + "BNS Sia Bridge"). +// Turning them off means non-Theseus browsers stop resolving BCDN names on +// this machine; Theseus itself uses its own in-process resolver so it's +// unaffected. Toggling requires admin (tasks run as SYSTEM) — start/stop go +// through an elevated powershell that UAC-prompts once per action. +const ARIADNE_TASKS = ["BNS Resolver Daemon", "BNS Sia Bridge"]; +function ariadneQueryState() { + return new Promise((resolve) => { + const { spawn } = require("child_process"); + // Get-ScheduledTask returns Ready | Running | Disabled | (missing → error). + // Print state or "MISSING" for each task; MISSING on the primary task + // means Ariadne isn't installed at all. + const ps = spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", + "$names=@('BNS Resolver Daemon','BNS Sia Bridge');" + + "$names | ForEach-Object { $t = Get-ScheduledTask -TaskName $_ -ErrorAction SilentlyContinue;" + + " if ($t) { \"$_=$($t.State)\" } else { \"$_=MISSING\" } }"], { windowsHide: true }); + let out = ""; + ps.stdout.on("data", (d) => { out += d; }); + ps.on("close", () => { + const lines = out.trim().split(/\r?\n/).filter(Boolean); + const map = Object.fromEntries(lines.map((l) => { const i = l.lastIndexOf("="); return [l.slice(0, i), l.slice(i + 1)]; })); + const primary = map["BNS Resolver Daemon"]; + if (!primary || primary === "MISSING") return resolve({ state: "not-installed" }); + if (primary === "Running") return resolve({ state: "running" }); + return resolve({ state: "stopped" }); + }); + ps.on("error", () => resolve({ state: "not-installed" })); + }); +} +function ariadneSetState(on) { + return new Promise((resolve, reject) => { + const { spawn } = require("child_process"); + // Elevated PowerShell — triggers UAC prompt. -Verb RunAs starts a separate + // elevated process; we can't easily capture its stdout, but we don't need + // to (re-query state afterwards). + const verb = on ? "Start-ScheduledTask" : "Stop-ScheduledTask"; + const cmd = `foreach ($t in 'BNS Resolver Daemon','BNS Sia Bridge') { try { ${verb} -TaskName $t -ErrorAction Stop } catch {} }`; + const ps = spawn("powershell.exe", ["-NoProfile", "-Command", + "Start-Process powershell -Verb RunAs -Wait -WindowStyle Hidden -ArgumentList '-NoProfile','-Command',\"" + cmd.replace(/"/g, "`\"") + "\""], { windowsHide: true }); + ps.on("close", (code) => { if (code === 0) resolve(true); else reject(new Error("UAC declined or task failed (exit " + code + ")")); }); + ps.on("error", (e) => reject(e)); + }); +} +ipcMain.handle("ariadne-state", () => ariadneQueryState().catch(() => ({ state: "not-installed" }))); +ipcMain.handle("ariadne-toggle", (_e, on) => ariadneSetState(!!on).catch((e) => ({ ok: false, error: e?.message || String(e) }))); // Storage: clear right now (any subset). "history" also drops the saved-session file. // ---- Password vault ------------------------------------------------------- // The vault lives at userData/passwords.vault (encrypted). Unlock state is diff --git a/settings-preload.js b/settings-preload.js index 9ff3787..0f3b6d8 100644 --- a/settings-preload.js +++ b/settings-preload.js @@ -31,6 +31,8 @@ contextBridge.exposeInMainWorld("cfg", { collisionState: () => ipcRenderer.invoke("collision-state"), setCollisionPolicy: (p) => ipcRenderer.invoke("collision-set-policy", p), resetCollisions: () => ipcRenderer.invoke("collision-reset"), + ariadneState: () => ipcRenderer.invoke("ariadne-state"), + ariadneToggle: (on) => ipcRenderer.invoke("ariadne-toggle", !!on), // Add-ons management (Settings > Add-ons tab). listAddons: () => ipcRenderer.invoke("addons-list"), setAddonEnabled: (id, enabled) => ipcRenderer.invoke("addons-set-enabled", id, !!enabled), diff --git a/settings.html b/settings.html index 307fa64..5b02eab 100644 --- a/settings.html +++ b/settings.html @@ -314,6 +314,29 @@
+
+
+
System-wide resolver — Ariadne's Thread
+
+ A local daemon that resolves BCDN names for every browser on this machine + (Chrome, Edge, Firefox, etc.), not just Theseus. Turning it off means non-Theseus + browsers stop resolving .bch / .x / other BCNR TLDs; + Theseus keeps working either way, since it has its own built-in resolver. +
+
+
checking…
+
+ + + +
+ +