- Added AbortSignal propagation and timeout-race handling for broker health, usage, refresh, and snapshot calls. - Added single-flight usage-report caching with 15s TTL, per-caller abort races, and null-on-fail fallback. - Expanded provider schemas and parse/build logic for cache metadata, headers, stop controls, and image/file content. - Hardened auth flows by rejecting refresh sentinels and using timing-safe bearer-token comparisons.
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
/**
|
|
* Shared `host:port` parser used by the auth-broker and auth-gateway boot
|
|
* paths. Centralized so the two servers can't drift on what they accept (the
|
|
* gateway used to silently allow empty hostnames; this fixes it).
|
|
*/
|
|
|
|
export interface ParsedBind {
|
|
hostname: string;
|
|
port: number;
|
|
}
|
|
|
|
function parsePort(raw: string, bind: string): number {
|
|
if (!/^\d+$/.test(raw)) {
|
|
throw new Error(`Invalid bind '${bind}'; port must be an integer.`);
|
|
}
|
|
const port = Number.parseInt(raw, 10);
|
|
if (!Number.isFinite(port) || port < 0 || port > 65535) {
|
|
throw new Error(`Invalid bind '${bind}'; port out of range.`);
|
|
}
|
|
return port;
|
|
}
|
|
|
|
/**
|
|
* Parse a `host:port` (or bare `port`, which assumes loopback) string.
|
|
*
|
|
* Accepts:
|
|
* - `"4000"` → `127.0.0.1:4000`
|
|
* - `"0.0.0.0:4000"` → as written
|
|
* - `"[::1]:4000"` → as written (brackets retained, Bun handles them)
|
|
*
|
|
* Rejects:
|
|
* - empty input
|
|
* - empty hostname (`":4000"`)
|
|
* - non-integer / out-of-range port
|
|
*/
|
|
export function parseBind(raw: string): ParsedBind {
|
|
const trimmed = raw.trim();
|
|
if (trimmed.length === 0) {
|
|
throw new Error("Invalid bind; expected 'host:port' or 'port'.");
|
|
}
|
|
if (/^\d+$/.test(trimmed)) {
|
|
return { hostname: "127.0.0.1", port: parsePort(trimmed, raw) };
|
|
}
|
|
const lastColon = trimmed.lastIndexOf(":");
|
|
if (lastColon < 0) {
|
|
throw new Error(`Invalid bind '${raw}'; expected 'host:port' or 'port'.`);
|
|
}
|
|
const hostPart = trimmed.slice(0, lastColon);
|
|
const portPart = trimmed.slice(lastColon + 1);
|
|
if (hostPart.length === 0) {
|
|
throw new Error(`Invalid bind '${raw}'; host must not be empty.`);
|
|
}
|
|
return { hostname: hostPart, port: parsePort(portPart, raw) };
|
|
}
|