Accept OpenClaw auth headers in more payload formats
This commit is contained in:
@@ -70,6 +70,46 @@ describe("buildJoinDefaultsPayloadForAccept", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 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("leaves non-openclaw payloads unchanged", () => {
|
it("leaves non-openclaw payloads unchanged", () => {
|
||||||
const defaultsPayload = { command: "echo hello" };
|
const defaultsPayload = { command: "echo hello" };
|
||||||
const result = buildJoinDefaultsPayloadForAccept({
|
const result = buildJoinDefaultsPayloadForAccept({
|
||||||
|
|||||||
@@ -128,13 +128,41 @@ function normalizeHostname(value: string | null | undefined): string | null {
|
|||||||
return trimmed.toLowerCase();
|
return trimmed.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeHeaderValue(
|
||||||
|
value: unknown,
|
||||||
|
depth: number = 0,
|
||||||
|
): string | null {
|
||||||
|
const direct = nonEmptyTrimmedString(value);
|
||||||
|
if (direct) return direct;
|
||||||
|
if (!isPlainObject(value) || depth >= 2) return null;
|
||||||
|
|
||||||
|
const candidateKeys = [
|
||||||
|
"value",
|
||||||
|
"token",
|
||||||
|
"secret",
|
||||||
|
"apiKey",
|
||||||
|
"api_key",
|
||||||
|
"auth",
|
||||||
|
"authorization",
|
||||||
|
"bearer",
|
||||||
|
"header",
|
||||||
|
];
|
||||||
|
for (const key of candidateKeys) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
||||||
|
const normalized = normalizeHeaderValue((value as Record<string, unknown>)[key], depth + 1);
|
||||||
|
if (normalized) return normalized;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeHeaderMap(input: unknown): Record<string, string> | undefined {
|
function normalizeHeaderMap(input: unknown): Record<string, string> | undefined {
|
||||||
if (!isPlainObject(input)) return undefined;
|
if (!isPlainObject(input)) return undefined;
|
||||||
const out: Record<string, string> = {};
|
const out: Record<string, string> = {};
|
||||||
for (const [key, value] of Object.entries(input)) {
|
for (const [key, value] of Object.entries(input)) {
|
||||||
if (typeof value !== "string") continue;
|
const normalizedValue = normalizeHeaderValue(value);
|
||||||
|
if (!normalizedValue) continue;
|
||||||
const trimmedKey = key.trim();
|
const trimmedKey = key.trim();
|
||||||
const trimmedValue = value.trim();
|
const trimmedValue = normalizedValue.trim();
|
||||||
if (!trimmedKey || !trimmedValue) continue;
|
if (!trimmedKey || !trimmedValue) continue;
|
||||||
out[trimmedKey] = trimmedValue;
|
out[trimmedKey] = trimmedValue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user