rendezvous.test.ts

2.5 KB · raw

1import { describe, expect, it, vi } from "vitest";23import {4  DEFAULT_RELAY_URL,5  buildRendezvousUrl,6  bytesToHex,7  deriveRendezvousId,8  deriveRendezvousSecret,9  dialingRendezvousIds,10  generatePairingRendezvousToken,11  normalizeRelayUrl,12  rendezvousSecretFromHex,13  rendezvousWindowIndex,14  waitingRendezvousIds,15} from "./rendezvous";1617const HANDSHAKE_HASH = rendezvousSecretFromHex(18  "0fbab8cd1782bf4b17d69beb69f5b80b0bf24d93da4924959c76ee701c32e655",19);2021describe("relay rendezvous contract", () => {22  it("derives the cross-platform secret and hourly id KATs", () => {23    const secret = deriveRendezvousSecret(HANDSHAKE_HASH);24    expect(bytesToHex(secret)).toBe(25      "0803691c8ac7330883c0987e33cea4a171992366ce4b06b88691e84ca689773d",26    );27    expect(deriveRendezvousId(secret, 500_000)).toBe(28      "9UY3j5AHnwYSApvymtY965su9n60rQOv8QZ2PZzHuKI",29    );30  });3132  it("uses one-hour windows with mandatory skew tolerance order", () => {33    const secret = deriveRendezvousSecret(HANDSHAKE_HASH);34    const now = 500_000 * 3600 + 3599;35    expect(rendezvousWindowIndex(now)).toBe(500_000);36    expect(waitingRendezvousIds(secret, now)).toEqual([37      deriveRendezvousId(secret, 500_000),38      deriveRendezvousId(secret, 499_999),39    ]);40    expect(dialingRendezvousIds(secret, now)).toEqual([41      deriveRendezvousId(secret, 500_000),42      deriveRendezvousId(secret, 499_999),43      deriveRendezvousId(secret, 500_001),44    ]);45  });4647  it("generates a fresh 128-bit base64url first-pair token", () => {48    vi.spyOn(crypto, "getRandomValues").mockImplementation((array) => {49      (array as Uint8Array).set(Array.from({ length: 16 }, (_, i) => i));50      return array;51    });52    expect(generatePairingRendezvousToken()).toBe("AAECAwQFBgcICQoLDA0ODw");53  });5455  it("accepts only credential-free wss relay URLs", () => {56    expect(normalizeRelayUrl(`${DEFAULT_RELAY_URL}/`)).toBe(DEFAULT_RELAY_URL);57    expect(normalizeRelayUrl("wss://relay.example.test/base/")).toBe(58      "wss://relay.example.test/base",59    );60    expect(() => normalizeRelayUrl("ws://relay.example.test")).toThrow(/wss/);61    expect(() => normalizeRelayUrl("wss://user:[email protected]")).toThrow();62    expect(() => normalizeRelayUrl("wss://relay.example.test?token=x")).toThrow();63  });6465  it("builds the relay path without exposing identity", () => {66    const id = "AAECAwQFBgcICQoLDA0ODw";67    expect(buildRendezvousUrl(DEFAULT_RELAY_URL, id)).toBe(68      `${DEFAULT_RELAY_URL}/r/${id}`,69    );70    expect(() => buildRendezvousUrl(DEFAULT_RELAY_URL, "short")).toThrow();71  });72});