import { runInNewContext } from "node:vm"; import { describe, expect, it, vi } from "vitest"; import { ControlPlaneError, createControlPlaneClient, normalizeAccountEmail, normalizeControlPlaneURL, } from "./control-plane-client.mjs"; const ACCOUNT = `signed.${"a".repeat(40)}`; const INSTALL = `omb_install_${"a".repeat(22)}.${"b".repeat(43)}`; const INSTALL_ID = "11111111-1111-4111-8111-111111111111"; const jsonResponse = (body, init = {}) => new Response(JSON.stringify(body), { status: init.status ?? 200, headers: { "content-type": "application/json", ...init.headers }, }); describe("control-plane desktop client", () => { it("accepts exact HTTPS and loopback development origins only", () => { expect(normalizeControlPlaneURL("https://accounts.openmausbot.com/")).toBe( "https://accounts.openmausbot.com", ); expect(normalizeControlPlaneURL("http://127.0.0.1:8787/")).toBe("http://127.0.0.1:8787"); expect(normalizeControlPlaneURL("http://accounts.openmausbot.com")).toBe(""); expect(normalizeControlPlaneURL("https://accounts.openmausbot.com/api")).toBe(""); expect(normalizeControlPlaneURL("https://user:secret@accounts.openmausbot.com")).toBe(""); }); it("normalizes an email without accepting malformed input", () => { expect(normalizeAccountEmail(" Ada@Example.COM ")).toBe("ada@example.com"); expect(normalizeAccountEmail("not-an-email")).toBe(""); expect(normalizeAccountEmail(new String("ada@example.com"))).toBe(""); expect(normalizeControlPlaneURL({ toString: () => "https://accounts.openmausbot.com" })).toBe(""); }); it("accepts plain cross-realm response records", async () => { const payload = runInNewContext( "({ user: { id: 'user-1', email: 'ada@example.com' } })", ); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => ({ status: 200, ok: true, headers: new Headers({ "set-auth-token": ACCOUNT }), json: async () => payload, })), }); await expect(client.verifyOTP("ada@example.com", "12345678")).resolves.toEqual({ accountToken: ACCOUNT, user: { id: "user-1", email: "ada@example.com" }, }); }); it("rejects non-plain response records instead of coercing them", async () => { class Payload { constructor() { this.user = { id: "user-1", email: "ada@example.com" }; } } const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => ({ status: 200, ok: true, headers: new Headers(), json: async () => new Payload(), })), }); await expect(client.me(ACCOUNT)).rejects.toMatchObject({ code: "invalid_response" }); }); it("requires the exact healthy control-plane identity before onboarding", async () => { const timeoutSignal = vi.fn(() => new AbortController().signal); const fetchImpl = vi .fn() .mockResolvedValueOnce(jsonResponse({ ok: true, service: "openmausbot-control-plane" })) .mockResolvedValueOnce(jsonResponse({ ok: true, service: "some-other-service" })); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl, timeoutSignal, }); await expect(client.health()).resolves.toBe(true); await expect(client.health()).rejects.toMatchObject({ code: "control_plane_unavailable", }); expect(fetchImpl.mock.calls[0][0]).toBe("https://accounts.openmausbot.com/healthz"); expect(fetchImpl.mock.calls[0][1].redirect).toBe("error"); expect(fetchImpl.mock.calls[0][1].headers.get("origin")).toBeNull(); expect(timeoutSignal).toHaveBeenNthCalledWith(1, 3_000); }); it("uses the signed Better Auth bearer header, never its raw JSON token", async () => { const fetchImpl = vi.fn(async (_url, init) => { expect(JSON.parse(init.body)).toEqual({ email: "ada@example.com", otp: "12345678", name: "ada", }); return jsonResponse( { token: "raw-database-token-must-not-be-used", user: { id: "user-1", email: "ada@example.com" } }, { headers: { "set-auth-token": ACCOUNT } }, ); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl, }); await expect(client.verifyOTP("Ada@Example.com", "1234-5678")).resolves.toEqual({ accountToken: ACCOUNT, user: { id: "user-1", email: "ada@example.com" }, }); expect(JSON.stringify(fetchImpl.mock.calls)).not.toContain("raw-database-token-must-not-be-used"); }); it("identifies native Better Auth mutations with the trusted control-plane origin", async () => { const fetchImpl = vi.fn(async (_url, init) => { // Undici adds Fetch Metadata after our wrapper; Better Auth 1.7 forbids a browser-shaped request without a trusted Origin. const wireHeaders = new Headers(init.headers); wireHeaders.set("sec-fetch-mode", "cors"); if (wireHeaders.has("sec-fetch-mode") && wireHeaders.get("origin") !== "https://accounts.openmausbot.com") { return jsonResponse({ error: "forbidden" }, { status: 403 }); } return jsonResponse({ success: true }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl, }); await expect(client.requestOTP("ada@example.com")).resolves.toEqual({ email: "ada@example.com", }); expect(fetchImpl.mock.calls[0][1].headers.get("origin")).toBe( "https://accounts.openmausbot.com", ); }); it("keeps a valid installation credential without rotating it", async () => { const fetchImpl = vi.fn(async (url) => { expect(url).toBe("https://accounts.openmausbot.com/v1/installations/self"); return jsonResponse({ installation: { id: INSTALL_ID, clientInstanceId: "client-1", name: "Mac", platform: "darwin", appVersion: "1.0.0", }, credentialExpiresAt: Date.now() + 10_000, }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); const result = await client.ensureInstallation({ accountToken: ACCOUNT, currentCredential: INSTALL, clientInstanceId: "client-1", name: "Mac", platform: "darwin", appVersion: "1.0.0", }); expect(result.credential).toBe(INSTALL); expect(fetchImpl).toHaveBeenCalledTimes(1); }); it("recovers a lost installation credential by rotating the matching identity", async () => { const rotated = `omb_install_${"c".repeat(22)}.${"d".repeat(43)}`; const fetchImpl = vi.fn(async (url, init) => { if (url.endsWith("/v1/installations")) { return jsonResponse({ installations: [{ id: INSTALL_ID, clientInstanceId: "client-1", name: "Mac", platform: "darwin" }], }); } expect(url).toContain(`/v1/installations/${INSTALL_ID}/credentials/rotate`); expect(init.method).toBe("POST"); return jsonResponse({ credential: rotated, credentialExpiresAt: Date.now() + 10_000 }, { status: 201 }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); await expect(client.ensureInstallation({ accountToken: ACCOUNT, clientInstanceId: "client-1", name: "Mac", platform: "darwin", appVersion: "1.0.0", })).resolves.toMatchObject({ credential: rotated, installation: { id: INSTALL_ID } }); }); it("lists validated active installations for response-loss cleanup", async () => { const fetchImpl = vi.fn(async (url, init) => { expect(url).toBe("https://accounts.openmausbot.com/v1/installations"); expect(init.headers.get("authorization")).toBe(`Bearer ${ACCOUNT}`); return jsonResponse({ installations: [{ id: INSTALL_ID, clientInstanceId: "client-1", name: "Mac", platform: "darwin", appVersion: "1.0.0", }], }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl, }); await expect(client.listInstallations(ACCOUNT)).resolves.toEqual([{ id: INSTALL_ID, clientInstanceId: "client-1", name: "Mac", platform: "darwin", appVersion: "1.0.0", }]); }); it("rejects malformed installation lists instead of skipping cleanup targets", async () => { const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => jsonResponse({ installations: [{ id: "not-an-installation", clientInstanceId: "client-1" }], })), }); await expect(client.listInstallations(ACCOUNT)).rejects.toMatchObject({ code: "invalid_response", }); }); it("validates endpoint material without leaking the connector token into the URL", async () => { const connectorToken = `eyJ${"x".repeat(80)}`; const fetchImpl = vi.fn(async (url, init) => { expect(url).toBe("https://accounts.openmausbot.com/v1/installations/self/endpoint"); expect(init.headers.get("authorization")).toBe(`Bearer ${INSTALL}`); expect(url).not.toContain(connectorToken); return jsonResponse({ endpoint: { url: "https://c-opaque.openmausbot.com" }, connectorToken }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); await expect(client.ensureEndpoint(INSTALL)).resolves.toEqual({ endpoint: { url: "https://c-opaque.openmausbot.com" }, connectorToken, }); }); it("reports the app's release with an endpoint request only when it is a printable version", async () => { const connectorToken = `eyJ${"x".repeat(80)}`; const fetchImpl = vi.fn(async () => jsonResponse({ endpoint: { url: "https://c-opaque.mausbot.si" }, connectorToken }), ); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); const sent = () => { const [, init] = fetchImpl.mock.lastCall; return { body: init.body, contentType: init.headers.get("content-type") }; }; await expect(client.ensureEndpoint(INSTALL, { appVersion: " 0.1.104 " })).resolves.toEqual({ endpoint: { url: "https://c-opaque.mausbot.si" }, connectorToken, }); expect(sent()).toEqual({ body: JSON.stringify({ appVersion: "0.1.104" }), contentType: "application/json" }); for (const options of [undefined, {}, { appVersion: "" }, { appVersion: " " }, { appVersion: "0.1\n.104" }, { appVersion: "9".repeat(65) }, { appVersion: 104 }, { appVersion: new String("0.1.104") }]) { await client.ensureEndpoint(INSTALL, options); expect(sent(), JSON.stringify(options)).toEqual({ body: undefined, contentType: null }); } expect(fetchImpl).toHaveBeenCalledTimes(9); }); it("says a self-hosted server is one only when told to, on registration, its address and its relay token", async () => { const fetchImpl = vi.fn(async (url) => { const path = new URL(url).pathname; if (path === "/v1/installations" ) return jsonResponse({ installation: { id: INSTALL_ID, clientInstanceId: "server-1", name: "vps", platform: "linux" }, credential: INSTALL }, { status: 201 }); if (path === "/v1/installations/self/endpoint") return jsonResponse({ endpoint: { url: "https://c-opaque.mausbot.si" }, connectorToken: `eyJ${"x".repeat(80)}` }); return jsonResponse({ token: "a.b", hostId: "h", nodes: [], expiresAt: 1, refreshAfter: 1 }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); const body = () => JSON.parse(fetchImpl.mock.lastCall[1].body); const register = (kind) => client.ensureInstallation({ accountToken: ACCOUNT, currentCredential: "", clientInstanceId: "server-1", name: "vps", platform: "linux", appVersion: "0.1.153", kind }); fetchImpl.mockImplementationOnce(async () => jsonResponse({ installations: [] })); await register("server"); expect(body()).toEqual({ clientInstanceId: "server-1", name: "vps", platform: "linux", appVersion: "0.1.153", kind: "server" }); fetchImpl.mockImplementationOnce(async () => jsonResponse({ installations: [] })); await register(undefined); expect(body()).toEqual({ clientInstanceId: "server-1", name: "vps", platform: "linux", appVersion: "0.1.153" }); await client.ensureEndpoint(INSTALL, { appVersion: "0.1.153", kind: "server" }); expect(body()).toEqual({ appVersion: "0.1.153", kind: "server" }); await client.ensureEndpoint(INSTALL, { appVersion: "0.1.153", kind: "laptop" }); expect(body()).toEqual({ appVersion: "0.1.153" }); await client.relayToken(INSTALL, { appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 }, kind: "server" }); expect(body()).toEqual({ appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 }, kind: "server" }); await client.relayToken(INSTALL, { appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 } }); expect(body()).toEqual({ appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 } }); }); it("asks once more without its kind when a control plane older than the field refuses it, and only then", async () => { const bodies = []; let answers = []; const fetchImpl = vi.fn(async (_url, init) => { bodies.push(init.body === undefined ? undefined : JSON.parse(init.body)); const next = answers.shift() ?? 200; return next === 200 ? jsonResponse({ endpoint: { url: "https://c-opaque.mausbot.si" }, connectorToken: `eyJ${"x".repeat(80)}`, token: "a.b" }) : jsonResponse({ error: next === 400 ? "invalid_request" : "rate_limited" }, { status: next }); }); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); answers = [400]; await client.ensureEndpoint(INSTALL, { appVersion: "0.1.153", kind: "server" }); expect(bodies).toEqual([{ appVersion: "0.1.153", kind: "server" }, { appVersion: "0.1.153" }]); bodies.length = 0; answers = [400]; await client.relayToken(INSTALL, { appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 }, kind: "server" }); expect(bodies).toEqual([{ appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 }, kind: "server" }, { appVersion: "0.1.153", devices: { e2e: 1, legacy: 0 } }]); // Once only, only for that refusal, and never for a request that carried no kind. for (const [kind, refusals, calls] of [["server", [400, 400], 2], ["server", [429], 1], [undefined, [400], 1]]) { bodies.length = 0; answers = refusals; await expect(client.ensureEndpoint(INSTALL, { appVersion: "0.1.153", kind })).rejects.toBeInstanceOf(ControlPlaneError); expect(bodies, `${kind} ${refusals}`).toHaveLength(calls); } }); it("reads why a relay-capable computer goes without a tunnel, and nothing else from the body", async () => { for (const [body, tunnel] of [ [{ error: "relay_capable", tunnel: "retired" }, "retired"], [{ error: "relay_capable", tunnel: "full" }, "full"], [{ error: "relay_capable" }, null], [{ error: "relay_capable", tunnel: "anything" }, null], [{ error: "endpoint_capacity", tunnel: "retired" }, null], ]) { const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => jsonResponse(body, { status: 409 })), }); await expect(client.ensureEndpoint(INSTALL, { appVersion: "0.1.152", legacyDevices: 1 })).rejects.toMatchObject({ code: body.error, tunnel }); } }); it("maps bounded server error codes and hides arbitrary response text", async () => { const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => jsonResponse({ error: "rate_limited", detail: "secret detail" }, { status: 429 })), }); await expect(client.requestOTP("ada@example.com")).rejects.toMatchObject({ name: "ControlPlaneError", code: "rate_limited", status: 429, }); }); it("falls back from Better Auth's message-only 429 without exposing its prose", async () => { const requestId = "44444444-4444-4444-8444-444444444444"; const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => jsonResponse( { message: "Too many requests. Please try again later." }, { status: 429, headers: { "x-request-id": requestId } }, )), }); await expect(client.requestOTP("ada@example.com")).rejects.toMatchObject({ name: "ControlPlaneError", code: "rate_limited", status: 429, requestId, }); }); it("uses stable status errors when a response has no public error contract", async () => { const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => jsonResponse( { code: "INTERNAL_DEPENDENCY_DETAIL", message: "do not expose this" }, { status: 400, headers: { "x-request-id": "not-a-safe-request-id" } }, )), }); await expect(client.requestOTP("ada@example.com")).rejects.toMatchObject({ code: "invalid_request", status: 400, requestId: "", }); }); it("fails closed on redirects and network errors", async () => { const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl: vi.fn(async () => { throw new TypeError("redirect blocked"); }), }); await expect(client.requestOTP("ada@example.com")).rejects.toEqual( expect.objectContaining({ code: "network_unavailable" }), ); expect(() => createControlPlaneClient({ baseURL: "http://remote.example" })).toThrow( ControlPlaneError, ); }); it("reads the endpoint without a connector token and maps a removed endpoint to null", async () => { const fetchImpl = vi .fn() .mockResolvedValueOnce(jsonResponse({ endpoint: null })) .mockResolvedValueOnce(jsonResponse({ endpoint: { url: "https://c-opaque.openmausbot.com", hostname: "c-opaque.openmausbot.com", status: "deleting" }, })) .mockResolvedValueOnce(jsonResponse({ endpoint: { url: "https://c-opaque.openmausbot.com", status: "renamed-by-a-future-server" }, })) .mockResolvedValueOnce(jsonResponse({ endpoint: { url: "http://c-opaque.openmausbot.com" } })); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); await expect(client.getEndpoint(INSTALL)).resolves.toBeNull(); await expect(client.getEndpoint(INSTALL)).resolves.toEqual({ url: "https://c-opaque.openmausbot.com", status: "deleting", }); await expect(client.getEndpoint(INSTALL)).resolves.toEqual({ url: "https://c-opaque.openmausbot.com", status: "unknown", }); await expect(client.getEndpoint(INSTALL)).rejects.toMatchObject({ code: "invalid_response" }); const [url, init] = fetchImpl.mock.calls[0]; expect(url).toBe("https://accounts.openmausbot.com/v1/installations/self/endpoint"); expect(init.method).toBe("GET"); expect(init.headers.get("authorization")).toBe(`Bearer ${INSTALL}`); await expect(client.getEndpoint(ACCOUNT)).rejects.toMatchObject({ code: "signed_out", status: 401 }); }); it("carries a capacity error code and the server's Retry-After delay", async () => { const fetchImpl = vi .fn() .mockResolvedValueOnce(jsonResponse({ error: "endpoint_capacity" }, { status: 503, headers: { "retry-after": "600", "x-request-id": "44444444-4444-4444-8444-444444444444" }, })) .mockResolvedValueOnce(jsonResponse({ error: "endpoint_capacity" }, { status: 503, headers: { "retry-after": "Wed, 21 Oct 2026 07:28:00 GMT" }, })); const client = createControlPlaneClient({ baseURL: "https://accounts.openmausbot.com", fetchImpl }); const first = await client.ensureEndpoint(INSTALL).catch((error) => error); expect(first).toBeInstanceOf(ControlPlaneError); expect(first).toMatchObject({ code: "endpoint_capacity", status: 503, retryAfterMs: 600_000, requestId: "44444444-4444-4444-8444-444444444444", }); await expect(client.ensureEndpoint(INSTALL)).rejects.toMatchObject({ code: "endpoint_capacity", retryAfterMs: 0, }); }); });