import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import type { SsrFPolicy } from "../infra/net/ssrf.js"; export function buildRemoteBaseUrlPolicy(baseUrl: string): SsrFPolicy | undefined { const trimmed = baseUrl.trim(); if (!trimmed) { return undefined; } try { const parsed = new URL(trimmed); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { return undefined; } // Keep policy tied to the configured host so private operator endpoints // continue to work, while cross-host redirects stay blocked. return { allowedHostnames: [parsed.hostname] }; } catch { return undefined; } } export async function withRemoteHttpResponse(params: { url: string; init?: RequestInit; ssrfPolicy?: SsrFPolicy; auditContext?: string; onResponse: (response: Response) => Promise; }): Promise { const { response, release } = await fetchWithSsrFGuard({ url: params.url, init: params.init, policy: params.ssrfPolicy, auditContext: params.auditContext ?? "memory-remote", }); try { return await params.onResponse(response); } finally { await release(); } }