Files
pikasTech-HWLAB/internal/cloud/tasktree-proxy.ts
T
2026-07-16 20:59:51 +02:00

23 lines
1.8 KiB
TypeScript

import { readBody, sendJson } from "./server-http-utils.ts";
export async function handleTaskTreeProxyHttp(request, response, url, options = {}) {
const env = options.env ?? process.env;
const baseUrl = String(env.HWLAB_TASKTREE_URL ?? "").trim();
if (!baseUrl) return sendJson(response, 503, { ok: false, error: { code: "tasktree_service_unconfigured", message: "HWLAB_TASKTREE_URL is required" }, valuesRedacted: true });
const auth = await options.accessController.authenticate(request, { required: true });
if (!auth.ok) return sendJson(response, auth.status, auth);
try {
const upstreamUrl = new URL(`${url.pathname}${url.search}`, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
const headers = new Headers({ accept: "application/json", "x-hwlab-bridge-service": "hwlab-cloud-api" });
const contentType = request.headers["content-type"];
if (contentType) headers.set("content-type", Array.isArray(contentType) ? contentType[0] : contentType);
if (auth.actor?.id) headers.set("x-hwlab-actor-id", auth.actor.id);
const body = request.method === "GET" || request.method === "HEAD" ? undefined : await readBody(request, options.bodyLimitBytes);
const upstream = await fetch(upstreamUrl, { method: request.method, headers, body, signal: AbortSignal.timeout(Number(env.HWLAB_TASKTREE_PROXY_TIMEOUT_MS || 30000)) });
response.writeHead(upstream.status, { "content-type": upstream.headers.get("content-type") || "application/json; charset=utf-8", "cache-control": "no-store", "x-hwlab-proxy-service": "hwlab-tasktree-api" });
response.end(await upstream.text() || "\n");
} catch (error) {
sendJson(response, 502, { ok: false, error: { code: "tasktree_proxy_failed", message: error?.message ?? String(error) }, valuesRedacted: true });
}
}