import { describe, expect, test } from "bun:test"; import { createEncryptedRequest, createKeyring, createMemoryReplayStore, decryptEncryptedResponse, decryptHttpBody, decryptRequest, encryptHttpBody, encryptResponse, encryptedExchange, } from "../src/index.ts"; const keyring = createKeyring([ { id: "primary", secret: "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=", active: true, }, ]); describe("encrypted HTTP envelopes", () => { test("binds ciphertext to method, URL, request id, age, and replay state", async () => { const now = 10_000; const replay = createMemoryReplayStore(() => now); const envelope = await encryptHttpBody( { message: "secret" }, { keyring, method: "POST", url: "https://api.example.test/private?view=full", requestId: "request-1", timestamp: now, }, ); const result = await decryptHttpBody<{ message: string }>(envelope, { keyring, method: "POST", url: "https://api.example.test/private?view=full", replayStore: replay, now: () => now, expectedRequestId: "request-1", }); expect(result.body).toEqual({ message: "secret" }); await expect( decryptHttpBody(envelope, { keyring, method: "POST", url: "https://api.example.test/private?view=full", replayStore: replay, now: () => now, }), ).rejects.toThrow("REPLAY"); await expect( decryptHttpBody(envelope, { keyring, method: "GET", url: "https://api.example.test/private?view=full", now: () => now, }), ).rejects.toThrow("CONTEXT"); }); test("checks the clear request-id header against the encrypted envelope", async () => { const request = await createEncryptedRequest( "https://api.example.test/private", { value: 1 }, { keyring, requestId: "request-2", method: "POST" }, ); request.headers.set("x-wrn-request-id", "tampered-id"); await expect(decryptRequest(request, { keyring })).rejects.toThrow("REQUEST-ID"); }); test("encrypts a response using and verifying the original request context", async () => { const request = await createEncryptedRequest( "https://api.example.test/private", { value: 1 }, { keyring, requestId: "request-3", method: "POST" }, ); const response = await encryptResponse({ ok: true }, request, { keyring }); const result = await decryptEncryptedResponse<{ ok: boolean }>(response, request, { keyring }); expect(result.body.ok).toBe(true); expect(response.headers.get("x-wrn-request-id")).toBe("request-3"); expect(response.headers.get("cache-control")).toBe("no-store"); const other = await createEncryptedRequest( "https://api.example.test/private", { value: 2 }, { keyring, requestId: "request-other", method: "POST" }, ); await expect(decryptEncryptedResponse(response, other, { keyring })).rejects.toThrow( "REQUEST-ID", ); }); test("provides transparent encrypted request and response middleware", async () => { const request = await createEncryptedRequest( "https://api.example.test/private", { value: 7 }, { keyring, requestId: "request-4", method: "POST" }, ); const context = { req: request, locals: {}, } as Parameters>[0]; const response = await encryptedExchange({ keyring })(context, () => Response.json({ received: context.locals.encryptedBody }), ); const result = await decryptEncryptedResponse<{ received: { value: number }; }>(response, request, { keyring }); expect(result.body.received.value).toBe(7); }); test("does not convert application exceptions into invalid-body responses", async () => { const request = await createEncryptedRequest( "https://api.example.test/private", { value: 7 }, { keyring, requestId: "request-5", method: "POST" }, ); const context = { req: request, locals: {}, } as Parameters>[0]; await expect( encryptedExchange({ keyring })(context, () => { throw new Error("application failed"); }), ).rejects.toThrow("application failed"); }); });