import assert from "node:assert/strict"; import { createServer, request as httpRequest } from "node:http"; import test from "node:test"; import { daytonaLinkCommands, denLink, MAX_LINK_DAYTONA_COMMAND_LENGTH } from "../src/link.ts"; import type { Server } from "node:http"; import type { DaytonaExec } from "@openwork/hosts"; const LARGE_BODY = Buffer.alloc(192 * 1024, 97); const ADMIN_TOKEN = "a".repeat(64); function listen(server: Server): Promise { return new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", () => { const address = server.address(); if (typeof address === "object" && address !== null) resolve(address.port); else reject(new Error("Upstream test server did not expose a port.")); }); }); } function close(server: Server): Promise { return new Promise((resolve, reject) => { server.close((error) => error ? reject(error) : resolve()); server.closeAllConnections(); }); } function timedFetch(url: string, timeoutMs = 5_000): Promise { return fetch(url, { signal: AbortSignal.timeout(timeoutMs) }); } function absoluteGet(proxyUrl: string, target: string): Promise { const proxy = new URL(proxyUrl); return new Promise((resolve, reject) => { const request = httpRequest({ hostname: proxy.hostname, port: proxy.port, path: target }, (response) => { response.setEncoding("utf8"); let body = ""; response.on("data", (chunk: string) => body += chunk); response.on("end", () => resolve(body)); }); request.on("error", reject); request.end(); }); } test("Daytona link commands upload the runner-side script before launching its temp path", () => { const source = Buffer.alloc(32 * 1024, 97); const commands = daytonaLinkCommands(source, "https://den.example.test", 3985, 3986, ADMIN_TOKEN); assert(commands.cleanup.includes("pid=$( /tmp/openwork-den-link-server.mjs.b64"); const chunkPattern = /^printf %s ([A-Za-z0-9+/=]+) >> \/tmp\/openwork-den-link-server\.mjs\.b64$/; const chunks = commands.upload.slice(1, -1).map((command) => { const match = chunkPattern.exec(command); assert(match); assert(match[1].length <= 8 * 1024); return match[1]; }); assert.equal(chunks.join(""), source.toString("base64")); const finalize = commands.upload.at(-1); assert(finalize?.includes("base64 -d /tmp/openwork-den-link-server.mjs.b64 > /tmp/openwork-den-link-server.mjs")); assert(finalize?.includes("actual_bytes=$(wc -c < /tmp/openwork-den-link-server.mjs)")); assert(finalize?.includes("rm -f /tmp/openwork-den-link-server.mjs.b64")); assert(finalize?.includes(`test \"$actual_bytes\" -eq ${source.byteLength}`)); const commandLengths = [commands.cleanup, ...commands.upload, commands.detach] .map((command) => ["exec", "desktop-sandbox", "--", `bash -lc '${command}'`].join(" ").length); assert(Math.max(...commandLengths) <= MAX_LINK_DAYTONA_COMMAND_LENGTH); assert(commands.detach.includes('"node", "/tmp/openwork-den-link-server.mjs"')); assert(commands.detach.includes("pid_file.write(str(process.pid)")); assert(commands.detach.includes('os.replace(temporary_pid, "/tmp/openwork-den-link-server.pid")')); assert(commands.detach.includes(`env={**os.environ, "LINK_ADMIN_TOKEN": "${ADMIN_TOKEN}"}`)); const launch = commands.detach.split("\n").find((line) => line.startsWith("process = subprocess.Popen")); assert(launch); assert(!launch.slice(0, launch.indexOf("], stdin=")).includes(ADMIN_TOKEN)); assert(!commands.detach.includes("/workspace/evals")); assert.throws( () => daytonaLinkCommands(source, "https://den.example.test", 3985, 3986, "not-hex"), /at least 32 lowercase hex characters/, ); }); test("denLink separates a sandbox loopback client from public admin control and defaults to public previews", async () => { const calls: string[][] = []; const exec: DaytonaExec = async (args) => { calls.push(args); const previewPort = args[0] === "preview-url" ? args.at(-1) : undefined; return { stdout: previewPort === "3985" ? "https://data-preview.example.test\n" : previewPort === "3986" ? "https://admin-preview.example.test\n" : "", stderr: "", code: 0, }; }; const originalFetch = globalThis.fetch; const fetched: Array<{ url: string; authorization: string | null }> = []; globalThis.fetch = async (input, init) => { fetched.push({ url: String(input), authorization: new Headers(init?.headers).get("authorization") }); return new Response(JSON.stringify({ ok: true, phase: "default", offline: false }), { headers: { "content-type": "application/json" }, }); }; try { { await using link = await denLink( { apiUrl: "https://den.example.test/api/den", webUrl: "https://den.example.test" }, { sandboxId: "desktop-sandbox", client: "sandbox-loopback", daytonaExec: exec }, ); assert.deepEqual(link.ref, { apiUrl: "http://127.0.0.1:3985/api/den", webUrl: "http://127.0.0.1:3985", }); assert(calls.some((args) => args[0] === "exec" && args.at(-1)?.includes("http://127.0.0.1:3986/health"))); assert.deepEqual( calls.filter((args) => args[0] === "preview-url").map((args) => args.at(-1)), ["3986"], ); assert.equal(fetched.length, 1); assert.equal(fetched[0]?.url, "https://admin-preview.example.test/health"); assert.match(fetched[0]?.authorization ?? "", /^Bearer [a-f0-9]{64}$/); const healthCommand = calls.find((args) => args[0] === "exec" && args.at(-1)?.includes("curl -sf"))?.at(-1); assert.match(healthCommand ?? "", /curl -sf -H "Authorization: Bearer [a-f0-9]{64}" http:\/\/127\.0\.0\.1:3986\/health/); } calls.length = 0; fetched.length = 0; await using publicLink = await denLink( { apiUrl: "https://den.example.test/api/den", webUrl: "https://den.example.test" }, { sandboxId: "desktop-sandbox", daytonaExec: exec }, ); assert.deepEqual(publicLink.ref, { apiUrl: "https://data-preview.example.test/api/den", webUrl: "https://data-preview.example.test", }); assert.deepEqual( calls.filter((args) => args[0] === "preview-url").map((args) => args.at(-1)), ["3985", "3986"], ); } finally { globalThis.fetch = originalFetch; } }); test("denLink admin rejects missing and wrong bearer tokens without mutating state", async () => { const upstream = createServer((_request, response) => response.end("ok")); const port = await listen(upstream); const originalFetch = globalThis.fetch; let adminHealthUrl = ""; let authorization = ""; globalThis.fetch = async (input, init) => { const url = String(input); const header = new Headers(init?.headers).get("authorization"); if (url.endsWith("/health") && header !== null) { adminHealthUrl = url; authorization = header; } return originalFetch(input, init); }; try { await using link = await denLink({ apiUrl: `http://127.0.0.1:${port}/api/den`, webUrl: `http://127.0.0.1:${port}`, }); await link.admin.phase("protected"); assert.match(authorization, /^Bearer [a-f0-9]{64}$/); const phaseUrl = adminHealthUrl.replace(/\/health$/, "/phase"); for (const headers of [ { "content-type": "application/json" }, { authorization: "Bearer " + "b".repeat(64), "content-type": "application/json" }, ]) { const denied = await originalFetch(phaseUrl, { method: "POST", headers, body: JSON.stringify({ name: "attacker" }), }); assert.equal(denied.status, 401); assert.deepEqual(await denied.json(), { error: "Unauthorized" }); } assert.equal((await link.admin.health()).phase, "protected"); } finally { globalThis.fetch = originalFetch; await close(upstream); } }); test("denLink shapes a local Den connection and records phases", { timeout: 25_000 }, async () => { const upstream = createServer((request, response) => { if (request.url === "/large") { response.writeHead(200, { "content-length": LARGE_BODY.length, "content-type": "application/octet-stream" }); response.end(LARGE_BODY); return; } if (request.url === "/stream") { response.writeHead(200, { "content-type": "application/octet-stream" }); response.write(Buffer.alloc(16 * 1024, 98)); let writes = 0; const timer = setInterval(() => { if (writes === 9) { clearInterval(timer); response.end(); return; } writes += 1; response.write(Buffer.alloc(16 * 1024, 98)); }, 200); response.once("close", () => clearInterval(timer)); return; } response.writeHead(200, { "content-type": "application/json", "x-upstream": "yes" }); response.end(JSON.stringify({ ok: true, path: request.url })); }); const port = await listen(upstream); try { await using link = await denLink({ apiUrl: `http://127.0.0.1:${port}/api/den`, webUrl: `http://127.0.0.1:${port}`, }); const passed = await timedFetch(`${link.ref.webUrl}/passthrough`); assert.equal(passed.status, 200); assert.equal(passed.headers.get("x-upstream"), "yes"); assert.deepEqual(await passed.json(), { ok: true, path: "/passthrough" }); let log = await link.admin.requests(); assert.deepEqual( { faulted: log.requests[0]?.faulted, phase: log.requests[0]?.phase }, { faulted: false, phase: "default" }, ); await link.admin.rules([{ kind: "status", pathPrefix: "/status", statusCode: 503, times: 2, body: { error: "unavailable" } }]); assert.equal((await timedFetch(`${link.ref.webUrl}/status`)).status, 503); assert.equal((await timedFetch(`${link.ref.webUrl}/status`)).status, 503); assert.equal((await timedFetch(`${link.ref.webUrl}/status`)).status, 200); log = await link.admin.requests(); assert.deepEqual(log.requests.slice(-3).map(({ faulted, fault }) => ({ faulted, fault })), [ { faulted: true, fault: "status" }, { faulted: true, fault: "status" }, { faulted: false, fault: undefined }, ]); await link.admin.rules([{ kind: "latency", pathPrefix: "/latency", delayMs: 300, jitterMs: 50 }]); const latencyStarted = Date.now(); assert.equal((await timedFetch(`${link.ref.webUrl}/latency`)).status, 200); const latencyElapsed = Date.now() - latencyStarted; assert(latencyElapsed >= 250, `Expected at least 250ms latency, got ${latencyElapsed}ms.`); assert(latencyElapsed <= 1_200, `Expected at most 1200ms latency, got ${latencyElapsed}ms.`); await link.admin.rules([{ kind: "reset", pathPrefix: "/reset", everyNth: 2 }]); assert.equal((await timedFetch(`${link.ref.webUrl}/reset`)).status, 200); await assert.rejects(timedFetch(`${link.ref.webUrl}/reset`)); assert.equal((await timedFetch(`${link.ref.webUrl}/reset`)).status, 200); await assert.rejects(timedFetch(`${link.ref.webUrl}/reset`)); await link.admin.phase("offline"); await link.admin.offline(600); await assert.rejects(timedFetch(`${link.ref.webUrl}/offline`, 2_000)); log = await link.admin.requests(); assert((log.refusedConnections.offline ?? 0) >= 1); await new Promise((resolve) => setTimeout(resolve, 800)); assert.equal((await timedFetch(`${link.ref.webUrl}/restored`)).status, 200); assert.equal((await link.admin.health()).offline, false); await link.admin.clear(); const streaming = await timedFetch(`${link.ref.webUrl}/stream`); assert(streaming.body); const reader = streaming.body.getReader(); const firstChunk = await reader.read(); assert.equal(firstChunk.done, false); await link.admin.offline(600); await assert.rejects(reader.read()); await new Promise((resolve) => setTimeout(resolve, 700)); await link.admin.bandwidth(64 * 1024); const cappedStarted = Date.now(); const capped = await timedFetch(`${link.ref.webUrl}/large`, 8_000); const cappedBody = Buffer.from(await capped.arrayBuffer()); const cappedElapsed = Date.now() - cappedStarted; assert(cappedElapsed >= 2_500, `Expected capped transfer to take at least 2500ms, got ${cappedElapsed}ms.`); assert.deepEqual(cappedBody, LARGE_BODY); assert.equal((await link.admin.requests()).requests.at(-1)?.fault, "bandwidth"); await link.admin.bandwidth(null); const fastStarted = Date.now(); const fast = await timedFetch(`${link.ref.webUrl}/large`); assert.deepEqual(Buffer.from(await fast.arrayBuffer()), LARGE_BODY); assert(Date.now() - fastStarted < 1_000); await link.admin.phase("b"); assert.equal((await timedFetch(`${link.ref.webUrl}/phase-b`)).status, 200); log = await link.admin.requests(); assert.equal(log.requests.at(-1)?.phase, "b"); await link.admin.phase("vpn", "vpn-flaky-emulated"); const vpnStarted = Date.now(); assert.equal((await timedFetch(`${link.ref.webUrl}/vpn-success-1`)).status, 200); const vpnDelay = Date.now() - vpnStarted; assert(vpnDelay >= 300, `Expected VPN emulation latency of at least 300ms, got ${vpnDelay}ms.`); assert(vpnDelay < 1_500, `Expected bounded VPN emulation latency, got ${vpnDelay}ms.`); assert.equal((await timedFetch(`${link.ref.webUrl}/vpn-success-2`)).status, 200); await assert.rejects(timedFetch(`${link.ref.webUrl}/vpn-reset`)); const stats = await link.admin.stats(); assert.equal(stats.phase, "vpn"); assert.equal(stats.profile, "vpn-flaky-emulated"); assert(stats.faults >= 1); log = await link.admin.requests(); assert.deepEqual(log.requests.slice(-3).map(({ fault, profile }) => ({ fault, profile })), [ { fault: "latency", profile: "vpn-flaky-emulated" }, { fault: "latency", profile: "vpn-flaky-emulated" }, { fault: "reset", profile: "vpn-flaky-emulated" }, ]); await link.admin.phase("baseline", "baseline"); assert.equal((await timedFetch(`${link.ref.webUrl}/baseline-restored`)).status, 200); const baselineEntry = (await link.admin.requests()).requests.at(-1); assert.deepEqual( baselineEntry && { path: baselineEntry.path, faulted: baselineEntry.faulted, phase: baselineEntry.phase, profile: baselineEntry.profile }, { path: "/baseline-restored", faulted: false, phase: "baseline", profile: "baseline" }, ); await link.admin.rules([{ kind: "status", statusCode: 500, times: 10 }]); await link.admin.clear(); assert.equal((await timedFetch(`${link.ref.webUrl}/cleared`)).status, 200); assert.equal((await link.admin.health()).offline, false); } finally { await close(upstream); } }); test("denLink pins absolute-form request targets to its upstream", async () => { let attackerRequests = 0; let upstreamRequestUrl: string | undefined; const upstream = createServer((request, response) => { upstreamRequestUrl = request.url; response.end("upstream"); }); const attacker = createServer((_request, response) => { attackerRequests += 1; response.end("attacker"); }); const [upstreamPort, attackerPort] = await Promise.all([listen(upstream), listen(attacker)]); try { await using link = await denLink({ apiUrl: `http://127.0.0.1:${upstreamPort}/api/den`, webUrl: `http://127.0.0.1:${upstreamPort}`, }); assert.equal( await absoluteGet(link.ref.webUrl, `http://127.0.0.1:${attackerPort}/steered?x=1`), "upstream", ); assert.equal(upstreamRequestUrl, "/steered?x=1"); assert.equal(attackerRequests, 0); } finally { await Promise.all([close(upstream), close(attacker)]); } });