mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 09:28:37 +00:00
refactor(extensions): dedupe channel config, onboarding, and monitors
This commit is contained in:
@@ -86,6 +86,18 @@ function twilioSignature(params: { authToken: string; url: string; postBody: str
|
||||
return crypto.createHmac("sha1", params.authToken).update(dataToSign).digest("base64");
|
||||
}
|
||||
|
||||
function expectReplayResultPair(
|
||||
first: { ok: boolean; isReplay?: boolean; verifiedRequestKey?: string },
|
||||
second: { ok: boolean; isReplay?: boolean; verifiedRequestKey?: string },
|
||||
) {
|
||||
expect(first.ok).toBe(true);
|
||||
expect(first.isReplay).toBeFalsy();
|
||||
expect(first.verifiedRequestKey).toBeTruthy();
|
||||
expect(second.ok).toBe(true);
|
||||
expect(second.isReplay).toBe(true);
|
||||
expect(second.verifiedRequestKey).toBe(first.verifiedRequestKey);
|
||||
}
|
||||
|
||||
describe("verifyPlivoWebhook", () => {
|
||||
it("accepts valid V2 signature", () => {
|
||||
const authToken = "test-auth-token";
|
||||
@@ -196,12 +208,7 @@ describe("verifyPlivoWebhook", () => {
|
||||
const first = verifyPlivoWebhook(ctx, authToken);
|
||||
const second = verifyPlivoWebhook(ctx, authToken);
|
||||
|
||||
expect(first.ok).toBe(true);
|
||||
expect(first.isReplay).toBeFalsy();
|
||||
expect(first.verifiedRequestKey).toBeTruthy();
|
||||
expect(second.ok).toBe(true);
|
||||
expect(second.isReplay).toBe(true);
|
||||
expect(second.verifiedRequestKey).toBe(first.verifiedRequestKey);
|
||||
expectReplayResultPair(first, second);
|
||||
});
|
||||
|
||||
it("returns a stable request key when verification is skipped", () => {
|
||||
@@ -245,12 +252,7 @@ describe("verifyTelnyxWebhook", () => {
|
||||
const first = verifyTelnyxWebhook(ctx, pemPublicKey);
|
||||
const second = verifyTelnyxWebhook(ctx, pemPublicKey);
|
||||
|
||||
expect(first.ok).toBe(true);
|
||||
expect(first.isReplay).toBeFalsy();
|
||||
expect(first.verifiedRequestKey).toBeTruthy();
|
||||
expect(second.ok).toBe(true);
|
||||
expect(second.isReplay).toBe(true);
|
||||
expect(second.verifiedRequestKey).toBe(first.verifiedRequestKey);
|
||||
expectReplayResultPair(first, second);
|
||||
});
|
||||
|
||||
it("returns a stable request key when verification is skipped", () => {
|
||||
|
||||
@@ -55,6 +55,21 @@ const createManager = (calls: CallRecord[]) => {
|
||||
return { manager, endCall, processEvent };
|
||||
};
|
||||
|
||||
async function postWebhookForm(server: VoiceCallWebhookServer, baseUrl: string, body: string) {
|
||||
const address = (
|
||||
server as unknown as { server?: { address?: () => unknown } }
|
||||
).server?.address?.();
|
||||
const requestUrl = new URL(baseUrl);
|
||||
if (address && typeof address === "object" && "port" in address && address.port) {
|
||||
requestUrl.port = String(address.port);
|
||||
}
|
||||
return await fetch(requestUrl.toString(), {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
describe("VoiceCallWebhookServer stale call reaper", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
@@ -146,18 +161,7 @@ describe("VoiceCallWebhookServer replay handling", () => {
|
||||
|
||||
try {
|
||||
const baseUrl = await server.start();
|
||||
const address = (
|
||||
server as unknown as { server?: { address?: () => unknown } }
|
||||
).server?.address?.();
|
||||
const requestUrl = new URL(baseUrl);
|
||||
if (address && typeof address === "object" && "port" in address && address.port) {
|
||||
requestUrl.port = String(address.port);
|
||||
}
|
||||
const response = await fetch(requestUrl.toString(), {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||
body: "CallSid=CA123&SpeechResult=hello",
|
||||
});
|
||||
const response = await postWebhookForm(server, baseUrl, "CallSid=CA123&SpeechResult=hello");
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(processEvent).not.toHaveBeenCalled();
|
||||
@@ -193,18 +197,7 @@ describe("VoiceCallWebhookServer replay handling", () => {
|
||||
|
||||
try {
|
||||
const baseUrl = await server.start();
|
||||
const address = (
|
||||
server as unknown as { server?: { address?: () => unknown } }
|
||||
).server?.address?.();
|
||||
const requestUrl = new URL(baseUrl);
|
||||
if (address && typeof address === "object" && "port" in address && address.port) {
|
||||
requestUrl.port = String(address.port);
|
||||
}
|
||||
const response = await fetch(requestUrl.toString(), {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||
body: "CallSid=CA123&SpeechResult=hello",
|
||||
});
|
||||
const response = await postWebhookForm(server, baseUrl, "CallSid=CA123&SpeechResult=hello");
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(parseWebhookEvent).toHaveBeenCalledTimes(1);
|
||||
@@ -231,18 +224,7 @@ describe("VoiceCallWebhookServer replay handling", () => {
|
||||
|
||||
try {
|
||||
const baseUrl = await server.start();
|
||||
const address = (
|
||||
server as unknown as { server?: { address?: () => unknown } }
|
||||
).server?.address?.();
|
||||
const requestUrl = new URL(baseUrl);
|
||||
if (address && typeof address === "object" && "port" in address && address.port) {
|
||||
requestUrl.port = String(address.port);
|
||||
}
|
||||
const response = await fetch(requestUrl.toString(), {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||
body: "CallSid=CA123&SpeechResult=hello",
|
||||
});
|
||||
const response = await postWebhookForm(server, baseUrl, "CallSid=CA123&SpeechResult=hello");
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
expect(parseWebhookEvent).not.toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user