livekit-client 1.12.0 → 1.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. package/README.md +19 -1
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +442 -334
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +12303 -14499
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/api/SignalClient.d.ts +2 -2
  11. package/dist/src/api/SignalClient.d.ts.map +1 -1
  12. package/dist/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  13. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  14. package/dist/src/connectionHelper/checks/Checker.d.ts +3 -2
  15. package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
  16. package/dist/src/connectionHelper/checks/webrtc.d.ts.map +1 -1
  17. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
  18. package/dist/src/e2ee/E2eeManager.d.ts +4 -2
  19. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  20. package/dist/src/e2ee/KeyProvider.d.ts +4 -2
  21. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  22. package/dist/src/e2ee/constants.d.ts +1 -0
  23. package/dist/src/e2ee/constants.d.ts.map +1 -1
  24. package/dist/src/e2ee/types.d.ts +1 -0
  25. package/dist/src/e2ee/types.d.ts.map +1 -1
  26. package/dist/src/e2ee/worker/FrameCryptor.d.ts +4 -3
  27. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  28. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +21 -2
  29. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  30. package/dist/src/index.d.ts +1 -1
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/proto/livekit_models_pb.d.ts +1264 -0
  33. package/dist/src/proto/livekit_models_pb.d.ts.map +1 -0
  34. package/dist/src/proto/livekit_rtc_pb.d.ts +1373 -0
  35. package/dist/src/proto/livekit_rtc_pb.d.ts.map +1 -0
  36. package/dist/src/room/PCTransport.d.ts +2 -1
  37. package/dist/src/room/PCTransport.d.ts.map +1 -1
  38. package/dist/src/room/RTCEngine.d.ts +9 -5
  39. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  40. package/dist/src/room/RegionUrlProvider.d.ts +4 -1
  41. package/dist/src/room/RegionUrlProvider.d.ts.map +1 -1
  42. package/dist/src/room/Room.d.ts +15 -11
  43. package/dist/src/room/Room.d.ts.map +1 -1
  44. package/dist/src/room/participant/LocalParticipant.d.ts +2 -2
  45. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  46. package/dist/src/room/participant/Participant.d.ts +5 -3
  47. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  48. package/dist/src/room/participant/ParticipantTrackPermission.d.ts +1 -1
  49. package/dist/src/room/participant/ParticipantTrackPermission.d.ts.map +1 -1
  50. package/dist/src/room/participant/RemoteParticipant.d.ts +8 -7
  51. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  52. package/dist/src/room/timers.d.ts +5 -4
  53. package/dist/src/room/timers.d.ts.map +1 -1
  54. package/dist/src/room/track/LocalTrack.d.ts +3 -0
  55. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  56. package/dist/src/room/track/LocalTrackPublication.d.ts +1 -1
  57. package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
  58. package/dist/src/room/track/LocalVideoTrack.d.ts +2 -2
  59. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  60. package/dist/src/room/track/RemoteTrackPublication.d.ts +1 -1
  61. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  62. package/dist/src/room/track/Track.d.ts +6 -4
  63. package/dist/src/room/track/Track.d.ts.map +1 -1
  64. package/dist/src/room/track/TrackPublication.d.ts +7 -5
  65. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  66. package/dist/src/room/track/create.d.ts.map +1 -1
  67. package/dist/src/room/track/options.d.ts +7 -0
  68. package/dist/src/room/track/options.d.ts.map +1 -1
  69. package/dist/src/room/track/utils.d.ts +5 -1
  70. package/dist/src/room/track/utils.d.ts.map +1 -1
  71. package/dist/src/room/utils.d.ts +3 -1
  72. package/dist/src/room/utils.d.ts.map +1 -1
  73. package/dist/src/test/mocks.d.ts +4 -3
  74. package/dist/src/test/mocks.d.ts.map +1 -1
  75. package/dist/src/utils/browserParser.d.ts +2 -0
  76. package/dist/src/utils/browserParser.d.ts.map +1 -1
  77. package/dist/ts4.2/src/api/SignalClient.d.ts +2 -2
  78. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  79. package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +3 -2
  80. package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +4 -2
  81. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +4 -2
  82. package/dist/ts4.2/src/e2ee/constants.d.ts +1 -0
  83. package/dist/ts4.2/src/e2ee/types.d.ts +1 -0
  84. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +4 -3
  85. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +21 -2
  86. package/dist/ts4.2/src/index.d.ts +1 -1
  87. package/dist/ts4.2/src/proto/livekit_models_pb.d.ts +1264 -0
  88. package/dist/ts4.2/src/proto/livekit_rtc_pb.d.ts +1373 -0
  89. package/dist/ts4.2/src/room/PCTransport.d.ts +2 -1
  90. package/dist/ts4.2/src/room/RTCEngine.d.ts +9 -5
  91. package/dist/ts4.2/src/room/RegionUrlProvider.d.ts +4 -1
  92. package/dist/ts4.2/src/room/Room.d.ts +15 -11
  93. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +2 -2
  94. package/dist/ts4.2/src/room/participant/Participant.d.ts +5 -3
  95. package/dist/ts4.2/src/room/participant/ParticipantTrackPermission.d.ts +1 -1
  96. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +8 -7
  97. package/dist/ts4.2/src/room/timers.d.ts +5 -4
  98. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -0
  99. package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +1 -1
  100. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +2 -2
  101. package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +1 -1
  102. package/dist/ts4.2/src/room/track/Track.d.ts +6 -4
  103. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +7 -5
  104. package/dist/ts4.2/src/room/track/options.d.ts +7 -0
  105. package/dist/ts4.2/src/room/track/utils.d.ts +5 -1
  106. package/dist/ts4.2/src/room/utils.d.ts +3 -1
  107. package/dist/ts4.2/src/test/mocks.d.ts +4 -3
  108. package/dist/ts4.2/src/utils/browserParser.d.ts +2 -0
  109. package/package.json +10 -10
  110. package/src/api/SignalClient.ts +104 -101
  111. package/src/connectionHelper/ConnectionCheck.ts +3 -2
  112. package/src/connectionHelper/checks/Checker.ts +3 -3
  113. package/src/connectionHelper/checks/webrtc.ts +66 -2
  114. package/src/connectionHelper/checks/websocket.ts +4 -0
  115. package/src/e2ee/E2eeManager.ts +4 -3
  116. package/src/e2ee/KeyProvider.ts +3 -2
  117. package/src/e2ee/constants.ts +4 -0
  118. package/src/e2ee/types.ts +1 -0
  119. package/src/e2ee/worker/FrameCryptor.test.ts +1 -3
  120. package/src/e2ee/worker/FrameCryptor.ts +14 -16
  121. package/src/e2ee/worker/ParticipantKeyHandler.ts +48 -2
  122. package/src/e2ee/worker/e2ee.worker.ts +12 -6
  123. package/src/index.ts +1 -1
  124. package/src/proto/livekit_models_pb.ts +2096 -0
  125. package/src/proto/livekit_rtc_pb.ts +2332 -0
  126. package/src/room/PCTransport.ts +1 -1
  127. package/src/room/RTCEngine.ts +24 -18
  128. package/src/room/RegionUrlProvider.ts +11 -2
  129. package/src/room/Room.test.ts +1 -0
  130. package/src/room/Room.ts +175 -86
  131. package/src/room/participant/LocalParticipant.ts +43 -59
  132. package/src/room/participant/Participant.ts +6 -4
  133. package/src/room/participant/ParticipantTrackPermission.ts +3 -3
  134. package/src/room/participant/RemoteParticipant.ts +24 -21
  135. package/src/room/participant/publishUtils.test.ts +1 -0
  136. package/src/room/track/LocalTrack.ts +24 -9
  137. package/src/room/track/LocalTrackPublication.ts +1 -1
  138. package/src/room/track/LocalVideoTrack.test.ts +2 -1
  139. package/src/room/track/LocalVideoTrack.ts +22 -22
  140. package/src/room/track/RemoteTrackPublication.ts +12 -7
  141. package/src/room/track/RemoteVideoTrack.test.ts +5 -4
  142. package/src/room/track/Track.ts +9 -6
  143. package/src/room/track/TrackPublication.ts +7 -5
  144. package/src/room/track/create.ts +18 -17
  145. package/src/room/track/facingMode.test.ts +1 -0
  146. package/src/room/track/options.ts +6 -0
  147. package/src/room/track/utils.test.ts +1 -0
  148. package/src/room/track/utils.ts +44 -2
  149. package/src/room/utils.test.ts +16 -0
  150. package/src/room/utils.ts +20 -4
  151. package/src/test/mocks.ts +7 -5
  152. package/src/utils/AsyncQueue.test.ts +1 -0
  153. package/src/utils/browserParser.test.ts +33 -3
  154. package/src/utils/browserParser.ts +5 -0
  155. package/dist/src/proto/google/protobuf/timestamp.d.ts +0 -146
  156. package/dist/src/proto/google/protobuf/timestamp.d.ts.map +0 -1
  157. package/dist/src/proto/livekit_models.d.ts +0 -2399
  158. package/dist/src/proto/livekit_models.d.ts.map +0 -1
  159. package/dist/src/proto/livekit_rtc.d.ts +0 -14352
  160. package/dist/src/proto/livekit_rtc.d.ts.map +0 -1
  161. package/dist/ts4.2/src/proto/google/protobuf/timestamp.d.ts +0 -150
  162. package/dist/ts4.2/src/proto/livekit_models.d.ts +0 -2659
  163. package/dist/ts4.2/src/proto/livekit_rtc.d.ts +0 -15764
  164. package/src/proto/google/protobuf/timestamp.ts +0 -230
  165. package/src/proto/livekit_models.ts +0 -4006
  166. package/src/proto/livekit_rtc.ts +0 -4672
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  // TODO code inspired by https://github.com/webrtc/samples/blob/gh-pages/src/content/insertable-streams/endtoend-encryption/js/worker.js
3
- import EventEmitter from 'eventemitter3';
3
+ import { EventEmitter } from 'events';
4
+ import type TypedEventEmitter from 'typed-emitter';
4
5
  import { workerLogger } from '../../logger';
5
6
  import type { VideoCodec } from '../../room/track/options';
6
7
  import { ENCRYPTION_ALGORITHM, IV_LENGTH, UNENCRYPTED_BYTES } from '../constants';
@@ -26,7 +27,7 @@ export interface TransformerInfo {
26
27
  abortController: AbortController;
27
28
  }
28
29
 
29
- export class BaseFrameCryptor extends EventEmitter<CryptorCallbacks> {
30
+ export class BaseFrameCryptor extends (EventEmitter as new () => TypedEventEmitter<CryptorCallbacks>) {
30
31
  encodeFunction(
31
32
  encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,
32
33
  controller: TransformStreamDefaultController,
@@ -49,8 +50,6 @@ export class BaseFrameCryptor extends EventEmitter<CryptorCallbacks> {
49
50
  export class FrameCryptor extends BaseFrameCryptor {
50
51
  private sendCounts: Map<number, number>;
51
52
 
52
- private isKeyInvalid = false;
53
-
54
53
  private participantId: string | undefined;
55
54
 
56
55
  private trackId: string | undefined;
@@ -270,16 +269,16 @@ export class FrameCryptor extends BaseFrameCryptor {
270
269
  const data = new Uint8Array(encodedFrame.data);
271
270
  const keyIndex = data[encodedFrame.data.byteLength - 1];
272
271
 
273
- if (this.keys.getKeySet(keyIndex)) {
272
+ if (this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
274
273
  try {
275
274
  const decodedFrame = await this.decryptFrame(encodedFrame, keyIndex);
275
+ this.keys.decryptionSuccess();
276
276
  if (decodedFrame) {
277
277
  return controller.enqueue(decodedFrame);
278
278
  }
279
- this.isKeyInvalid = false;
280
279
  } catch (error) {
281
280
  if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {
282
- if (!this.isKeyInvalid) {
281
+ if (this.keys.hasValidKey) {
283
282
  workerLogger.warn('invalid key');
284
283
  this.emit(
285
284
  CryptorEvent.Error,
@@ -288,20 +287,12 @@ export class FrameCryptor extends BaseFrameCryptor {
288
287
  CryptorErrorReason.InvalidKey,
289
288
  ),
290
289
  );
291
- this.isKeyInvalid = true;
290
+ this.keys.decryptionFailure();
292
291
  }
293
292
  } else {
294
293
  workerLogger.warn('decoding frame failed', { error });
295
294
  }
296
295
  }
297
- } else {
298
- this.emit(
299
- CryptorEvent.Error,
300
- new CryptorError(
301
- `key missing for participant ${this.participantId}`,
302
- CryptorErrorReason.MissingKey,
303
- ),
304
- );
305
296
  }
306
297
 
307
298
  return controller.enqueue(encodedFrame);
@@ -407,6 +398,13 @@ export class FrameCryptor extends BaseFrameCryptor {
407
398
  }
408
399
 
409
400
  workerLogger.warn('maximum ratchet attempts exceeded, resetting key');
401
+ this.emit(
402
+ CryptorEvent.Error,
403
+ new CryptorError(
404
+ `valid key missing for participant ${this.participantId}`,
405
+ CryptorErrorReason.MissingKey,
406
+ ),
407
+ );
410
408
  }
411
409
  } else {
412
410
  throw new CryptorError(
@@ -1,4 +1,5 @@
1
- import EventEmitter from 'eventemitter3';
1
+ import { EventEmitter } from 'events';
2
+ import type TypedEventEmitter from 'typed-emitter';
2
3
  import { workerLogger } from '../../logger';
3
4
  import { KEYRING_SIZE } from '../constants';
4
5
  import type { KeyProviderOptions, KeySet, ParticipantKeyHandlerCallbacks } from '../types';
@@ -15,7 +16,7 @@ import { deriveKeys, importKey, ratchet } from '../utils';
15
16
  * if decryption fails or can be triggered manually on both sender and receiver side.
16
17
  *
17
18
  */
18
- export class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCallbacks> {
19
+ export class ParticipantKeyHandler extends (EventEmitter as new () => TypedEventEmitter<ParticipantKeyHandlerCallbacks>) {
19
20
  private currentKeyIndex: number;
20
21
 
21
22
  private cryptoKeyRing: Array<KeySet>;
@@ -28,6 +29,14 @@ export class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCal
28
29
 
29
30
  private participantId: string | undefined;
30
31
 
32
+ private decryptionFailureCount = 0;
33
+
34
+ private _hasValidKey: boolean = true;
35
+
36
+ get hasValidKey() {
37
+ return this._hasValidKey;
38
+ }
39
+
31
40
  constructor(
32
41
  participantId: string | undefined,
33
42
  isEnabled: boolean,
@@ -40,12 +49,37 @@ export class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCal
40
49
  this.keyProviderOptions = keyProviderOptions;
41
50
  this.ratchetPromiseMap = new Map();
42
51
  this.participantId = participantId;
52
+ this.resetKeyStatus();
43
53
  }
44
54
 
45
55
  setEnabled(enabled: boolean) {
46
56
  this.enabled = enabled;
47
57
  }
48
58
 
59
+ decryptionFailure() {
60
+ if (this.keyProviderOptions.failureTolerance < 0) {
61
+ return;
62
+ }
63
+ this.decryptionFailureCount += 1;
64
+
65
+ if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {
66
+ this._hasValidKey = false;
67
+ }
68
+ }
69
+
70
+ decryptionSuccess() {
71
+ this.resetKeyStatus();
72
+ }
73
+
74
+ /**
75
+ * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially
76
+ * invalid keys as valid again
77
+ */
78
+ resetKeyStatus() {
79
+ this.decryptionFailureCount = 0;
80
+ this._hasValidKey = true;
81
+ }
82
+
49
83
  /**
50
84
  * Ratchets the current key (or the one at keyIndex if provided) and
51
85
  * returns the ratcheted material
@@ -84,6 +118,17 @@ export class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCal
84
118
  return ratchetPromise;
85
119
  }
86
120
 
121
+ /**
122
+ * takes in a key material with `deriveBits` and `deriveKey` set as key usages
123
+ * and derives encryption keys from the material and sets it on the key ring buffer
124
+ * together with the material
125
+ * also resets the valid key property and updates the currentKeyIndex
126
+ */
127
+ async setKey(material: CryptoKey, keyIndex = 0) {
128
+ await this.setKeyFromMaterial(material, keyIndex);
129
+ this.resetKeyStatus();
130
+ }
131
+
87
132
  /**
88
133
  * takes in a key material with `deriveBits` and `deriveKey` set as key usages
89
134
  * and derives encryption keys from the material and sets it on the key ring buffer
@@ -108,6 +153,7 @@ export class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCal
108
153
 
109
154
  async setCurrentKeyIndex(index: number) {
110
155
  this.currentKeyIndex = index % this.cryptoKeyRing.length;
156
+ this.resetKeyStatus();
111
157
  }
112
158
 
113
159
  isEnabled() {
@@ -7,6 +7,7 @@ import type {
7
7
  ErrorMessage,
8
8
  KeyProviderOptions,
9
9
  RatchetMessage,
10
+ RatchetRequestMessage,
10
11
  } from '../types';
11
12
  import { FrameCryptor } from './FrameCryptor';
12
13
  import { ParticipantKeyHandler } from './ParticipantKeyHandler';
@@ -75,7 +76,7 @@ onmessage = (ev) => {
75
76
  workerLogger.debug('set shared key');
76
77
  setSharedKey(data.key, data.keyIndex);
77
78
  } else if (data.participantId) {
78
- getParticipantKeyHandler(data.participantId).setKeyFromMaterial(data.key, data.keyIndex);
79
+ getParticipantKeyHandler(data.participantId).setKey(data.key, data.keyIndex);
79
80
  } else {
80
81
  workerLogger.error('no participant Id was provided and shared key usage is disabled');
81
82
  }
@@ -92,13 +93,18 @@ onmessage = (ev) => {
92
93
  });
93
94
  break;
94
95
  case 'ratchetRequest':
95
- getParticipantKeyHandler(data.participantId).ratchetKey(data.keyIndex);
96
-
96
+ handleRatchetRequest(data);
97
97
  default:
98
98
  break;
99
99
  }
100
100
  };
101
101
 
102
+ async function handleRatchetRequest(data: RatchetRequestMessage['data']) {
103
+ const keyHandler = getParticipantKeyHandler(data.participantId);
104
+ await keyHandler.ratchetKey(data.keyIndex);
105
+ keyHandler.resetKeyStatus();
106
+ }
107
+
102
108
  function getTrackCryptor(participantId: string, trackId: string) {
103
109
  let cryptor = participantCryptors.find((c) => c.getTrackId() === trackId);
104
110
  if (!cryptor) {
@@ -131,7 +137,7 @@ function getParticipantKeyHandler(participantId?: string) {
131
137
  if (!keys) {
132
138
  keys = new ParticipantKeyHandler(participantId, true, keyProviderOptions);
133
139
  if (sharedKey) {
134
- keys.setKeyFromMaterial(sharedKey);
140
+ keys.setKey(sharedKey);
135
141
  }
136
142
  participantKeys.set(participantId, keys);
137
143
  }
@@ -171,9 +177,9 @@ function setEncryptionEnabled(enable: boolean, participantId?: string) {
171
177
  function setSharedKey(key: CryptoKey, index?: number) {
172
178
  workerLogger.debug('setting shared key');
173
179
  sharedKey = key;
174
- publisherKeys?.setKeyFromMaterial(key, index);
180
+ publisherKeys?.setKey(key, index);
175
181
  for (const [, keyHandler] of participantKeys) {
176
- keyHandler.setKeyFromMaterial(key, index);
182
+ keyHandler.setKey(key, index);
177
183
  }
178
184
  }
179
185
 
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LogLevel, setLogExtension, setLogLevel } from './logger';
2
- import { DataPacket_Kind, DisconnectReason, VideoQuality } from './proto/livekit_models';
2
+ import { DataPacket_Kind, DisconnectReason, VideoQuality } from './proto/livekit_models_pb';
3
3
  import DefaultReconnectPolicy from './room/DefaultReconnectPolicy';
4
4
  import Room, { ConnectionState, RoomState } from './room/Room';
5
5
  import LocalParticipant from './room/participant/LocalParticipant';