import { beforeEach, describe, expect, it, vi } from "vitest"; import { dialPairingChannel, type PairingSocket } from "./pairing-dial"; import { encodePairingCode } from "./pairing-code"; const enc = (o: unknown) => new TextEncoder().encode(JSON.stringify(o)); const dec = (b: Uint8Array) => JSON.parse(new TextDecoder().decode(b)); const LISTENER_EPHEMERAL_HEX = "a".repeat(64); const CODE = encodePairingCode("192.168.4.77", 51555, Uint8Array.of(0xde, 0xad, 0xbe, 0xef)); const FAKE_HANDSHAKE_HASH = Uint8Array.from([0x0f, 0xba, 0xb8, 0xcd, ...new Array(28).fill(0)]); // Skip the real handshake messages; encrypt/decrypt are identity transforms so // the channel's framing can be asserted directly. vi.mock("./noise-js", async (orig) => { const actual = await orig(); return { ...actual, noiseNKInitiator: vi.fn(async () => ({ encrypt: (pt: Uint8Array) => pt, decrypt: (ct: Uint8Array) => ct, handshakeHash: FAKE_HANDSHAKE_HASH, })), }; }); /** `null` in the queue means "the socket closes here with no data". */ function fakeSocket(inbound: Array) { const sent: Uint8Array[] = []; let closed = false; let lastWasClose = false; const queue = [...inbound]; const sock: PairingSocket = { send(bytes) { sent.push(bytes); }, async receive() { const next = queue.shift(); if (next === undefined || next === null) { closed = true; lastWasClose = true; throw new Error("socket closed"); } lastWasClose = false; return next; }, close() { closed = true; }, closedBeforeFrame() { return lastWasClose; }, }; return { sock, sent, isClosed: () => closed }; } function ackThen(...rest: Array) { return fakeSocket([ enc({ type: "PEACH_HELLO_ACK", ephemeralPublicKeyHex: LISTENER_EPHEMERAL_HEX }), ...rest, ]); } beforeEach(() => { vi.clearAllMocks(); }); describe("dialPairingChannel", () => { it("dials the coded endpoint", async () => { const openSocket = vi.fn(async () => ackThen().sock); const result = await dialPairingChannel(CODE, { openSocket }); expect(result.ok).toBe(true); expect(openSocket).toHaveBeenCalledWith("192.168.4.77", 51555); }); it("presents the token as hex and returns the shared SAS", async () => { const s = ackThen(); const result = await dialPairingChannel(CODE, { openSocket: async () => s.sock }); expect(dec(s.sent[0])).toEqual({ type: "PEACH_HELLO", token: "deadbeef" }); expect(result.ok && result.dialled.sas).toBe("895245"); expect(result.ok && result.dialled.host).toBe("192.168.4.77"); expect(result.ok && result.dialled.rendezvousSecretHex).toBe( "a8977cd86e944e72e9cb569dbba00a7b0abbf7f456c745299aa8f66157859143", ); }); it("rejects an addressless legacy code before opening a socket", async () => { const openSocket = vi.fn(async () => ackThen().sock); const result = await dialPairingChannel("123456", { openSocket }); expect(result).toEqual({ ok: false, error: "invalid_code" }); expect(openSocket).not.toHaveBeenCalled(); }); it("reads a silent close as invalid_code, not a transport failure", async () => { // A wrong or expired token gets no error frame — the listener just closes. const s = fakeSocket([null]); const result = await dialPairingChannel(CODE, { openSocket: async () => s.sock }); expect(result).toEqual({ ok: false, error: "invalid_code" }); expect(s.isClosed()).toBe(true); }); it("treats a non-ACK first frame exactly like a wrong token", async () => { const s = fakeSocket([enc({ type: "SOMETHING_ELSE" })]); const result = await dialPairingChannel(CODE, { openSocket: async () => s.sock }); expect(result).toEqual({ ok: false, error: "invalid_code" }); }); it("rejects an ACK whose ephemeral key is not 32-byte hex", async () => { const s = fakeSocket([enc({ type: "PEACH_HELLO_ACK", ephemeralPublicKeyHex: "nope" })]); const result = await dialPairingChannel(CODE, { openSocket: async () => s.sock }); expect(result).toEqual({ ok: false, error: "handshake_failed" }); expect(s.isClosed()).toBe(true); }); it("reports no_host_found when the endpoint refuses the connection", async () => { const result = await dialPairingChannel(CODE, { openSocket: async () => { throw new Error("ECONNREFUSED"); }, }); expect(result).toEqual({ ok: false, error: "no_host_found" }); }); it("leaves the socket open on success so the caller owns its lifetime", async () => { const s = ackThen(enc({ hello: "world" })); const result = await dialPairingChannel(CODE, { openSocket: async () => s.sock }); if (!result.ok) throw new Error("expected a dialled channel"); expect(s.isClosed()).toBe(false); await result.dialled.channel.send(enc({ type: "ANYTHING" })); // sent[0] is the plaintext hello; sent[1] went through the Noise channel. expect(dec(s.sent[1])).toEqual({ type: "ANYTHING" }); expect(dec(await result.dialled.channel.receive())).toEqual({ hello: "world" }); result.dialled.socket.close(); expect(s.isClosed()).toBe(true); }); });