livekit-client 1.13.0 → 1.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +122 -105
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +172 -109
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/e2ee/E2eeManager.d.ts +4 -3
  10. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  11. package/dist/src/e2ee/KeyProvider.d.ts +7 -6
  12. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  13. package/dist/src/e2ee/events.d.ts +34 -0
  14. package/dist/src/e2ee/events.d.ts.map +1 -0
  15. package/dist/src/e2ee/index.d.ts +1 -0
  16. package/dist/src/e2ee/index.d.ts.map +1 -1
  17. package/dist/src/e2ee/types.d.ts +17 -33
  18. package/dist/src/e2ee/types.d.ts.map +1 -1
  19. package/dist/src/e2ee/worker/FrameCryptor.d.ts +15 -12
  20. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  21. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
  22. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  23. package/dist/src/room/PCTransport.d.ts.map +1 -1
  24. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  25. package/dist/src/room/Room.d.ts.map +1 -1
  26. package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
  27. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  28. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  29. package/dist/src/room/track/processor/types.d.ts +2 -1
  30. package/dist/src/room/track/processor/types.d.ts.map +1 -1
  31. package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +4 -3
  32. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +7 -6
  33. package/dist/ts4.2/src/e2ee/events.d.ts +34 -0
  34. package/dist/ts4.2/src/e2ee/index.d.ts +1 -0
  35. package/dist/ts4.2/src/e2ee/types.d.ts +17 -33
  36. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +15 -12
  37. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
  38. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
  39. package/dist/ts4.2/src/room/track/processor/types.d.ts +2 -1
  40. package/package.json +1 -1
  41. package/src/e2ee/E2eeManager.ts +105 -77
  42. package/src/e2ee/KeyProvider.ts +23 -13
  43. package/src/e2ee/events.ts +48 -0
  44. package/src/e2ee/index.ts +1 -0
  45. package/src/e2ee/types.ts +19 -41
  46. package/src/e2ee/worker/FrameCryptor.ts +51 -43
  47. package/src/e2ee/worker/ParticipantKeyHandler.ts +25 -27
  48. package/src/e2ee/worker/e2ee.worker.ts +61 -68
  49. package/src/room/PCTransport.ts +12 -2
  50. package/src/room/RTCEngine.ts +0 -1
  51. package/src/room/Room.ts +20 -15
  52. package/src/room/participant/LocalParticipant.ts +5 -1
  53. package/src/room/track/LocalTrack.ts +18 -10
  54. package/src/room/track/facingMode.ts +1 -1
  55. package/src/room/track/processor/types.ts +2 -1
@@ -13,8 +13,8 @@ import type { Track } from '../room/track/Track';
13
13
  import type { VideoCodec } from '../room/track/options';
14
14
  import type { BaseKeyProvider } from './KeyProvider';
15
15
  import { E2EE_FLAG } from './constants';
16
+ import { type E2EEManagerCallbacks, EncryptionEvent, KeyProviderEvent } from './events';
16
17
  import type {
17
- E2EEManagerCallbacks,
18
18
  E2EEOptions,
19
19
  E2EEWorkerMessage,
20
20
  EnableMessage,
@@ -28,7 +28,6 @@ import type {
28
28
  SifTrailerMessage,
29
29
  UpdateCodecMessage,
30
30
  } from './types';
31
- import { EncryptionEvent } from './types';
32
31
  import { isE2EESupported, isScriptTransformSupported, mimeTypeToVideoCodecString } from './utils';
33
32
 
34
33
  /**
@@ -43,10 +42,6 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
43
42
 
44
43
  private keyProvider: BaseKeyProvider;
45
44
 
46
- get isEnabled() {
47
- return this.encryptionEnabled;
48
- }
49
-
50
45
  constructor(options: E2EEOptions) {
51
46
  super();
52
47
  this.keyProvider = options.keyProvider;
@@ -86,18 +81,9 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
86
81
  /**
87
82
  * @internal
88
83
  */
89
- async setParticipantCryptorEnabled(enabled: boolean, participantId?: string) {
90
- log.info(`set e2ee to ${enabled}`);
91
-
92
- if (this.worker) {
93
- const enableMsg: EnableMessage = {
94
- kind: 'enable',
95
- data: { enabled, participantId },
96
- };
97
- this.worker.postMessage(enableMsg);
98
- } else {
99
- throw new ReferenceError('failed to enable e2ee, worker is not ready');
100
- }
84
+ setParticipantCryptorEnabled(enabled: boolean, participantIdentity: string) {
85
+ log.debug(`set e2ee to ${enabled} for participant ${participantIdentity}`);
86
+ this.postEnable(enabled, participantIdentity);
101
87
  }
102
88
 
103
89
  /**
@@ -115,19 +101,35 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
115
101
  const { kind, data } = ev.data;
116
102
  switch (kind) {
117
103
  case 'error':
118
- console.error('error in worker', { data });
119
- this.emit(EncryptionEvent.Error, data.error);
104
+ log.error(data.error.message);
105
+ this.emit(EncryptionEvent.EncryptionError, data.error);
106
+ break;
107
+ case 'initAck':
108
+ if (data.enabled) {
109
+ this.keyProvider.getKeys().forEach((keyInfo) => {
110
+ this.postKey(keyInfo);
111
+ });
112
+ }
120
113
  break;
114
+
121
115
  case 'enable':
122
- if (this.encryptionEnabled !== data.enabled && !data.participantId) {
116
+ if (
117
+ this.encryptionEnabled !== data.enabled &&
118
+ data.participantIdentity === this.room?.localParticipant.identity
119
+ ) {
123
120
  this.emit(
124
121
  EncryptionEvent.ParticipantEncryptionStatusChanged,
125
122
  data.enabled,
126
- this.room?.localParticipant,
123
+ this.room!.localParticipant,
127
124
  );
128
125
  this.encryptionEnabled = data.enabled;
129
- } else if (data.participantId) {
130
- const participant = this.room?.getParticipantByIdentity(data.participantId);
126
+ } else if (data.participantIdentity) {
127
+ const participant = this.room?.getParticipantByIdentity(data.participantIdentity);
128
+ if (!participant) {
129
+ throw TypeError(
130
+ `couldn't set encryption status, participant not found${data.participantIdentity}`,
131
+ );
132
+ }
131
133
  this.emit(EncryptionEvent.ParticipantEncryptionStatusChanged, data.enabled, participant);
132
134
  }
133
135
  if (this.encryptionEnabled) {
@@ -137,7 +139,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
137
139
  }
138
140
  break;
139
141
  case 'ratchetKey':
140
- this.keyProvider.emit('keyRatcheted', data.material, data.keyIndex);
142
+ this.keyProvider.emit(KeyProviderEvent.KeyRatcheted, data.material, data.keyIndex);
141
143
  break;
142
144
  default:
143
145
  break;
@@ -146,7 +148,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
146
148
 
147
149
  private onWorkerError = (ev: ErrorEvent) => {
148
150
  log.error('e2ee worker encountered an error:', { error: ev.error });
149
- this.emit(EncryptionEvent.Error, ev.error);
151
+ this.emit(EncryptionEvent.EncryptionError, ev.error);
150
152
  };
151
153
 
152
154
  public setupEngine(engine: RTCEngine) {
@@ -162,69 +164,78 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
162
164
  participant.identity,
163
165
  ),
164
166
  );
165
- room.on(RoomEvent.ConnectionStateChanged, (state) => {
166
- if (state === ConnectionState.Connected) {
167
- room.participants.forEach((participant) => {
168
- participant.tracks.forEach((pub) => {
169
- this.setParticipantCryptorEnabled(
170
- pub.trackInfo!.encryption !== Encryption_Type.NONE,
171
- participant.identity,
172
- );
167
+ room
168
+ .on(RoomEvent.ConnectionStateChanged, (state) => {
169
+ if (state === ConnectionState.Connected) {
170
+ room.participants.forEach((participant) => {
171
+ participant.tracks.forEach((pub) => {
172
+ this.setParticipantCryptorEnabled(
173
+ pub.trackInfo!.encryption !== Encryption_Type.NONE,
174
+ participant.identity,
175
+ );
176
+ });
173
177
  });
178
+ }
179
+ })
180
+ .on(RoomEvent.TrackUnsubscribed, (track, _, participant) => {
181
+ const msg: RemoveTransformMessage = {
182
+ kind: 'removeTransform',
183
+ data: {
184
+ participantIdentity: participant.identity,
185
+ trackId: track.mediaStreamID,
186
+ },
187
+ };
188
+ this.worker?.postMessage(msg);
189
+ })
190
+ .on(RoomEvent.TrackSubscribed, (track, pub, participant) => {
191
+ this.setupE2EEReceiver(track, participant.identity, pub.trackInfo);
192
+ })
193
+ .on(RoomEvent.SignalConnected, () => {
194
+ if (!this.room) {
195
+ throw new TypeError(`expected room to be present on signal connect`);
196
+ }
197
+ this.setParticipantCryptorEnabled(
198
+ this.room.localParticipant.isE2EEEnabled,
199
+ this.room.localParticipant.identity,
200
+ );
201
+ keyProvider.getKeys().forEach((keyInfo) => {
202
+ this.postKey(keyInfo);
174
203
  });
175
- }
176
- });
177
-
178
- room.on(RoomEvent.TrackUnsubscribed, (track, _, participant) => {
179
- const msg: RemoveTransformMessage = {
180
- kind: 'removeTransform',
181
- data: {
182
- participantId: participant.identity,
183
- trackId: track.mediaStreamID,
184
- },
185
- };
186
- this.worker?.postMessage(msg);
187
- });
188
- room.on(RoomEvent.TrackSubscribed, (track, pub, participant) => {
189
- this.setupE2EEReceiver(track, participant.identity, pub.trackInfo);
190
- });
204
+ });
191
205
  room.localParticipant.on(ParticipantEvent.LocalTrackPublished, async (publication) => {
192
- this.setupE2EESender(
193
- publication.track!,
194
- publication.track!.sender!,
195
- room.localParticipant.identity,
196
- );
206
+ this.setupE2EESender(publication.track!, publication.track!.sender!);
197
207
  });
198
208
 
199
209
  keyProvider
200
- .on('setKey', (keyInfo) => this.postKey(keyInfo))
201
- .on('ratchetRequest', (participantId, keyIndex) =>
210
+ .on(KeyProviderEvent.SetKey, (keyInfo) => this.postKey(keyInfo))
211
+ .on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) =>
202
212
  this.postRatchetRequest(participantId, keyIndex),
203
213
  );
204
214
  }
205
215
 
206
- private postRatchetRequest(participantId?: string, keyIndex?: number) {
216
+ private postRatchetRequest(participantIdentity?: string, keyIndex?: number) {
207
217
  if (!this.worker) {
208
218
  throw Error('could not ratchet key, worker is missing');
209
219
  }
210
220
  const msg: RatchetRequestMessage = {
211
221
  kind: 'ratchetRequest',
212
222
  data: {
213
- participantId,
223
+ participantIdentity: participantIdentity,
214
224
  keyIndex,
215
225
  },
216
226
  };
217
227
  this.worker.postMessage(msg);
218
228
  }
219
229
 
220
- private postKey({ key, participantId, keyIndex }: KeyInfo) {
230
+ private postKey({ key, participantIdentity, keyIndex }: KeyInfo) {
221
231
  if (!this.worker) {
222
232
  throw Error('could not set key, worker is missing');
223
233
  }
224
234
  const msg: SetKeyMessage = {
225
235
  kind: 'setKey',
226
236
  data: {
227
- participantId,
237
+ participantIdentity: participantIdentity,
238
+ isPublisher: participantIdentity === this.room?.localParticipant.identity,
228
239
  key,
229
240
  keyIndex,
230
241
  },
@@ -232,14 +243,33 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
232
243
  this.worker.postMessage(msg);
233
244
  }
234
245
 
246
+ private postEnable(enabled: boolean, participantIdentity: string) {
247
+ if (this.worker) {
248
+ const enableMsg: EnableMessage = {
249
+ kind: 'enable',
250
+ data: {
251
+ enabled,
252
+ participantIdentity,
253
+ },
254
+ };
255
+ this.worker.postMessage(enableMsg);
256
+ } else {
257
+ throw new ReferenceError('failed to enable e2ee, worker is not ready');
258
+ }
259
+ }
260
+
235
261
  private postRTPMap(map: Map<number, VideoCodec>) {
236
262
  if (!this.worker) {
237
- throw Error('could not post rtp map, worker is missing');
263
+ throw TypeError('could not post rtp map, worker is missing');
264
+ }
265
+ if (!this.room?.localParticipant.identity) {
266
+ throw TypeError('could not post rtp map, local participant identity is missing');
238
267
  }
239
268
  const msg: RTPVideoMapMessage = {
240
269
  kind: 'setRTPMap',
241
270
  data: {
242
271
  map,
272
+ participantIdentity: this.room.localParticipant.identity,
243
273
  },
244
274
  };
245
275
  this.worker.postMessage(msg);
@@ -273,12 +303,12 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
273
303
  );
274
304
  }
275
305
 
276
- private setupE2EESender(track: Track, sender: RTCRtpSender, localId: string) {
306
+ private setupE2EESender(track: Track, sender: RTCRtpSender) {
277
307
  if (!(track instanceof LocalTrack) || !sender) {
278
308
  if (!sender) log.warn('early return because sender is not ready');
279
309
  return;
280
310
  }
281
- this.handleSender(sender, track.mediaStreamID, localId, undefined);
311
+ this.handleSender(sender, track.mediaStreamID, undefined);
282
312
  }
283
313
 
284
314
  /**
@@ -289,7 +319,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
289
319
  private async handleReceiver(
290
320
  receiver: RTCRtpReceiver,
291
321
  trackId: string,
292
- participantId: string,
322
+ participantIdentity: string,
293
323
  codec?: VideoCodec,
294
324
  ) {
295
325
  if (!this.worker) {
@@ -299,7 +329,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
299
329
  if (isScriptTransformSupported()) {
300
330
  const options = {
301
331
  kind: 'decode',
302
- participantId,
332
+ participantIdentity,
303
333
  trackId,
304
334
  codec,
305
335
  };
@@ -313,7 +343,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
313
343
  data: {
314
344
  trackId,
315
345
  codec,
316
- participantId,
346
+ participantIdentity: participantIdentity,
317
347
  },
318
348
  };
319
349
  this.worker.postMessage(msg);
@@ -341,7 +371,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
341
371
  writableStream: writable,
342
372
  trackId: trackId,
343
373
  codec,
344
- participantId,
374
+ participantIdentity: participantIdentity,
345
375
  },
346
376
  };
347
377
  this.worker.postMessage(msg, [readable, writable]);
@@ -356,22 +386,20 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
356
386
  * a frame encoder.
357
387
  *
358
388
  */
359
- private handleSender(
360
- sender: RTCRtpSender,
361
- trackId: string,
362
- participantId: string,
363
- codec?: VideoCodec,
364
- ) {
389
+ private handleSender(sender: RTCRtpSender, trackId: string, codec?: VideoCodec) {
365
390
  if (E2EE_FLAG in sender || !this.worker) {
366
391
  return;
367
392
  }
368
393
 
394
+ if (!this.room?.localParticipant.identity || this.room.localParticipant.identity === '') {
395
+ throw TypeError('local identity needs to be known in order to set up encrypted sender');
396
+ }
397
+
369
398
  if (isScriptTransformSupported()) {
370
399
  log.info('initialize script transform');
371
-
372
400
  const options = {
373
401
  kind: 'encode',
374
- participantId,
402
+ participantIdentity: this.room.localParticipant.identity,
375
403
  trackId,
376
404
  codec,
377
405
  };
@@ -388,7 +416,7 @@ export class E2EEManager extends (EventEmitter as new () => TypedEventEmitter<E2
388
416
  writableStream: senderStreams.writable,
389
417
  codec,
390
418
  trackId,
391
- participantId,
419
+ participantIdentity: this.room.localParticipant.identity,
392
420
  },
393
421
  };
394
422
  this.worker.postMessage(msg, [senderStreams.readable, senderStreams.writable]);
@@ -1,7 +1,9 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import type TypedEventEmitter from 'typed-emitter';
3
+ import log from '../logger';
3
4
  import { KEY_PROVIDER_DEFAULTS } from './constants';
4
- import type { KeyInfo, KeyProviderCallbacks, KeyProviderOptions } from './types';
5
+ import { type KeyProviderCallbacks, KeyProviderEvent } from './events';
6
+ import type { KeyInfo, KeyProviderOptions } from './types';
5
7
  import { createKeyMaterialFromBuffer, createKeyMaterialFromString } from './utils';
6
8
 
7
9
  /**
@@ -16,29 +18,29 @@ export class BaseKeyProvider extends (EventEmitter as new () => TypedEventEmitte
16
18
  super();
17
19
  this.keyInfoMap = new Map();
18
20
  this.options = { ...KEY_PROVIDER_DEFAULTS, ...options };
19
- this.on('keyRatcheted', this.onKeyRatcheted);
21
+ this.on(KeyProviderEvent.KeyRatcheted, this.onKeyRatcheted);
20
22
  }
21
23
 
22
24
  /**
23
25
  * callback to invoke once a key has been set for a participant
24
26
  * @param key
25
- * @param participantId
27
+ * @param participantIdentity
26
28
  * @param keyIndex
27
29
  */
28
- protected onSetEncryptionKey(key: CryptoKey, participantId?: string, keyIndex?: number) {
29
- const keyInfo: KeyInfo = { key, participantId, keyIndex };
30
- this.keyInfoMap.set(`${participantId ?? 'shared'}-${keyIndex ?? 0}`, keyInfo);
31
- this.emit('setKey', keyInfo);
30
+ protected onSetEncryptionKey(key: CryptoKey, participantIdentity?: string, keyIndex?: number) {
31
+ const keyInfo: KeyInfo = { key, participantIdentity, keyIndex };
32
+ this.keyInfoMap.set(`${participantIdentity ?? 'shared'}-${keyIndex ?? 0}`, keyInfo);
33
+ this.emit(KeyProviderEvent.SetKey, keyInfo);
32
34
  }
33
35
 
34
36
  /**
35
- * callback being invoked after a ratchet request has been performed on the local participant
37
+ * callback being invoked after a ratchet request has been performed on a participant
36
38
  * that surfaces the new key material.
37
39
  * @param material
38
40
  * @param keyIndex
39
41
  */
40
42
  protected onKeyRatcheted = (material: CryptoKey, keyIndex?: number) => {
41
- console.debug('key ratcheted event received', material, keyIndex);
43
+ log.debug('key ratcheted event received', { material, keyIndex });
42
44
  };
43
45
 
44
46
  getKeys() {
@@ -49,8 +51,8 @@ export class BaseKeyProvider extends (EventEmitter as new () => TypedEventEmitte
49
51
  return this.options;
50
52
  }
51
53
 
52
- ratchetKey(participantId?: string, keyIndex?: number) {
53
- this.emit('ratchetRequest', participantId, keyIndex);
54
+ ratchetKey(participantIdentity?: string, keyIndex?: number) {
55
+ this.emit(KeyProviderEvent.RatchetRequest, participantIdentity, keyIndex);
54
56
  }
55
57
  }
56
58
 
@@ -63,14 +65,22 @@ export class ExternalE2EEKeyProvider extends BaseKeyProvider {
63
65
  ratchetInterval: number | undefined;
64
66
 
65
67
  constructor(options: Partial<Omit<KeyProviderOptions, 'sharedKey'>> = {}) {
66
- const opts: Partial<KeyProviderOptions> = { ...options, sharedKey: true };
68
+ const opts: Partial<KeyProviderOptions> = {
69
+ ...options,
70
+ sharedKey: true,
71
+ // for a shared key provider failing to decrypt for a specific participant
72
+ // should not mark the key as invalid, so we accept wrong keys forever
73
+ // and won't try to auto-ratchet
74
+ ratchetWindowSize: 0,
75
+ failureTolerance: -1,
76
+ };
67
77
  super(opts);
68
78
  }
69
79
 
70
80
  /**
71
81
  * Accepts a passphrase that's used to create the crypto keys.
72
82
  * When passing in a string, PBKDF2 is used.
73
- * Also accepts an Array buffer of cryptographically random numbers that uses HKDF.
83
+ * When passing in an Array buffer of cryptographically random numbers, HKDF is being used. (recommended)
74
84
  * @param key
75
85
  */
76
86
  async setKey(key: string | ArrayBuffer) {
@@ -0,0 +1,48 @@
1
+ import type Participant from '../room/participant/Participant';
2
+ import type { CryptorError } from './errors';
3
+ import type { KeyInfo } from './types';
4
+
5
+ export enum KeyProviderEvent {
6
+ SetKey = 'setKey',
7
+ RatchetRequest = 'ratchetRequest',
8
+ KeyRatcheted = 'keyRatcheted',
9
+ }
10
+
11
+ export type KeyProviderCallbacks = {
12
+ [KeyProviderEvent.SetKey]: (keyInfo: KeyInfo) => void;
13
+ [KeyProviderEvent.RatchetRequest]: (participantIdentity?: string, keyIndex?: number) => void;
14
+ [KeyProviderEvent.KeyRatcheted]: (material: CryptoKey, keyIndex?: number) => void;
15
+ };
16
+
17
+ export enum KeyHandlerEvent {
18
+ KeyRatcheted = 'keyRatcheted',
19
+ }
20
+
21
+ export type ParticipantKeyHandlerCallbacks = {
22
+ [KeyHandlerEvent.KeyRatcheted]: (
23
+ material: CryptoKey,
24
+ participantIdentity: string,
25
+ keyIndex?: number,
26
+ ) => void;
27
+ };
28
+
29
+ export enum EncryptionEvent {
30
+ ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',
31
+ EncryptionError = 'encryptionError',
32
+ }
33
+
34
+ export type E2EEManagerCallbacks = {
35
+ [EncryptionEvent.ParticipantEncryptionStatusChanged]: (
36
+ enabled: boolean,
37
+ participant: Participant,
38
+ ) => void;
39
+ [EncryptionEvent.EncryptionError]: (error: Error) => void;
40
+ };
41
+
42
+ export type CryptorCallbacks = {
43
+ [CryptorEvent.Error]: (error: CryptorError) => void;
44
+ };
45
+
46
+ export enum CryptorEvent {
47
+ Error = 'cryptorError',
48
+ }
package/src/e2ee/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './KeyProvider';
2
2
  export * from './utils';
3
3
  export * from './types';
4
+ export * from './events';
package/src/e2ee/types.ts CHANGED
@@ -1,7 +1,5 @@
1
- import type Participant from '../room/participant/Participant';
2
1
  import type { VideoCodec } from '../room/track/options';
3
2
  import type { BaseKeyProvider } from './KeyProvider';
4
- import type { CryptorError } from './errors';
5
3
 
6
4
  export interface BaseMessage {
7
5
  kind: string;
@@ -18,7 +16,8 @@ export interface InitMessage extends BaseMessage {
18
16
  export interface SetKeyMessage extends BaseMessage {
19
17
  kind: 'setKey';
20
18
  data: {
21
- participantId?: string;
19
+ participantIdentity?: string;
20
+ isPublisher: boolean;
22
21
  key: CryptoKey;
23
22
  keyIndex?: number;
24
23
  };
@@ -28,6 +27,7 @@ export interface RTPVideoMapMessage extends BaseMessage {
28
27
  kind: 'setRTPMap';
29
28
  data: {
30
29
  map: Map<number, VideoCodec>;
30
+ participantIdentity: string;
31
31
  };
32
32
  }
33
33
 
@@ -41,7 +41,7 @@ export interface SifTrailerMessage extends BaseMessage {
41
41
  export interface EncodeMessage extends BaseMessage {
42
42
  kind: 'decode' | 'encode';
43
43
  data: {
44
- participantId: string;
44
+ participantIdentity: string;
45
45
  readableStream: ReadableStream;
46
46
  writableStream: WritableStream;
47
47
  trackId: string;
@@ -52,7 +52,7 @@ export interface EncodeMessage extends BaseMessage {
52
52
  export interface RemoveTransformMessage extends BaseMessage {
53
53
  kind: 'removeTransform';
54
54
  data: {
55
- participantId: string;
55
+ participantIdentity: string;
56
56
  trackId: string;
57
57
  };
58
58
  }
@@ -60,7 +60,7 @@ export interface RemoveTransformMessage extends BaseMessage {
60
60
  export interface UpdateCodecMessage extends BaseMessage {
61
61
  kind: 'updateCodec';
62
62
  data: {
63
- participantId: string;
63
+ participantIdentity: string;
64
64
  trackId: string;
65
65
  codec: VideoCodec;
66
66
  };
@@ -69,7 +69,7 @@ export interface UpdateCodecMessage extends BaseMessage {
69
69
  export interface RatchetRequestMessage extends BaseMessage {
70
70
  kind: 'ratchetRequest';
71
71
  data: {
72
- participantId: string | undefined;
72
+ participantIdentity?: string;
73
73
  keyIndex?: number;
74
74
  };
75
75
  }
@@ -77,7 +77,7 @@ export interface RatchetRequestMessage extends BaseMessage {
77
77
  export interface RatchetMessage extends BaseMessage {
78
78
  kind: 'ratchetKey';
79
79
  data: {
80
- // participantId: string | undefined;
80
+ participantIdentity: string;
81
81
  keyIndex?: number;
82
82
  material: CryptoKey;
83
83
  };
@@ -93,8 +93,14 @@ export interface ErrorMessage extends BaseMessage {
93
93
  export interface EnableMessage extends BaseMessage {
94
94
  kind: 'enable';
95
95
  data: {
96
- // if no participant id is set it indicates publisher encryption enable/disable
97
- participantId?: string;
96
+ participantIdentity: string;
97
+ enabled: boolean;
98
+ };
99
+ }
100
+
101
+ export interface InitAck extends BaseMessage {
102
+ kind: 'initAck';
103
+ data: {
98
104
  enabled: boolean;
99
105
  };
100
106
  }
@@ -110,7 +116,8 @@ export type E2EEWorkerMessage =
110
116
  | UpdateCodecMessage
111
117
  | RatchetRequestMessage
112
118
  | RatchetMessage
113
- | SifTrailerMessage;
119
+ | SifTrailerMessage
120
+ | InitAck;
114
121
 
115
122
  export type KeySet = { material: CryptoKey; encryptionKey: CryptoKey };
116
123
 
@@ -121,38 +128,9 @@ export type KeyProviderOptions = {
121
128
  failureTolerance: number;
122
129
  };
123
130
 
124
- export type KeyProviderCallbacks = {
125
- setKey: (keyInfo: KeyInfo) => void;
126
- ratchetRequest: (participantId?: string, keyIndex?: number) => void;
127
- /** currently only emitted for local participant */
128
- keyRatcheted: (material: CryptoKey, keyIndex?: number) => void;
129
- };
130
-
131
- export type ParticipantKeyHandlerCallbacks = {
132
- keyRatcheted: (material: CryptoKey, keyIndex?: number, participantId?: string) => void;
133
- };
134
-
135
- export type E2EEManagerCallbacks = {
136
- participantEncryptionStatusChanged: (enabled: boolean, participant?: Participant) => void;
137
- encryptionError: (error: Error) => void;
138
- };
139
-
140
- export const EncryptionEvent = {
141
- ParticipantEncryptionStatusChanged: 'participantEncryptionStatusChanged',
142
- Error: 'encryptionError',
143
- } as const;
144
-
145
- export type CryptorCallbacks = {
146
- cryptorError: (error: CryptorError) => void;
147
- };
148
-
149
- export const CryptorEvent = {
150
- Error: 'cryptorError',
151
- } as const;
152
-
153
131
  export type KeyInfo = {
154
132
  key: CryptoKey;
155
- participantId?: string;
133
+ participantIdentity?: string;
156
134
  keyIndex?: number;
157
135
  };
158
136