Files
openclaw-zero-token/commands/configure.gateway-auth.test.ts
sjhu 571e14a236 feat: upgrade to upstream v2026.3.28
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
2026-03-30 17:58:12 +08:00

217 lines
5.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { buildGatewayAuthConfig } from "./configure.js";
function expectGeneratedTokenFromInput(
token: string | undefined,
forbiddenValues: string[] = ["undefined"],
) {
const result = buildGatewayAuthConfig({
mode: "token",
token,
});
expect(result?.mode).toBe("token");
expect(typeof result?.token).toBe("string");
if (typeof result?.token !== "string") {
throw new Error("Expected generated token to be a string.");
}
for (const forbiddenValue of forbiddenValues) {
expect(result.token).not.toBe(forbiddenValue);
}
expect(result.token.length).toBeGreaterThan(0);
}
describe("buildGatewayAuthConfig", () => {
it("preserves allowTailscale when switching to token", () => {
const result = buildGatewayAuthConfig({
existing: {
mode: "password",
password: "secret", // pragma: allowlist secret
allowTailscale: true,
},
mode: "token",
token: "abc",
});
expect(result).toEqual({ mode: "token", token: "abc", allowTailscale: true });
});
it("drops password when switching to token", () => {
const result = buildGatewayAuthConfig({
existing: {
mode: "password",
password: "secret", // pragma: allowlist secret
allowTailscale: false,
},
mode: "token",
token: "abc",
});
expect(result).toEqual({
mode: "token",
token: "abc",
allowTailscale: false,
});
});
it("drops token when switching to password", () => {
const result = buildGatewayAuthConfig({
existing: { mode: "token", token: "abc" },
mode: "password",
password: "secret", // pragma: allowlist secret
});
expect(result).toEqual({ mode: "password", password: "secret" }); // pragma: allowlist secret
});
it("does not silently omit password when literal string is provided", () => {
const result = buildGatewayAuthConfig({
mode: "password",
password: "undefined", // pragma: allowlist secret
});
expect(result).toEqual({ mode: "password", password: "undefined" }); // pragma: allowlist secret
});
it("generates random token for missing, empty, and coerced-literal token inputs", () => {
expectGeneratedTokenFromInput(undefined);
expectGeneratedTokenFromInput("", [""]);
expectGeneratedTokenFromInput(" ", [""]);
expectGeneratedTokenFromInput("undefined", ["undefined"]);
expectGeneratedTokenFromInput("null", ["null"]);
});
it("trims and preserves explicit token values", () => {
const result = buildGatewayAuthConfig({
mode: "token",
token: " abc123 ",
});
expect(result).toEqual({ mode: "token", token: "abc123" });
});
it("trims password values before storing them", () => {
const result = buildGatewayAuthConfig({
mode: "password",
password: " secret ", // pragma: allowlist secret
});
expect(result).toEqual({ mode: "password", password: "secret" }); // pragma: allowlist secret
});
it("keeps password mode valid even when the trimmed password becomes empty", () => {
const result = buildGatewayAuthConfig({
mode: "password",
password: " ",
});
expect(result).toEqual({ mode: "password" });
});
it("preserves SecretRef tokens when token mode is selected", () => {
const tokenRef = {
source: "env",
provider: "default",
id: "OPENCLAW_GATEWAY_TOKEN",
} as const;
const result = buildGatewayAuthConfig({
mode: "token",
token: tokenRef,
});
expect(result).toEqual({
mode: "token",
token: tokenRef,
});
});
it("builds trusted-proxy config with all options", () => {
const result = buildGatewayAuthConfig({
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
allowUsers: ["nick@example.com", "admin@company.com"],
},
});
expect(result).toEqual({
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
allowUsers: ["nick@example.com", "admin@company.com"],
},
});
});
it("builds trusted-proxy config with only userHeader", () => {
const result = buildGatewayAuthConfig({
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-remote-user",
},
});
expect(result).toEqual({
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-remote-user",
},
});
});
it("preserves allowTailscale when switching to trusted-proxy", () => {
const result = buildGatewayAuthConfig({
existing: {
mode: "token",
token: "abc",
allowTailscale: true,
},
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
});
expect(result).toEqual({
mode: "trusted-proxy",
allowTailscale: true,
trustedProxy: {
userHeader: "x-forwarded-user",
},
});
});
it("throws error when trusted-proxy mode lacks trustedProxy config", () => {
expect(() => {
buildGatewayAuthConfig({
mode: "trusted-proxy",
// missing trustedProxy
});
}).toThrow("trustedProxy config is required when mode is trusted-proxy");
});
it("drops token and password when switching to trusted-proxy", () => {
const result = buildGatewayAuthConfig({
existing: {
mode: "token",
token: "abc",
password: "secret", // pragma: allowlist secret
},
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
});
expect(result).toEqual({
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
});
expect(result).not.toHaveProperty("token");
expect(result).not.toHaveProperty("password");
});
});