import { describe, expect, it } from "vitest"; import { MAX_MEDIA_ROUTE_REVISION, MAX_SFU_TOKEN_LENGTH, MAX_VIEWER_QUALITY_EVIDENCE_BYTES, MAX_VIEWERS_PER_ROOM_LIMIT, clientMessageSchema, decodeClientMessage, participantRouteAssignmentSchema, serverMessageSchema, } from "../src/shared/protocol.js"; const token = "a".repeat(43); const roomId = "123456789012"; const qualitySettings = { resolution: "1080p", maxFramerate: 60, maxBitrate: 8_000_000, degradationPreference: "maintain-resolution", } as const; const qualityEvidence = { type: "viewer-quality-evidence", guard: { connectionId: "connection_12345678", routeRevision: 0, }, sequence: 0, windowMs: 2_000, metrics: { width: 1_920, height: 1_080, framesPerSecond: 59.8, bitrateKbps: 7_500, packetsReceivedDelta: 1_500, packetsLostDelta: 2, jitterMs: 3.5, framesDecodedDelta: 120, framesDroppedDelta: 1, decodeMsPerFrame: 2.4, freezeCountDelta: 0, freezeDurationMsDelta: 0, codec: "video/H264", codecProfile: "profile-level-id=42e01f", codecParameters: "packetization-mode=1; level-asymmetry-allowed=1", }, } as const; describe("client signaling protocol", () => { it("accepts a bounded authentication message", () => { expect( decodeClientMessage( JSON.stringify({ type: "authenticate", roomId, role: "viewer", clientId: "client_12345678", }), ), ).toMatchObject({ type: "authenticate", role: "viewer" }); }); it("rejects unknown fields and malformed tokens", () => { const result = clientMessageSchema.safeParse({ type: "authenticate", roomId, role: "host", token: "short", clientId: "client_12345678", admin: true, }); expect(result.success).toBe(false); }); it("requires a host token and rejects viewer tokens or malformed room codes", () => { expect( clientMessageSchema.safeParse({ type: "authenticate", roomId, role: "host", token, clientId: "client_12345678", }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "authenticate", roomId, role: "viewer", token, clientId: "client_12345678", }).success, ).toBe(false); expect( clientMessageSchema.safeParse({ type: "authenticate", roomId: "1", role: "viewer", clientId: "client_12345678", }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "authenticate", roomId: "0123", role: "viewer", clientId: "client_12345678", }).success, ).toBe(false); expect( clientMessageSchema.safeParse({ type: "authenticate", roomId: "1".repeat(13), role: "viewer", clientId: "client_12345678", }).success, ).toBe(false); }); it("bounds SDP before routing it", () => { const result = clientMessageSchema.safeParse({ type: "signal", targetPeerId: "viewer_12345678", payload: { kind: "description", connectionId: "connection_12345678", description: { type: "offer", sdp: "v".repeat(48 * 1024 + 1), }, }, }); expect(result.success).toBe(false); }); it("requires viewers to choose ICE restart or peer rebuild explicitly", () => { const restartRequest = { type: "restart-request", connectionId: "connection_12345678", rebuild: true, }; expect(clientMessageSchema.safeParse(restartRequest).success).toBe(true); expect( clientMessageSchema.safeParse({ ...restartRequest, targetPeerId: "parent_12345678", }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: restartRequest.type, connectionId: restartRequest.connectionId, }).success, ).toBe(false); }); it("accepts explicit and legacy sharing-stop messages", () => { expect(clientMessageSchema.safeParse({ type: "stop-sharing" }).success).toBe( true, ); expect( clientMessageSchema.safeParse({ type: "stop-sharing", shareGeneration: "share_generation_12345678", }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "authenticate", roomId, role: "host", token, clientId: "client_12345678", shareGeneration: "share_generation_12345678", }).success, ).toBe(true); expect(clientMessageSchema.safeParse({ type: "close-room" }).success).toBe( true, ); expect(clientMessageSchema.safeParse({ type: "abandon-room" }).success).toBe( true, ); }); it("accepts only strict, bounded quality settings", () => { expect( clientMessageSchema.safeParse({ type: "set-quality-settings", qualitySettings, }).success, ).toBe(true); for (const invalid of [ { ...qualitySettings, resolution: "2160p" }, { ...qualitySettings, maxFramerate: 14 }, { ...qualitySettings, maxFramerate: 61 }, { ...qualitySettings, maxFramerate: 30.5 }, { ...qualitySettings, maxBitrate: 1_999_999 }, { ...qualitySettings, maxBitrate: 12_000_001 }, { ...qualitySettings, maxBitrate: 5_000_000.5 }, { ...qualitySettings, degradationPreference: "automatic" }, { ...qualitySettings, codec: "video/VP9" }, ]) { expect( clientMessageSchema.safeParse({ type: "set-quality-settings", qualitySettings: invalid, }).success, ).toBe(false); } const { maxFramerate: _missing, ...missingField } = qualitySettings; expect( clientMessageSchema.safeParse({ type: "set-quality-settings", qualitySettings: missingField, }).success, ).toBe(false); }); it("accepts only a binary browser relay capacity", () => { expect( clientMessageSchema.safeParse({ type: "relay-capacity", downstreamEdges: 0, }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "relay-capacity", downstreamEdges: 1, }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "relay-capacity", downstreamEdges: 2, }).success, ).toBe(false); expect( clientMessageSchema.safeParse({ type: "relay-capacity", downstreamEdges: 1, score: 100, }).success, ).toBe(false); }); it("accepts only strict, bounded viewer quality evidence", () => { expect(clientMessageSchema.safeParse(qualityEvidence).success).toBe(true); expect( Buffer.byteLength(JSON.stringify(qualityEvidence), "utf8"), ).toBeLessThanOrEqual(MAX_VIEWER_QUALITY_EVIDENCE_BYTES); for (const invalid of [ { ...qualityEvidence, roomId }, { ...qualityEvidence, guard: { ...qualityEvidence.guard, peerId: "viewer_12345678" }, }, { ...qualityEvidence, windowMs: 999 }, { ...qualityEvidence, sequence: -1 }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, width: null }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, bitrateKbps: Number.POSITIVE_INFINITY }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, freezeDurationMsDelta: 2_001 }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, codecParameters: "sprop-parameter-sets=deadbeef", }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, codecProfile: "device-id=deadbeef", }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, scalabilityMode: "DEVICE_ABC123", }, }, { ...qualityEvidence, metrics: { ...qualityEvidence.metrics, decoderImplementation: "device-specific-decoder", }, }, ]) { expect(clientMessageSchema.safeParse(invalid).success).toBe(false); } }); it.each([ ["video/VP8", null, "max-fr=60; max-fs=8160"], ["video/VP9", "profile-id=2", "max-fs=8160"], ["video/AV1", "profile=1", "level-idx=31; tier=0"], ["video/unknown", null, null], ])( "accepts canonical viewer codec evidence for %s", (codec, codecProfile, codecParameters) => { expect( clientMessageSchema.safeParse({ ...qualityEvidence, metrics: { ...qualityEvidence.metrics, codec, codecProfile, codecParameters, }, }).success, ).toBe(true); }, ); it("accepts bounded route acknowledgements, failures, and SFU refreshes", () => { expect( clientMessageSchema.safeParse({ type: "route-ready", revision: 7, phase: "prepare", }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "route-failed", revision: 7, phase: "active", connectionId: null, }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "refresh-sfu", revision: MAX_MEDIA_ROUTE_REVISION, }).success, ).toBe(true); expect( clientMessageSchema.safeParse({ type: "route-ready", revision: -1, phase: "prepare", }).success, ).toBe(false); expect( clientMessageSchema.safeParse({ type: "route-failed", revision: 7, phase: "active", }).success, ).toBe(false); expect( clientMessageSchema.safeParse({ type: "refresh-sfu", revision: 1.5, }).success, ).toBe(false); }); }); describe("server signaling protocol", () => { function authenticatedMessage(maxViewers: number, viewerPeerIds: string[] = []) { return { type: "authenticated", role: "host", peerId: "host_12345678", roomExpiresAt: "2026-08-18T18:00:00.000Z", maxViewers, hostOnline: true, connectionId: null, viewerPeerIds, iceConfig: { iceServers: [], expiresAt: null, relayAvailable: false, }, }; } it("accepts dynamic viewer limits within the protocol boundary", () => { expect(serverMessageSchema.safeParse(authenticatedMessage(1)).success).toBe( true, ); expect(serverMessageSchema.safeParse(authenticatedMessage(8)).success).toBe( true, ); expect( serverMessageSchema.safeParse( authenticatedMessage(MAX_VIEWERS_PER_ROOM_LIMIT), ).success, ).toBe(true); }); it("represents persistent rooms without a room expiry", () => { expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), roomExpiresAt: null, }).success, ).toBe(true); expect( serverMessageSchema.safeParse({ type: "sharing-stopped" }).success, ).toBe(true); }); it("requires a complete bounded peer-assisted assignment", () => { const peerAssisted = { ...authenticatedMessage(8), mediaMode: "peer-assisted", mediaAssignment: { parentPeerId: null, childPeerIds: ["viewer_12345678", "viewer_87654321"], }, routeRevision: 0, routeAssignment: { upstream: { kind: "none" }, childPeerIds: ["viewer_12345678", "viewer_87654321"], sfuPublicationGeneration: null, }, qualitySettings, }; expect(serverMessageSchema.safeParse(peerAssisted).success).toBe(true); expect( serverMessageSchema.safeParse({ ...peerAssisted, sfuStandbyUrl: "wss://sfu.example.com", }).success, ).toBe(true); expect( serverMessageSchema.safeParse({ type: "media-assignment", mediaAssignment: peerAssisted.mediaAssignment, }).success, ).toBe(true); expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), mediaMode: "peer-assisted", routeRevision: 0, routeAssignment: peerAssisted.routeAssignment, qualitySettings, }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), mediaMode: "peer-assisted", mediaAssignment: peerAssisted.mediaAssignment, routeRevision: 0, routeAssignment: peerAssisted.routeAssignment, }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...peerAssisted, mediaAssignment: { parentPeerId: null, childPeerIds: [ "viewer_12345678", "viewer_87654321", "viewer_overflow", ], }, }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...peerAssisted, qualitySettings: { ...qualitySettings, maxBitrate: 20_000_000 }, }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), qualitySettings, }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), sfuStandbyUrl: "wss://sfu.example.com", }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...peerAssisted, sfuStandbyUrl: "https://sfu.example.com", }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ type: "quality-settings", qualitySettings: { resolution: "720p", maxFramerate: 30, maxBitrate: 3_000_000, degradationPreference: "balanced", }, }).success, ).toBe(true); expect( serverMessageSchema.safeParse({ type: "quality-settings", qualitySettings: { ...qualitySettings, maxFramerate: 0 }, }).success, ).toBe(false); }); it("keeps hybrid route messages strict and separate from ordinary P2P auth", () => { const assignment = { upstream: { kind: "peer", peerId: "parent_12345678" }, childPeerIds: ["child_12345678", "child_87654321"], sfuPublicationGeneration: null, }; expect(participantRouteAssignmentSchema.safeParse(assignment).success).toBe( true, ); expect( serverMessageSchema.safeParse({ type: "route-update", revision: 9, phase: "prepare", assignment, }).success, ).toBe(true); expect( serverMessageSchema.safeParse({ type: "sfu-config", revision: 9, url: "wss://sfu.example.com", token: "header.payload.signature", }).success, ).toBe(true); expect( participantRouteAssignmentSchema.safeParse({ ...assignment, childPeerIds: [ "child_12345678", "child_87654321", "child_overflow", ], }).success, ).toBe(false); expect( participantRouteAssignmentSchema.safeParse({ ...assignment, childPeerIds: ["child_12345678", "child_12345678"], }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ type: "route-update", revision: 9, phase: "prepare", assignment, roomAssignments: [], }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ type: "sfu-config", revision: 9, url: "wss://sfu.example.com", token: "x".repeat(MAX_SFU_TOKEN_LENGTH + 1), }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...authenticatedMessage(8), routeRevision: 9, }).success, ).toBe(false); }); it("accepts every bounded hybrid upstream shape", () => { for (const upstream of [ { kind: "none" }, { kind: "peer", peerId: "parent_12345678" }, { kind: "sfu" }, ]) { expect( participantRouteAssignmentSchema.safeParse({ upstream, childPeerIds: [], sfuPublicationGeneration: upstream.kind === "none" ? "generation_12345678" : null, }).success, ).toBe(true); } }); it("accepts only canonical server-derived viewer evidence envelopes", () => { const forwarded = { ...qualityEvidence, viewerPeerId: "viewer_12345678", parentPeerId: "host_12345678", }; expect(serverMessageSchema.safeParse(forwarded).success).toBe(true); expect( Buffer.byteLength(JSON.stringify(forwarded), "utf8"), ).toBeLessThanOrEqual(MAX_VIEWER_QUALITY_EVIDENCE_BYTES); expect( serverMessageSchema.safeParse({ ...forwarded, roomId }).success, ).toBe(false); expect( serverMessageSchema.safeParse({ ...qualityEvidence, viewerPeerId: "viewer_12345678", }).success, ).toBe(false); }); it.each([0, 1.5, MAX_VIEWERS_PER_ROOM_LIMIT + 1])( "rejects viewer limit %s outside the protocol boundary", (maxViewers) => { expect( serverMessageSchema.safeParse(authenticatedMessage(maxViewers)).success, ).toBe(false); }, ); it("bounds authenticated viewer rosters independently of configured capacity", () => { const viewerPeerIds = Array.from( { length: MAX_VIEWERS_PER_ROOM_LIMIT }, (_, index) => `viewer_${index.toString().padStart(8, "0")}`, ); expect( serverMessageSchema.safeParse( authenticatedMessage(MAX_VIEWERS_PER_ROOM_LIMIT, viewerPeerIds), ).success, ).toBe(true); expect( serverMessageSchema.safeParse( authenticatedMessage(MAX_VIEWERS_PER_ROOM_LIMIT, [ ...viewerPeerIds, "viewer_overflow", ]), ).success, ).toBe(false); }); });