import { expect, test } from "bun:test"; import { defineRoom, type Middleware } from "@wrnexus/core"; import { createProductionHandlers } from "../src/prod.ts"; const room = defineRoom({ security: { requireUser: true }, authorize: (info) => info.user === "signed-in-user", }); const auth: Middleware = async (ctx, next) => { if (ctx.req.headers.get("cookie") === "test-session=valid") ctx.user = { id: "signed-in-user" }; return next(); }; function handlers(middleware: Middleware[] = [auth]) { return createProductionHandlers( { pages: [], api: [], realtime: [{ raw: "/realtime/updates", mod: { default: room } }], middleware, components: [], layouts: [], }, {}, ); } function request( query = "", cookie = "test-session=valid", origin = "https://account.example.test", ) { return new Request("https://account.example.test/realtime/updates" + query, { headers: { host: "account.example.test", origin, cookie, upgrade: "websocket" }, }); } test("room upgrade receives middleware identity after post-processing completes", async () => { let finished = false; const post: Middleware = async (_, next) => { const res = await next(); finished = true; return new Response(res.body, { status: res.status, headers: res.headers }); }; let upgraded = false; const response = await handlers([auth, post]).fetch(request(), { upgrade: (_, options) => { expect(finished).toBe(true); expect((options.data as any).meta.user).toBe("signed-in-user"); expect(options.headers?.has("x-wrnexus-upgrade-permit")).toBe(false); upgraded = true; return true; }, }); expect(response).toBeUndefined(); expect(upgraded).toBe(true); }); test("query user cannot impersonate an authenticated room member", async () => { const response = await handlers().fetch(request("?user=signed-in-user", ""), { upgrade: () => { throw Error("must not upgrade"); }, }); expect(response?.status).toBe(403); }); test("middleware rejection and cross-site origins never upgrade", async () => { const server = { upgrade: () => { throw Error("must not upgrade"); }, }; expect( (await handlers([() => new Response("denied", { status: 401 })]).fetch(request(), server)) ?.status, ).toBe(401); expect( (await handlers().fetch(request("", "test-session=valid", "https://evil.example"), server)) ?.status, ).toBe(403); }); test("post-processing rejection overrides room authorization", async () => { const deny: Middleware = async (_, next) => { await next(); return new Response("denied", { status: 403 }); }; expect( ( await handlers([auth, deny]).fetch(request(), { upgrade: () => { throw Error("must not upgrade"); }, }) )?.status, ).toBe(403); }); test("Bun accepts a real socket with the middleware-authenticated identity", async () => { const app = handlers(); const server = Bun.serve({ port: 0, fetch: app.fetch, websocket: app.websocket }); try { await new Promise((resolve, reject) => { const Socket = WebSocket as unknown as { new (url: string, options?: import("bun").WebSocketOptions): WebSocket; }; const socket = new Socket(`ws://localhost:${server.port}/realtime/updates`, { headers: { cookie: "test-session=valid", origin: `http://localhost:${server.port}` }, }); const timer = setTimeout(() => { socket.close(); reject(Error("upgrade timed out")); }, 3000); socket.onopen = () => { clearTimeout(timer); socket.close(); resolve(); }; socket.onerror = () => { clearTimeout(timer); reject(Error("upgrade failed")); }; }); } finally { server.stop(true); await app.shutdown(); } });