@@ -14,6 +14,7 @@ import {
1414 ParticipantKind ,
1515 Room ,
1616 RoomEvent ,
17+ type RoomOptions ,
1718 RpcError ,
1819 SimulateScenarioKind ,
1920 TrackKind ,
@@ -99,7 +100,10 @@ async function createJoinToken(params: {
99100 return await token . toJwt ( ) ;
100101}
101102
102- async function connectTestRooms ( count : number ) : Promise < { roomName : string ; rooms : Room [ ] } > {
103+ async function connectTestRooms (
104+ count : number ,
105+ extraOptions ?: Partial < RoomOptions > ,
106+ ) : Promise < { roomName : string ; rooms : Room [ ] } > {
103107 const env = getTestEnv ( ) ;
104108 const roomName = `test_room_${ randomUUID ( ) } ` ;
105109 const rooms = await Promise . all (
@@ -111,7 +115,11 @@ async function connectTestRooms(count: number): Promise<{ roomName: string; room
111115 name : `Participant ${ i } ` ,
112116 } ) ;
113117 const room = new Room ( ) ;
114- await room . connect ( env . url , token , { autoSubscribe : true , dynacast : false } ) ;
118+ await room . connect ( env . url , token , {
119+ autoSubscribe : true ,
120+ dynacast : false ,
121+ ...extraOptions ,
122+ } ) ;
115123 return room ;
116124 } ) ,
117125 ) ;
@@ -296,6 +304,46 @@ describeE2E('livekit-rtc e2e', () => {
296304 testTimeoutMs ,
297305 ) ;
298306
307+ it (
308+ 'sends and receives a data message between participants sharing a key' ,
309+ async ( ) => {
310+ // A shared-key `keyProviderOptions` with only `sharedKey` set relies on
311+ // the SDK filling in the remaining (proto-required) provider defaults;
312+ // regression guard for connect failing to encode KeyProviderOptions.
313+ const encryption = {
314+ keyProviderOptions : { sharedKey : new TextEncoder ( ) . encode ( 'test-shared-key' ) } ,
315+ } ;
316+ const { rooms } = await connectTestRooms ( 2 , { encryption } ) ;
317+ const [ receivingRoom , sendingRoom ] = rooms ;
318+ const senderIdentity = sendingRoom ! . localParticipant ! . identity ;
319+ const receiverIdentity = receivingRoom ! . localParticipant ! . identity ;
320+
321+ const payload = new TextEncoder ( ) . encode ( 'e2ee-hello' ) ;
322+ const received = withTimeout (
323+ new Promise < Uint8Array > ( ( resolve ) => {
324+ receivingRoom ! . on ( RoomEvent . DataReceived , ( data , participant ) => {
325+ if ( participant ?. identity !== senderIdentity ) return ;
326+ resolve ( data ) ;
327+ } ) ;
328+ } ) ,
329+ testTimeoutMs ,
330+ 'Timed out waiting for encrypted data message' ,
331+ ) ;
332+
333+ await sendingRoom ! . localParticipant ! . publishData ( payload , {
334+ reliable : true ,
335+ destination_identities : [ receiverIdentity ] ,
336+ } ) ;
337+
338+ // The message round-trips intact only if both sides brought a working
339+ // shared-key provider through connect and encrypt/decrypt lined up.
340+ expect ( await received ) . toEqual ( payload ) ;
341+
342+ await Promise . all ( rooms . map ( ( r ) => r . disconnect ( ) ) ) ;
343+ } ,
344+ testTimeoutMs ,
345+ ) ;
346+
299347 it (
300348 'emits participantDisconnected when a participant leaves' ,
301349 async ( ) => {
0 commit comments