feat(server,web): serve Workspace HTML previews from a separate origin (#46)

Serve "open in new tab" HTML previews from a separate origin (the loopback counterpart, or PENGUIN_PREVIEW_ORIGIN) with a signed, host-bound token, so localStorage/cookies/third-party embeds work while Agent-generated pages stay off the app origin. The app is canonicalized onto localhost and the preview host (127.0.0.1) serves only /preview/* — its /api answers 401 and app routes 302 to the canonical host — so the preview origin can neither set nor honor a session cookie.
This commit is contained in:
Yaowei Zheng
2026-07-23 23:11:04 +08:00
committed by GitHub
parent cc1be054de
commit b18ae8f5f1
22 changed files with 842 additions and 14 deletions
+4 -1
View File
@@ -81,7 +81,10 @@ async function waitForReady(url: string, timeoutMs = 15_000, intervalMs = 300):
// Each probe is capped at 1s: if the port is held by a non-HTTP program, the
// connection can succeed while the response hangs forever; without a timeout this
// would block the whole polling loop (the deadline check below would never run).
const res = await fetch(url, { signal: AbortSignal.timeout(1000) });
// `redirect: "manual"`: on a loopback bind the root path 302s to the canonical host
// (127.0.0.1 is reserved for previews); the probe only needs to know the port answers,
// so treat that 302 as ready rather than chasing it to a name that may resolve to ::1.
const res = await fetch(url, { redirect: "manual", signal: AbortSignal.timeout(1000) });
void res.body?.cancel();
return true;
} catch {