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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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(); }); });