From 9448fd083b41eac8adddd59e8bc3157eb9da8723 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Thu, 20 Aug 2026 23:01:34 -0700 Subject: [PATCH] fix(update): scope TUI gate to local user --- src/infra/local-tui-processes.test.ts | 7 +++++++ src/infra/local-tui-processes.ts | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/infra/local-tui-processes.test.ts b/src/infra/local-tui-processes.test.ts index b8dcdf78e9b7..fcccb27b9239 100644 --- a/src/infra/local-tui-processes.test.ts +++ b/src/infra/local-tui-processes.test.ts @@ -2,11 +2,18 @@ import { describe, expect, it, vi } from "vitest"; import { listLocalTuiProcesses, quiesceLocalTuiProcessesBeforeUpdate, + resolveLocalTuiUpdateLockPath, terminateLocalTuiProcesses, waitForLocalTuiUpdate, } from "./local-tui-processes.js"; describe("local TUI processes", () => { + it("scopes the update gate to the invoking user's home", () => { + expect(resolveLocalTuiUpdateLockPath("/home/alice")).not.toBe( + resolveLocalTuiUpdateLockPath("/home/bob"), + ); + }); + it("lists only verified local TUI processes from ps output", () => { const spawnSync = vi.fn().mockReturnValue({ status: 0, diff --git a/src/infra/local-tui-processes.ts b/src/infra/local-tui-processes.ts index d3682b5ee367..39ab585bc2df 100644 --- a/src/infra/local-tui-processes.ts +++ b/src/infra/local-tui-processes.ts @@ -1,4 +1,5 @@ import { spawnSync, type SpawnSyncOptionsWithStringEncoding } from "node:child_process"; +import { createHash } from "node:crypto"; import os from "node:os"; import path from "node:path"; import { parseCmdScriptCommandLine } from "../daemon/cmd-argv.js"; @@ -29,7 +30,12 @@ type PsResult = { const LOCAL_TUI_SUBCOMMANDS = new Set(["chat", "terminal", "tui"]); const LOCAL_TUI_PROCESS_PROBE_TIMEOUT_MS = 1_000; -const LOCAL_TUI_UPDATE_LOCK_PATH = path.join(os.tmpdir(), "openclaw-local-tui-update"); +export function resolveLocalTuiUpdateLockPath(userHome = os.homedir()): string { + const ownerScope = createHash("sha256").update(userHome).digest("hex").slice(0, 16); + return path.join(os.tmpdir(), `openclaw-local-tui-update-${ownerScope}`); +} + +const LOCAL_TUI_UPDATE_LOCK_PATH = resolveLocalTuiUpdateLockPath(); const LOCAL_TUI_UPDATE_LOCK_OPTIONS = { stale: 30_000, retries: { retries: 100, factor: 1, minTimeout: 50, maxTimeout: 250 },