@lifeaitools/clauth 1.5.6 → 1.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/commands/serve.js +35 -1
- package/package.json +1 -1
package/cli/commands/serve.js
CHANGED
|
@@ -739,6 +739,7 @@ function dashboardHtml(port, whitelist, isStaged = false) {
|
|
|
739
739
|
<button class="btn-add" onclick="toggleAddService()">+ Add Service</button>
|
|
740
740
|
<button class="btn-check" id="check-btn" onclick="checkAll()">⬤ Check All</button>
|
|
741
741
|
<button class="btn-lock" onclick="lockVault()">🔒 Lock</button>
|
|
742
|
+
<button class="btn-stop" onclick="restartDaemon()" style="background:#1a2e1a;border:1px solid #166534;color:#86efac" title="Restart daemon — keeps vault unlocked">↺ Restart</button>
|
|
742
743
|
<button class="btn-stop" onclick="stopDaemon()" style="background:#7f1d1d;border:1px solid #991b1b;color:#fca5a5" title="Stop daemon — password required on next start">⏹ Stop</button>
|
|
743
744
|
<button class="btn-cancel" style="margin-left:auto" onclick="toggleChangePw()">Change Password</button>
|
|
744
745
|
</div>
|
|
@@ -1131,6 +1132,17 @@ async function makeLive() {
|
|
|
1131
1132
|
}
|
|
1132
1133
|
}
|
|
1133
1134
|
|
|
1135
|
+
// ── Restart daemon (keeps boot.key — vault stays unlocked) ──
|
|
1136
|
+
async function restartDaemon() {
|
|
1137
|
+
if (!confirm("Restart the daemon?\\n\\nThe vault will stay unlocked (boot.key kept).")) return;
|
|
1138
|
+
const btn = document.querySelector('[onclick="restartDaemon()"]');
|
|
1139
|
+
if (btn) { btn.disabled = true; btn.textContent = "↺ Restarting…"; }
|
|
1140
|
+
try {
|
|
1141
|
+
await fetch(BASE + "/restart", { method: "POST" });
|
|
1142
|
+
} catch {}
|
|
1143
|
+
document.getElementById("main-view").innerHTML = '<div style="text-align:center;padding:80px 20px"><div style="font-size:3rem;margin-bottom:16px">↺</div><div style="font-size:1.1rem;color:#86efac">Restarting…</div><div style="font-size:.85rem;color:#64748b;margin-top:8px">Page will reload automatically.</div></div>';
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1134
1146
|
// ── Stop daemon (user-initiated — clears boot.key, requires password on restart) ──
|
|
1135
1147
|
async function stopDaemon() {
|
|
1136
1148
|
if (!confirm("Stop the daemon?\\n\\nCredentials will need to be re-entered on next start.")) return;
|
|
@@ -3272,6 +3284,28 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
3272
3284
|
return ok(res, { status: tunnelStatus });
|
|
3273
3285
|
}
|
|
3274
3286
|
|
|
3287
|
+
// POST /restart — spawn fresh process then exit (keeps boot.key, vault stays unlocked)
|
|
3288
|
+
if (method === "POST" && reqPath === "/restart") {
|
|
3289
|
+
ok(res, { ok: true, message: "restarting" });
|
|
3290
|
+
const { spawn } = await import("child_process");
|
|
3291
|
+
const cliEntry = path.resolve(__dirname, "../index.js");
|
|
3292
|
+
const childArgs = [cliEntry, "serve", "start", "--port", String(port)];
|
|
3293
|
+
if (password) childArgs.push("--pw", password);
|
|
3294
|
+
if (whitelist) childArgs.push("--services", whitelist.join(","));
|
|
3295
|
+
if (tunnelHostname) childArgs.push("--tunnel", tunnelHostname);
|
|
3296
|
+
const out = fs.openSync(LOG_FILE, "a");
|
|
3297
|
+
const child = spawn(process.execPath, childArgs, {
|
|
3298
|
+
detached: true,
|
|
3299
|
+
stdio: ["ignore", out, out],
|
|
3300
|
+
env: { ...process.env, __CLAUTH_DAEMON: "1" },
|
|
3301
|
+
});
|
|
3302
|
+
child.unref();
|
|
3303
|
+
stopTunnel();
|
|
3304
|
+
removePid();
|
|
3305
|
+
setTimeout(() => process.exit(0), 300);
|
|
3306
|
+
return;
|
|
3307
|
+
}
|
|
3308
|
+
|
|
3275
3309
|
// GET|POST /shutdown (for daemon stop — programmatic, keeps boot.key)
|
|
3276
3310
|
// Accept POST as well — older scripts and curl default to POST
|
|
3277
3311
|
if ((method === "GET" || method === "POST") && reqPath === "/shutdown") {
|
|
@@ -4287,7 +4321,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
4287
4321
|
// Don't count browser noise, MCP discovery probes, or OAuth probes as auth failures
|
|
4288
4322
|
const isBenign = reqPath.startsWith("/.well-known/") || [
|
|
4289
4323
|
"/favicon.ico", "/robots.txt", "/apple-touch-icon.png", "/apple-touch-icon-precomposed.png",
|
|
4290
|
-
"/sse", "/mcp", "/message", "/register", "/authorize", "/token", "/shutdown",
|
|
4324
|
+
"/sse", "/mcp", "/message", "/register", "/authorize", "/token", "/shutdown", "/restart",
|
|
4291
4325
|
].includes(reqPath);
|
|
4292
4326
|
if (isBenign) {
|
|
4293
4327
|
res.writeHead(404, { "Content-Type": "application/json", ...CORS });
|