rendezvous.test.ts

3.1 KB · raw

1import { describe, expect, it, vi } from "vitest";23import {4  DEFAULT_RELAY_URL,5  buildRendezvousUrl,6  bytesToHex,7  deriveMeshRendezvousSecret,8  deriveRendezvousId,9  deriveRendezvousSecret,10  dialingRendezvousIds,11  generatePairingRendezvousToken,12  normalizeRelayUrl,13  rendezvousSecretFromHex,14  rendezvousWindowIndex,15  waitingRendezvousIds,16} from "./rendezvous";1718const HANDSHAKE_HASH = rendezvousSecretFromHex(19  "0fbab8cd1782bf4b17d69beb69f5b80b0bf24d93da4924959c76ee701c32e655",20);2122describe("relay rendezvous contract", () => {23  it("derives the symmetric cross-client mesh capability vector", () => {24    const root = Uint8Array.from({ length: 32 }, (_, i) => i);25    const low = Uint8Array.from({ length: 32 }, (_, i) => i + 32);26    const high = Uint8Array.from({ length: 32 }, (_, i) => i + 64);27    const forward = deriveMeshRendezvousSecret(root, low, high);28    const reverse = deriveMeshRendezvousSecret(root, high, low);2930    expect(bytesToHex(forward)).toBe(31      "ad0359be7dc8fbb7df19ed027354b5029133a23a6023f43c2b3500b43addae7b",32    );33    expect(reverse).toEqual(forward);34  });3536  it("derives the cross-platform secret and hourly id KATs", () => {37    const secret = deriveRendezvousSecret(HANDSHAKE_HASH);38    expect(bytesToHex(secret)).toBe(39      "0803691c8ac7330883c0987e33cea4a171992366ce4b06b88691e84ca689773d",40    );41    expect(deriveRendezvousId(secret, 500_000)).toBe(42      "9UY3j5AHnwYSApvymtY965su9n60rQOv8QZ2PZzHuKI",43    );44  });4546  it("uses one-hour windows with mandatory skew tolerance order", () => {47    const secret = deriveRendezvousSecret(HANDSHAKE_HASH);48    const now = 500_000 * 3600 + 3599;49    expect(rendezvousWindowIndex(now)).toBe(500_000);50    expect(waitingRendezvousIds(secret, now)).toEqual([51      deriveRendezvousId(secret, 500_000),52      deriveRendezvousId(secret, 499_999),53    ]);54    expect(dialingRendezvousIds(secret, now)).toEqual([55      deriveRendezvousId(secret, 500_000),56      deriveRendezvousId(secret, 499_999),57      deriveRendezvousId(secret, 500_001),58    ]);59  });6061  it("generates a fresh 128-bit base64url first-pair token", () => {62    vi.spyOn(crypto, "getRandomValues").mockImplementation((array) => {63      (array as Uint8Array).set(Array.from({ length: 16 }, (_, i) => i));64      return array;65    });66    expect(generatePairingRendezvousToken()).toBe("AAECAwQFBgcICQoLDA0ODw");67  });6869  it("accepts only credential-free wss relay URLs", () => {70    expect(normalizeRelayUrl(`${DEFAULT_RELAY_URL}/`)).toBe(DEFAULT_RELAY_URL);71    expect(normalizeRelayUrl("wss://relay.example.test/base/")).toBe(72      "wss://relay.example.test/base",73    );74    expect(() => normalizeRelayUrl("ws://relay.example.test")).toThrow(/wss/);75    expect(() => normalizeRelayUrl("wss://user:[email protected]")).toThrow();76    expect(() => normalizeRelayUrl("wss://relay.example.test?token=x")).toThrow();77  });7879  it("builds the relay path without exposing identity", () => {80    const id = "AAECAwQFBgcICQoLDA0ODw";81    expect(buildRendezvousUrl(DEFAULT_RELAY_URL, id)).toBe(82      `${DEFAULT_RELAY_URL}/r/${id}`,83    );84    expect(() => buildRendezvousUrl(DEFAULT_RELAY_URL, "short")).toThrow();85  });86});