Files
openclaw/extensions/elevenlabs/shared.ts
dwc1997 8b03d5ce24 fix(elevenlabs): reject malformed base URL overrides (#105163)
* fix(elevenlabs): fall back to default base URL when config value is malformed

* fix(elevenlabs): reject malformed and non-http(s) base URL overrides

* fix(elevenlabs): redact configured URL from base URL validation errors

* fix(elevenlabs): preserve realtime WebSocket overrides

* test(elevenlabs): avoid stale realtime test overlap

* style(elevenlabs): format realtime URL assertion

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 07:08:45 +01:00

50 lines
1.8 KiB
TypeScript

// Elevenlabs plugin module implements shared behavior.
export const DEFAULT_ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
export function isValidElevenLabsVoiceId(voiceId: string): boolean {
return /^[a-zA-Z0-9]{10,40}$/.test(voiceId);
}
function normalizeElevenLabsBaseUrlWithProtocols(
baseUrl: string | undefined,
allowedProtocols: readonly string[],
): string {
const trimmed = baseUrl?.trim();
// Only an absent/blank value falls back to the default endpoint. An explicit
// custom endpoint is operator intent, so never silently retarget it.
if (!trimmed) {
return DEFAULT_ELEVENLABS_BASE_URL;
}
const normalized = trimmed.replace(/\/+$/, "");
let parsed: URL;
try {
parsed = new URL(normalized);
} catch {
// Do not interpolate the raw value: an explicit baseUrl may embed userinfo
// (https://user:token@host) or credential-bearing query params that would
// otherwise leak into logs/diagnostics via this error.
throw new Error("Invalid ElevenLabs baseUrl: value is not a valid URL");
}
if (!allowedProtocols.includes(parsed.protocol)) {
// Only the scheme is safe to surface; the rest of the URL may carry secrets.
throw new Error(
`Invalid ElevenLabs baseUrl: unsupported scheme "${parsed.protocol}" (expected ${allowedProtocols.join(" or ")})`,
);
}
return normalized;
}
export function normalizeElevenLabsBaseUrl(baseUrl?: string): string {
return normalizeElevenLabsBaseUrlWithProtocols(baseUrl, ["http:", "https:"]);
}
export function normalizeElevenLabsRealtimeBaseUrl(baseUrl?: string): string {
const url = new URL(
normalizeElevenLabsBaseUrlWithProtocols(baseUrl, ["http:", "https:", "ws:", "wss:"]),
);
if (url.protocol === "http:" || url.protocol === "https:") {
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
}
return url.toString().replace(/\/+$/, "");
}