// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // Real signed assertions through the template's request adapter, across separate requests. import { generateKeyPairSync, randomUUID, sign } from "node:crypto" import { createServer } from "node:http" import type { AddressInfo } from "node:net" import { buildRegistry, Container } from "@conusai-kit/core" import { afterEach, describe, expect, it, vi } from "vitest" const mocks = vi.hoisted(() => ({ runtime: vi.fn() })) vi.mock("../apps/web/src/server/app", () => ({ webRuntime: mocks.runtime })) vi.mock("@conusai-kit/tenancy", async (original) => ({ ...(await original>()), createTenancyHooks: () => ({}), })) const { supportOboCaller } = await import("../apps/web/src/server/support-obo") const issuer = "https://platform.example.test" const audience = "https://app.example.test" const keys = generateKeyPairSync("ed25519") const jwk = { ...keys.publicKey.export({ format: "jwk" }), kid: "synthetic", alg: "EdDSA", use: "sig" } const registry = buildRegistry([]) const httpFetch = globalThis.fetch function configure() { mocks.runtime.mockReturnValue({ data: {}, registry, env: { deployment: { CONUSAI_API_URL: `${issuer}/api`, CONUSAI_PUBLIC_URL: audience, CONUSAI_ORG_ID: "3", CONUSAI_PROJECT_ID: "4", CONUSAI_ENVIRONMENT_ID: "5", }, }, }) vi.stubGlobal( "fetch", vi.fn(async () => Response.json({ keys: [jwk] })), ) } function assertion(extra: Record = {}) { const now = Math.floor(Date.now() / 1000) const encode = (value: object) => Buffer.from(JSON.stringify(value)).toString("base64url") const body = `${encode({ alg: "EdDSA", typ: "conusai-obo+jwt", kid: "synthetic" })}.${encode({ iss: issuer, aud: audience, sub: "synthetic-user", sub_ns: "app", app_tenant: "tenant-a", conv: "synthetic-conversation", channel: "sc_synthetic", org: "3", project: "4", env: "5", jti: randomUUID(), iat: now, exp: now + 60, ...extra, })}` return `${body}.${sign(null, Buffer.from(body), keys.privateKey).toString("base64url")}` } function request(token?: string, pathname = "/api/mcp") { return new Request(`${audience}${pathname}`, { headers: token ? { "Conusai-On-Behalf-Of": token } : {}, }) } afterEach(() => { vi.unstubAllGlobals() vi.clearAllMocks() }) describe("the Support OBO request adapter", () => { it("accepts a signed assertion once and refuses its replay on a separate request", async () => { configure() const token = assertion() expect(await supportOboCaller(request(token), new Container())).not.toBeNull() await expect(supportOboCaller(request(token), new Container())).rejects.toMatchObject({ status: 401 }) }) it("refuses another environment and permits a new assertion", async () => { configure() await expect(supportOboCaller(request(assertion({ env: "6" })), new Container())).rejects.toMatchObject({ status: 401, }) expect(await supportOboCaller(request(assertion()), new Container())).not.toBeNull() }) it("keeps the replay boundary across real HTTP requests", async () => { configure() const server = createServer(async (incoming, response) => { try { const token = incoming.headers["conusai-on-behalf-of"] const caller = await supportOboCaller(request(typeof token === "string" ? token : undefined), new Container()) response.writeHead(caller ? 200 : 204).end() } catch (error) { response.writeHead((error as { status?: number }).status ?? 500).end() } }) await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)) const origin = `http://127.0.0.1:${(server.address() as AddressInfo).port}` const token = assertion() try { const headers = { "Conusai-On-Behalf-Of": token } expect((await httpFetch(`${origin}/api/mcp`, { headers })).status).toBe(200) expect((await httpFetch(`${origin}/api/mcp`, { headers })).status).toBe(401) expect((await httpFetch(`${origin}/api/mcp`)).status).toBe(204) } finally { await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))) } }) it("leaves ordinary requests and non-MCP routes on session authentication", async () => { expect(await supportOboCaller(request(), new Container())).toBeNull() expect(await supportOboCaller(request("ignored", "/api/ready"), new Container())).toBeNull() expect(mocks.runtime).not.toHaveBeenCalled() }) })