livekit-client 1.13.0 → 1.13.2

Sign up to get free protection for your applications and to get access to all the features.
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