295 lines
8.7 KiB
TypeScript
295 lines
8.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
buildJoinDefaultsPayloadForAccept,
|
|
normalizeAgentDefaultsForJoin,
|
|
} from "../routes/access.js";
|
|
|
|
describe("buildJoinDefaultsPayloadForAccept", () => {
|
|
it("maps OpenClaw compatibility fields into agent defaults", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: null,
|
|
responsesWebhookUrl: "http://localhost:18789/v1/responses",
|
|
paperclipApiUrl: "http://host.docker.internal:3100",
|
|
inboundOpenClawAuthHeader: "gateway-token",
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
url: "http://localhost:18789/v1/responses",
|
|
paperclipApiUrl: "http://host.docker.internal:3100",
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("does not overwrite explicit OpenClaw endpoint defaults when already provided", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
url: "https://example.com/v1/responses",
|
|
method: "POST",
|
|
headers: {
|
|
"x-openclaw-auth": "existing-token",
|
|
},
|
|
paperclipApiUrl: "https://paperclip.example.com",
|
|
},
|
|
responsesWebhookUrl: "https://legacy.example.com/v1/responses",
|
|
responsesWebhookMethod: "PUT",
|
|
paperclipApiUrl: "https://legacy-paperclip.example.com",
|
|
inboundOpenClawAuthHeader: "legacy-token",
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
url: "https://example.com/v1/responses",
|
|
method: "POST",
|
|
paperclipApiUrl: "https://paperclip.example.com",
|
|
webhookAuthHeader: "Bearer existing-token",
|
|
headers: {
|
|
"x-openclaw-auth": "existing-token",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("preserves explicit webhookAuthHeader when configured", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
url: "https://example.com/v1/responses",
|
|
webhookAuthHeader: "Bearer explicit-token",
|
|
headers: {
|
|
"x-openclaw-auth": "existing-token",
|
|
},
|
|
},
|
|
inboundOpenClawAuthHeader: "legacy-token",
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
webhookAuthHeader: "Bearer explicit-token",
|
|
headers: {
|
|
"x-openclaw-auth": "existing-token",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("accepts auth from agentDefaultsPayload.headers.x-openclaw-auth", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
url: "http://127.0.0.1:18789/v1/responses",
|
|
method: "POST",
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts auth from agentDefaultsPayload.headers.x-openclaw-token", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
url: "http://127.0.0.1:18789/hooks/agent",
|
|
method: "POST",
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token",
|
|
},
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts inbound x-openclaw-token compatibility header", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: null,
|
|
inboundOpenClawTokenHeader: "gateway-token",
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts wrapped auth values in headers for compatibility", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
headers: {
|
|
"x-openclaw-auth": {
|
|
value: "gateway-token",
|
|
},
|
|
},
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts auth headers provided as tuple entries", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
headers: [["x-openclaw-auth", "gateway-token"]],
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts auth headers provided as name/value entries", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
headers: [{ name: "x-openclaw-auth", value: { authToken: "gateway-token" } }],
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("accepts auth headers wrapped in a single unknown key", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw",
|
|
defaultsPayload: {
|
|
headers: {
|
|
"x-openclaw-auth": {
|
|
gatewayToken: "gateway-token",
|
|
},
|
|
},
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-auth": "gateway-token",
|
|
},
|
|
webhookAuthHeader: "Bearer gateway-token",
|
|
});
|
|
});
|
|
|
|
it("leaves non-openclaw payloads unchanged", () => {
|
|
const defaultsPayload = { command: "echo hello" };
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "process",
|
|
defaultsPayload,
|
|
responsesWebhookUrl: "https://ignored.example.com",
|
|
inboundOpenClawAuthHeader: "ignored-token",
|
|
});
|
|
|
|
expect(result).toEqual(defaultsPayload);
|
|
});
|
|
|
|
it("normalizes wrapped gateway token headers for openclaw_gateway", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw_gateway",
|
|
defaultsPayload: {
|
|
url: "ws://127.0.0.1:18789",
|
|
headers: {
|
|
"x-openclaw-token": {
|
|
value: "gateway-token-1234567890",
|
|
},
|
|
},
|
|
},
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
url: "ws://127.0.0.1:18789",
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token-1234567890",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("accepts inbound x-openclaw-token for openclaw_gateway", () => {
|
|
const result = buildJoinDefaultsPayloadForAccept({
|
|
adapterType: "openclaw_gateway",
|
|
defaultsPayload: {
|
|
url: "ws://127.0.0.1:18789",
|
|
},
|
|
inboundOpenClawTokenHeader: "gateway-token-1234567890",
|
|
}) as Record<string, unknown>;
|
|
|
|
expect(result).toMatchObject({
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token-1234567890",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("generates persistent device key for openclaw_gateway when device auth is enabled", () => {
|
|
const normalized = normalizeAgentDefaultsForJoin({
|
|
adapterType: "openclaw_gateway",
|
|
defaultsPayload: {
|
|
url: "ws://127.0.0.1:18789",
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token-1234567890",
|
|
},
|
|
disableDeviceAuth: false,
|
|
},
|
|
deploymentMode: "authenticated",
|
|
deploymentExposure: "private",
|
|
bindHost: "127.0.0.1",
|
|
allowedHostnames: [],
|
|
});
|
|
|
|
expect(normalized.fatalErrors).toEqual([]);
|
|
expect(normalized.normalized?.disableDeviceAuth).toBe(false);
|
|
expect(typeof normalized.normalized?.devicePrivateKeyPem).toBe("string");
|
|
expect((normalized.normalized?.devicePrivateKeyPem as string).length).toBeGreaterThan(64);
|
|
});
|
|
|
|
it("does not generate device key when openclaw_gateway has disableDeviceAuth=true", () => {
|
|
const normalized = normalizeAgentDefaultsForJoin({
|
|
adapterType: "openclaw_gateway",
|
|
defaultsPayload: {
|
|
url: "ws://127.0.0.1:18789",
|
|
headers: {
|
|
"x-openclaw-token": "gateway-token-1234567890",
|
|
},
|
|
disableDeviceAuth: true,
|
|
},
|
|
deploymentMode: "authenticated",
|
|
deploymentExposure: "private",
|
|
bindHost: "127.0.0.1",
|
|
allowedHostnames: [],
|
|
});
|
|
|
|
expect(normalized.fatalErrors).toEqual([]);
|
|
expect(normalized.normalized?.disableDeviceAuth).toBe(true);
|
|
expect(normalized.normalized?.devicePrivateKeyPem).toBeUndefined();
|
|
});
|
|
});
|