2026-03-06 09:36:20 -06:00
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
|
import { buildJoinDefaultsPayloadForAccept } 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",
|
2026-03-06 10:14:57 -06:00
|
|
|
webhookAuthHeader: "Bearer gateway-token",
|
2026-03-06 09:36:20 -06:00
|
|
|
headers: {
|
|
|
|
|
"x-openclaw-auth": "gateway-token",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 10:14:57 -06:00
|
|
|
it("does not overwrite explicit OpenClaw endpoint defaults when already provided", () => {
|
2026-03-06 09:36:20 -06:00
|
|
|
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",
|
2026-03-06 10:14:57 -06:00
|
|
|
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",
|
2026-03-06 09:36:20 -06:00
|
|
|
headers: {
|
|
|
|
|
"x-openclaw-auth": "existing-token",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 12:06:08 -06:00
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 16:50:20 -06:00
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 12:06:08 -06:00
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 12:31:58 -06:00
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 12:49:41 -06:00
|
|
|
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",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-06 09:36:20 -06:00
|
|
|
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);
|
|
|
|
|
});
|
2026-03-07 16:01:19 -06:00
|
|
|
|
|
|
|
|
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",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
2026-03-06 09:36:20 -06:00
|
|
|
});
|