Skip to content

Commit a6e96bf

Browse files
ralyodioclaude
andauthored
dns ca: escalate itself for the system store, like dns enable; never advise sudo moshcode (#522)
bonita: sudo moshcode dns ca → sudo: 'moshcode': command not found, because moshcode lives in the operator's PATH, not root's. The verb now escalates this one command from inside (escalateSelf, which carries the path and lets operatorHome find the person behind sudo) and falls back to the browser store alone with a note when no sudo is on offer; --user-only skips the prompt on purpose. The two skipped-step hints that said sudo moshcode dns ca now say to run moshcode dns ca from a terminal. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent a04cc75 commit a6e96bf

3 files changed

Lines changed: 21 additions & 3 deletions

File tree

‎src/cli-schema.mjs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,8 @@ export const DNS_VERBS = [
11481148
name: "ca",
11491149
description: "trust the registry's root here, so every Moshpit name is trusted at once",
11501150
synopsis: [
1151-
["moshcode dns ca", "fetch the registry's root, check it, install it (NSS without root, the system store with sudo)"],
1151+
["moshcode dns ca", "fetch the registry's root, check it, install it everywhere (asks for sudo for the system store)"],
1152+
["moshcode dns ca --user-only", "the browser store only; no prompt"],
11521153
["moshcode dns ca --remove", "take it back out of every store"],
11531154
],
11541155
},

‎src/dns.mjs‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,6 +2625,23 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
26252625
// bridge, DoH in the browser, TronBrowser's own resolver) but its clients
26262626
// still refuse the certificates. `--remove` takes it back out.
26272627
if (sub === "ca") {
2628+
// Half of this needs root (the system store) and half must not run as
2629+
// root's own user (the operator's NSS database), which is exactly the
2630+
// shape `dns enable` already handles: escalate this one command, and let
2631+
// operatorHome() find the person behind sudo. `sudo moshcode dns ca` from
2632+
// a shell is what bonita hit: moshcode lives in the operator's PATH, not
2633+
// root's, so "command not found". Escalating from inside carries the path.
2634+
// --user-only keeps it to the browser store, no prompt, for a machine
2635+
// where sudo is not on offer.
2636+
if (uid !== 0 && !rest.includes("--user-only")) {
2637+
const escalated = escalate({
2638+
args: ["dns", "ca", ...rest],
2639+
what: "dns ca",
2640+
out,
2641+
});
2642+
if (escalated.ran) return escalated.code;
2643+
out("(no sudo here — installing into the browser store only; the system store needs root)");
2644+
}
26282645
if (rest.includes("--remove")) {
26292646
const r = await removeRegistryTrust(out, deps);
26302647
return r.ok ? 0 : 1;

‎src/trust.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ export async function applyRegistryTrust(out, deps = {}) {
11671167
}
11681168
for (const step of plan.skipped) {
11691169
out(` -- ${step.label} — ${step.why}`);
1170-
if (step.needsRoot) out(" re-run with root to cover it: sudo moshcode dns ca");
1170+
if (step.needsRoot) out(" run `moshcode dns ca` from a terminal to cover it — it asks for sudo itself");
11711171
}
11721172
return { ok: true, installed, skipped: plan.skipped.length, file };
11731173
}
@@ -1225,7 +1225,7 @@ export async function removeRegistryTrust(out, deps = {}) {
12251225
if (haveFile) await runner("rm", ["-f", file]);
12261226
for (const step of plan.skipped) {
12271227
out(` -- ${step.label} — ${step.why}`);
1228-
if (step.needsRoot && uid !== 0) out(" re-run with root to cover it: sudo moshcode dns ca --remove");
1228+
if (step.needsRoot && uid !== 0) out(" run `moshcode dns ca --remove` from a terminal to cover it — it asks for sudo itself");
12291229
}
12301230
return { ok: true, removed, skipped: plan.skipped.length };
12311231
}

0 commit comments

Comments
 (0)