diff --git a/scripts/lib/openclaw-test-state.mjs b/scripts/lib/openclaw-test-state.mjs index fccbbf89eed..8e017d9eaa1 100644 --- a/scripts/lib/openclaw-test-state.mjs +++ b/scripts/lib/openclaw-test-state.mjs @@ -1,4 +1,5 @@ #!/usr/bin/env node +import { randomBytes } from "node:crypto"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; @@ -7,7 +8,6 @@ import { fileURLToPath } from "node:url"; const DEFAULT_LABEL = "state"; const DEFAULT_SCENARIO = "empty"; -const TEST_AUTH_PROFILE_SECRET_KEY = "openclaw-test-state-auth-profile-secret-key"; const SCENARIOS = new Set([ "empty", "minimal", @@ -253,6 +253,17 @@ function renderExports(env) { .join("\n"); } +function generateAuthProfileSecretKey() { + return randomBytes(32).toString("base64url"); +} + +function renderAuthProfileSecretKeyExport() { + return [ + `OPENCLAW_AUTH_PROFILE_SECRET_KEY="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"`, + "export OPENCLAW_AUTH_PROFILE_SECRET_KEY", + ]; +} + function renderConfigWrite(configPathExpression, config) { if (config === undefined) { return ""; @@ -283,7 +294,7 @@ function buildCreatePlan(options = {}) { OPENCLAW_HOME: home, OPENCLAW_STATE_DIR: stateDir, OPENCLAW_CONFIG_PATH: configPath, - OPENCLAW_AUTH_PROFILE_SECRET_KEY: TEST_AUTH_PROFILE_SECRET_KEY, + OPENCLAW_AUTH_PROFILE_SECRET_KEY: generateAuthProfileSecretKey(), ...scenarioEnv(scenario), }; return { @@ -332,7 +343,7 @@ export function renderShellSnippet(options = {}) { 'export OPENCLAW_HOME="$OPENCLAW_TEST_STATE_HOME"', 'export OPENCLAW_STATE_DIR="$OPENCLAW_TEST_STATE_HOME/.openclaw"', 'export OPENCLAW_CONFIG_PATH="$OPENCLAW_STATE_DIR/openclaw.json"', - `export OPENCLAW_AUTH_PROFILE_SECRET_KEY=${shellQuote(TEST_AUTH_PROFILE_SECRET_KEY)}`, + ...renderAuthProfileSecretKeyExport(), 'export OPENCLAW_TEST_WORKSPACE_DIR="$OPENCLAW_TEST_STATE_HOME/workspace"', 'mkdir -p "$OPENCLAW_STATE_DIR" "$OPENCLAW_TEST_WORKSPACE_DIR"', ]; @@ -376,7 +387,7 @@ export function renderShellFunction() { export OPENCLAW_HOME="$OPENCLAW_TEST_STATE_HOME" export OPENCLAW_STATE_DIR="$OPENCLAW_TEST_STATE_HOME/.openclaw" export OPENCLAW_CONFIG_PATH="$OPENCLAW_STATE_DIR/openclaw.json" - export OPENCLAW_AUTH_PROFILE_SECRET_KEY=${shellQuote(TEST_AUTH_PROFILE_SECRET_KEY)} + ${renderAuthProfileSecretKeyExport().join("\n ")} export OPENCLAW_TEST_WORKSPACE_DIR="$OPENCLAW_TEST_STATE_HOME/workspace" unset OPENCLAW_AGENT_DIR unset PI_CODING_AGENT_DIR diff --git a/test/scripts/openclaw-test-state.test.ts b/test/scripts/openclaw-test-state.test.ts index 290deb4702c..3391822f263 100644 --- a/test/scripts/openclaw-test-state.test.ts +++ b/test/scripts/openclaw-test-state.test.ts @@ -19,6 +19,12 @@ function escapeRegex(value: string): string { return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"); } +function expectGeneratedSecretKey(value: string | undefined): void { + expect(typeof value).toBe("string"); + expect(value?.length ?? 0).toBeGreaterThan(20); + expect(value).not.toBe("openclaw-test-state-auth-profile-secret-key"); +} + describe("scripts/lib/openclaw-test-state", () => { it("creates a sourceable env file and JSON description", async () => { const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-state-script-")); @@ -47,13 +53,14 @@ describe("scripts/lib/openclaw-test-state", () => { expect(payload.stateDir).toBe(path.join(payload.home, ".openclaw")); expect(payload.configPath).toBe(path.join(payload.stateDir, "openclaw.json")); expect(payload.workspaceDir).toBe(path.join(payload.home, "workspace")); + expectGeneratedSecretKey(payload.env.OPENCLAW_AUTH_PROFILE_SECRET_KEY); expect(payload.env).toEqual({ HOME: payload.home, USERPROFILE: payload.home, OPENCLAW_HOME: payload.home, OPENCLAW_STATE_DIR: payload.stateDir, OPENCLAW_CONFIG_PATH: payload.configPath, - OPENCLAW_AUTH_PROFILE_SECRET_KEY: "openclaw-test-state-auth-profile-secret-key", + OPENCLAW_AUTH_PROFILE_SECRET_KEY: payload.env.OPENCLAW_AUTH_PROFILE_SECRET_KEY, }); expect(payload.config).toEqual({ update: { @@ -76,7 +83,7 @@ describe("scripts/lib/openclaw-test-state", () => { expect(JSON.parse(probe.stdout)).toEqual({ home: payload.home, stateDir: payload.stateDir, - secretKey: "openclaw-test-state-auth-profile-secret-key", + secretKey: payload.env.OPENCLAW_AUTH_PROFILE_SECRET_KEY, channel: "stable", }); await fs.rm(payload.root, { recursive: true, force: true }); @@ -119,7 +126,7 @@ describe("scripts/lib/openclaw-test-state", () => { ); expect(payload.openclawHome).toBe(payload.home); expect(payload.workspace).toBe(`${payload.home}/workspace`); - expect(payload.secretKey).toBe("openclaw-test-state-auth-profile-secret-key"); + expectGeneratedSecretKey(payload.secretKey); expect(payload.channel).toBe("stable"); const customTemp = path.join(tempRoot, "state-tmp"); @@ -194,7 +201,7 @@ describe("scripts/lib/openclaw-test-state", () => { expect(payload.home).toContain("/openclaw-onboard-case-minimal-home."); expect(payload.agentDir).toBeNull(); expect(payload.workspace).toBe(`${payload.home}/workspace`); - expect(payload.secretKey).toBe("openclaw-test-state-auth-profile-secret-key"); + expectGeneratedSecretKey(payload.secretKey); expect(payload.config).toStrictEqual({}); const existingHome = path.join(tempRoot, "existing-home");