mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
14fe739ee9
* fix(feishu): enforce exact signed webhook request targets * fix(feishu): preserve explicitly configured signed webhook query targets * fix(feishu): preserve shipped relative webhook paths * fix(feishu): normalize and migrate legacy webhook callback paths * fix(feishu): preserve transformed webhook schema defaults * fix(feishu): require canonical webhook paths before runtime startup * docs(feishu): document canonical webhook routes and doctor recovery
25 lines
958 B
TypeScript
25 lines
958 B
TypeScript
// Feishu webhook paths normalize trusted operator configuration into HTTP request targets.
|
|
export const DEFAULT_FEISHU_WEBHOOK_PATH = "/feishu/events";
|
|
|
|
/** Normalize trusted configuration only; incoming request targets must remain unmodified. */
|
|
export function normalizeFeishuWebhookPath(value?: string): string | null {
|
|
const configured = value?.trim();
|
|
if (!configured) {
|
|
return DEFAULT_FEISHU_WEBHOOK_PATH;
|
|
}
|
|
|
|
try {
|
|
const parsed = new URL(configured, "http://localhost");
|
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
return null;
|
|
}
|
|
// URL.search drops a trailing empty query; actual HTTP requests keep it
|
|
// unless a fragment follows, so preserve the exact configured wire target.
|
|
const emptyQuery =
|
|
!parsed.search && parsed.href.endsWith("?") && !configured.includes("#") ? "?" : "";
|
|
return `${parsed.pathname}${parsed.search}${emptyQuery}`;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|