openclaw/src/gateway/probe-auth.test.ts

193 lines
5.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import {
resolveGatewayProbeAuthSafe,
resolveGatewayProbeAuthSafeWithSecretInputs,
resolveGatewayProbeAuthWithSecretInputs,
} from "./probe-auth.js";
function expectUnresolvedProbeTokenWarning(cfg: OpenClawConfig) {
const result = resolveGatewayProbeAuthSafe({
cfg,
mode: "local",
env: {} as NodeJS.ProcessEnv,
});
expect(result.auth).toEqual({});
expect(result.warning).toContain("gateway.auth.token");
expect(result.warning).toContain("unresolved");
}
describe("resolveGatewayProbeAuthSafe", () => {
it("returns probe auth credentials when available", () => {
const result = resolveGatewayProbeAuthSafe({
cfg: {
gateway: {
auth: {
token: "token-value",
},
},
} as OpenClawConfig,
mode: "local",
env: {} as NodeJS.ProcessEnv,
});
expect(result).toEqual({
auth: {
token: "token-value",
password: undefined,
},
});
});
it("returns warning and empty auth when token SecretRef is unresolved", () => {
expectUnresolvedProbeTokenWarning({
gateway: {
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "MISSING_GATEWAY_TOKEN" },
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig);
});
it("does not fall through to remote token when local token SecretRef is unresolved", () => {
expectUnresolvedProbeTokenWarning({
gateway: {
mode: "local",
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "MISSING_GATEWAY_TOKEN" },
},
remote: {
token: "remote-token",
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig);
});
it("ignores unresolved local token SecretRef in remote mode when remote-only auth is requested", () => {
const result = resolveGatewayProbeAuthSafe({
cfg: {
gateway: {
mode: "remote",
remote: {
url: "wss://gateway.example",
},
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "MISSING_LOCAL_TOKEN" },
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig,
mode: "remote",
env: {} as NodeJS.ProcessEnv,
});
expect(result).toEqual({
auth: {
token: undefined,
password: undefined,
},
});
});
});
describe("resolveGatewayProbeAuthSafeWithSecretInputs", () => {
it("resolves env SecretRef token via async secret-inputs path", async () => {
const result = await resolveGatewayProbeAuthSafeWithSecretInputs({
cfg: {
gateway: {
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "OPENCLAW_GATEWAY_TOKEN" },
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig,
mode: "local",
env: {
OPENCLAW_GATEWAY_TOKEN: "test-token-from-env",
} as NodeJS.ProcessEnv,
});
expect(result.warning).toBeUndefined();
expect(result.auth).toEqual({
token: "test-token-from-env",
password: undefined,
});
});
it("returns warning and empty auth when SecretRef cannot be resolved via async path", async () => {
const result = await resolveGatewayProbeAuthSafeWithSecretInputs({
cfg: {
gateway: {
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "MISSING_TOKEN_XYZ" },
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig,
mode: "local",
env: {} as NodeJS.ProcessEnv,
});
expect(result.auth).toEqual({});
expect(result.warning).toContain("gateway.auth.token");
expect(result.warning).toContain("unresolved");
});
});
describe("resolveGatewayProbeAuthWithSecretInputs", () => {
it("resolves local probe SecretRef values before shared credential selection", async () => {
const auth = await resolveGatewayProbeAuthWithSecretInputs({
cfg: {
gateway: {
auth: {
mode: "token",
token: { source: "env", provider: "default", id: "DAEMON_GATEWAY_TOKEN" },
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
} as OpenClawConfig,
mode: "local",
env: {
DAEMON_GATEWAY_TOKEN: "resolved-daemon-token",
} as NodeJS.ProcessEnv,
});
expect(auth).toEqual({
token: "resolved-daemon-token",
password: undefined,
});
});
});