livekit-client 2.5.7 → 2.5.9
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -2
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +53 -20
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +39 -3
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +25 -5
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +3 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +5 -1
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +7 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +25 -5
- package/dist/ts4.2/src/room/Room.d.ts +3 -1
- package/dist/ts4.2/src/room/events.d.ts +5 -1
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +7 -0
- package/package.json +7 -7
- package/src/e2ee/worker/FrameCryptor.test.ts +311 -113
- package/src/e2ee/worker/FrameCryptor.ts +10 -5
- package/src/e2ee/worker/ParticipantKeyHandler.test.ts +169 -5
- package/src/e2ee/worker/ParticipantKeyHandler.ts +50 -20
- package/src/e2ee/worker/__snapshots__/ParticipantKeyHandler.test.ts.snap +356 -0
- package/src/room/Room.ts +8 -0
- package/src/room/events.ts +5 -0
- package/src/room/participant/LocalParticipant.ts +26 -1
- package/src/room/track/LocalTrackPublication.ts +1 -1
@@ -4691,6 +4691,10 @@ var RoomEvent;
|
|
4691
4691
|
* fired when the first remote participant has subscribed to the localParticipant's track
|
4692
4692
|
*/
|
4693
4693
|
RoomEvent["LocalTrackSubscribed"] = "localTrackSubscribed";
|
4694
|
+
/**
|
4695
|
+
* fired when the client receives connection metrics from other participants
|
4696
|
+
*/
|
4697
|
+
RoomEvent["MetricsReceived"] = "metricsReceived";
|
4694
4698
|
})(RoomEvent || (RoomEvent = {}));
|
4695
4699
|
var ParticipantEvent;
|
4696
4700
|
(function (ParticipantEvent) {
|
@@ -5937,10 +5941,14 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
5937
5941
|
}
|
5938
5942
|
const data = new Uint8Array(encodedFrame.data);
|
5939
5943
|
const keyIndex = data[encodedFrame.data.byteLength - 1];
|
5940
|
-
if (this.keys.
|
5944
|
+
if (this.keys.hasInvalidKeyAtIndex(keyIndex)) {
|
5945
|
+
// drop frame
|
5946
|
+
return;
|
5947
|
+
}
|
5948
|
+
if (this.keys.getKeySet(keyIndex)) {
|
5941
5949
|
try {
|
5942
5950
|
const decodedFrame = yield this.decryptFrame(encodedFrame, keyIndex);
|
5943
|
-
this.keys.decryptionSuccess();
|
5951
|
+
this.keys.decryptionSuccess(keyIndex);
|
5944
5952
|
if (decodedFrame) {
|
5945
5953
|
return controller.enqueue(decodedFrame);
|
5946
5954
|
}
|
@@ -5949,7 +5957,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
5949
5957
|
// emit an error if the key handler thinks we have a valid key
|
5950
5958
|
if (this.keys.hasValidKey) {
|
5951
5959
|
this.emit(CryptorEvent.Error, error);
|
5952
|
-
this.keys.decryptionFailure();
|
5960
|
+
this.keys.decryptionFailure(keyIndex);
|
5953
5961
|
}
|
5954
5962
|
} else {
|
5955
5963
|
workerLogger.warn('decoding frame failed', {
|
@@ -5957,11 +5965,11 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
5957
5965
|
});
|
5958
5966
|
}
|
5959
5967
|
}
|
5960
|
-
} else
|
5968
|
+
} else {
|
5961
5969
|
// emit an error if the key index is out of bounds but the key handler thinks we still have a valid key
|
5962
5970
|
workerLogger.warn("skipping decryption due to missing key at index ".concat(keyIndex));
|
5963
5971
|
this.emit(CryptorEvent.Error, new CryptorError("missing key at index ".concat(keyIndex, " for participant ").concat(this.participantIdentity), CryptorErrorReason.MissingKey, this.participantIdentity));
|
5964
|
-
this.keys.decryptionFailure();
|
5972
|
+
this.keys.decryptionFailure(keyIndex);
|
5965
5973
|
}
|
5966
5974
|
});
|
5967
5975
|
}
|
@@ -6255,43 +6263,68 @@ function isFrameServerInjected(frameData, trailerBytes) {
|
|
6255
6263
|
*
|
6256
6264
|
*/
|
6257
6265
|
class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
6266
|
+
/**
|
6267
|
+
* true if the current key has not been marked as invalid
|
6268
|
+
*/
|
6258
6269
|
get hasValidKey() {
|
6259
|
-
return this.
|
6270
|
+
return !this.hasInvalidKeyAtIndex(this.currentKeyIndex);
|
6260
6271
|
}
|
6261
6272
|
constructor(participantIdentity, keyProviderOptions) {
|
6262
6273
|
super();
|
6263
|
-
this.decryptionFailureCount = 0;
|
6264
|
-
this._hasValidKey = true;
|
6265
6274
|
this.currentKeyIndex = 0;
|
6266
6275
|
if (keyProviderOptions.keyringSize < 1 || keyProviderOptions.keyringSize > 256) {
|
6267
6276
|
throw new TypeError('Keyring size needs to be between 1 and 256');
|
6268
6277
|
}
|
6269
6278
|
this.cryptoKeyRing = new Array(keyProviderOptions.keyringSize).fill(undefined);
|
6279
|
+
this.decryptionFailureCounts = new Array(keyProviderOptions.keyringSize).fill(0);
|
6270
6280
|
this.keyProviderOptions = keyProviderOptions;
|
6271
6281
|
this.ratchetPromiseMap = new Map();
|
6272
6282
|
this.participantIdentity = participantIdentity;
|
6273
|
-
this.resetKeyStatus();
|
6274
6283
|
}
|
6284
|
+
/**
|
6285
|
+
* Returns true if the key at the given index is marked as invalid.
|
6286
|
+
*
|
6287
|
+
* @param keyIndex the index of the key
|
6288
|
+
*/
|
6289
|
+
hasInvalidKeyAtIndex(keyIndex) {
|
6290
|
+
return this.keyProviderOptions.failureTolerance >= 0 && this.decryptionFailureCounts[keyIndex] > this.keyProviderOptions.failureTolerance;
|
6291
|
+
}
|
6292
|
+
/**
|
6293
|
+
* Informs the key handler that a decryption failure occurred for an encryption key.
|
6294
|
+
* @internal
|
6295
|
+
* @param keyIndex the key index for which the failure occurred. Defaults to the current key index.
|
6296
|
+
*/
|
6275
6297
|
decryptionFailure() {
|
6298
|
+
let keyIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentKeyIndex;
|
6276
6299
|
if (this.keyProviderOptions.failureTolerance < 0) {
|
6277
6300
|
return;
|
6278
6301
|
}
|
6279
|
-
this.
|
6280
|
-
if (this.
|
6281
|
-
workerLogger.warn("key for ".concat(this.participantIdentity, " is being marked as invalid"));
|
6282
|
-
this._hasValidKey = false;
|
6302
|
+
this.decryptionFailureCounts[keyIndex] += 1;
|
6303
|
+
if (this.decryptionFailureCounts[keyIndex] > this.keyProviderOptions.failureTolerance) {
|
6304
|
+
workerLogger.warn("key for ".concat(this.participantIdentity, " at index ").concat(keyIndex, " is being marked as invalid"));
|
6283
6305
|
}
|
6284
6306
|
}
|
6307
|
+
/**
|
6308
|
+
* Informs the key handler that a frame was successfully decrypted using an encryption key.
|
6309
|
+
* @internal
|
6310
|
+
* @param keyIndex the key index for which the success occurred. Defaults to the current key index.
|
6311
|
+
*/
|
6285
6312
|
decryptionSuccess() {
|
6286
|
-
this.
|
6313
|
+
let keyIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentKeyIndex;
|
6314
|
+
this.resetKeyStatus(keyIndex);
|
6287
6315
|
}
|
6288
6316
|
/**
|
6289
6317
|
* Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially
|
6290
6318
|
* invalid keys as valid again
|
6319
|
+
*
|
6320
|
+
* @param keyIndex the index of the key. Defaults to the current key index.
|
6291
6321
|
*/
|
6292
|
-
resetKeyStatus() {
|
6293
|
-
|
6294
|
-
|
6322
|
+
resetKeyStatus(keyIndex) {
|
6323
|
+
if (keyIndex === undefined) {
|
6324
|
+
this.decryptionFailureCounts.fill(0);
|
6325
|
+
} else {
|
6326
|
+
this.decryptionFailureCounts[keyIndex] = 0;
|
6327
|
+
}
|
6295
6328
|
}
|
6296
6329
|
/**
|
6297
6330
|
* Ratchets the current key (or the one at keyIndex if provided) and
|
@@ -6316,7 +6349,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
6316
6349
|
const currentMaterial = keySet.material;
|
6317
6350
|
const newMaterial = yield importKey(yield ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt), currentMaterial.algorithm.name, 'derive');
|
6318
6351
|
if (setKey) {
|
6319
|
-
this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
|
6352
|
+
yield this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
|
6320
6353
|
this.emit(KeyHandlerEvent.KeyRatcheted, newMaterial, this.participantIdentity, currentKeyIndex);
|
6321
6354
|
}
|
6322
6355
|
resolve(newMaterial);
|
@@ -6341,7 +6374,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
6341
6374
|
let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
6342
6375
|
return function* () {
|
6343
6376
|
yield _this.setKeyFromMaterial(material, keyIndex);
|
6344
|
-
_this.resetKeyStatus();
|
6377
|
+
_this.resetKeyStatus(keyIndex);
|
6345
6378
|
}();
|
6346
6379
|
});
|
6347
6380
|
}
|
@@ -6378,7 +6411,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
6378
6411
|
setCurrentKeyIndex(index) {
|
6379
6412
|
return __awaiter(this, void 0, void 0, function* () {
|
6380
6413
|
this.currentKeyIndex = index % this.cryptoKeyRing.length;
|
6381
|
-
this.resetKeyStatus();
|
6414
|
+
this.resetKeyStatus(index);
|
6382
6415
|
});
|
6383
6416
|
}
|
6384
6417
|
getCurrentKeyIndex() {
|