livekit-client 1.12.0 → 1.12.1

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 (31) hide show
  1. package/README.md +14 -0
  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 +59 -39
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +44 -17
  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/e2ee/worker/FrameCryptor.d.ts +0 -1
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +8 -0
  13. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  14. package/dist/src/room/Room.d.ts.map +1 -1
  15. package/dist/src/room/participant/RemoteParticipant.d.ts +6 -4
  16. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  17. package/dist/src/room/track/create.d.ts.map +1 -1
  18. package/dist/src/utils/browserParser.d.ts +2 -0
  19. package/dist/src/utils/browserParser.d.ts.map +1 -1
  20. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +0 -1
  21. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +8 -0
  22. package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +6 -4
  23. package/dist/ts4.2/src/utils/browserParser.d.ts +2 -0
  24. package/package.json +1 -1
  25. package/src/e2ee/worker/FrameCryptor.ts +12 -14
  26. package/src/e2ee/worker/ParticipantKeyHandler.ts +15 -0
  27. package/src/e2ee/worker/e2ee.worker.ts +12 -6
  28. package/src/room/Room.ts +17 -7
  29. package/src/room/participant/RemoteParticipant.ts +19 -15
  30. package/src/room/track/create.ts +9 -0
  31. package/src/utils/browserParser.ts +5 -0
@@ -1,3 +1,30 @@
1
+ /******************************************************************************
2
+ Copyright (c) Microsoft Corporation.
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
14
+ ***************************************************************************** */
15
+ /* global Reflect, Promise */
16
+
17
+
18
+ function __awaiter(thisArg, _arguments, P, generator) {
19
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20
+ return new (P || (P = Promise))(function (resolve, reject) {
21
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
22
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
23
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
24
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
25
+ });
26
+ }
27
+
1
28
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
29
 
3
30
  function getDefaultExportFromCjs (x) {
@@ -364,33 +391,6 @@ class CryptorError extends LivekitError {
364
391
  }
365
392
  }
366
393
 
367
- /******************************************************************************
368
- Copyright (c) Microsoft Corporation.
369
-
370
- Permission to use, copy, modify, and/or distribute this software for any
371
- purpose with or without fee is hereby granted.
372
-
373
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
374
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
375
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
376
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
377
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
378
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
379
- PERFORMANCE OF THIS SOFTWARE.
380
- ***************************************************************************** */
381
- /* global Reflect, Promise */
382
-
383
-
384
- function __awaiter(thisArg, _arguments, P, generator) {
385
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
386
- return new (P || (P = Promise))(function (resolve, reject) {
387
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
388
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
389
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
390
- step((generator = generator.apply(thisArg, _arguments || [])).next());
391
- });
392
- }
393
-
394
394
  var eventemitter3 = {exports: {}};
395
395
 
396
396
  (function (module) {
@@ -818,7 +818,6 @@ class FrameCryptor extends BaseFrameCryptor {
818
818
  constructor(opts) {
819
819
  var _a;
820
820
  super();
821
- this.isKeyInvalid = false;
822
821
  this.sendCounts = new Map();
823
822
  this.keys = opts.keys;
824
823
  this.participantId = opts.participantId;
@@ -963,19 +962,18 @@ class FrameCryptor extends BaseFrameCryptor {
963
962
  }
964
963
  const data = new Uint8Array(encodedFrame.data);
965
964
  const keyIndex = data[encodedFrame.data.byteLength - 1];
966
- if (this.keys.getKeySet(keyIndex)) {
965
+ if (this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
967
966
  try {
968
967
  const decodedFrame = yield this.decryptFrame(encodedFrame, keyIndex);
969
968
  if (decodedFrame) {
970
969
  return controller.enqueue(decodedFrame);
971
970
  }
972
- this.isKeyInvalid = false;
973
971
  } catch (error) {
974
972
  if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {
975
- if (!this.isKeyInvalid) {
973
+ if (this.keys.hasValidKey) {
976
974
  workerLogger.warn('invalid key');
977
975
  this.emit(CryptorEvent.Error, new CryptorError("invalid key for participant ".concat(this.participantId), CryptorErrorReason.InvalidKey));
978
- this.isKeyInvalid = true;
976
+ this.keys.hasValidKey = false;
979
977
  }
980
978
  } else {
981
979
  workerLogger.warn('decoding frame failed', {
@@ -983,8 +981,6 @@ class FrameCryptor extends BaseFrameCryptor {
983
981
  });
984
982
  }
985
983
  }
986
- } else {
987
- this.emit(CryptorEvent.Error, new CryptorError("key missing for participant ".concat(this.participantId), CryptorErrorReason.MissingKey));
988
984
  }
989
985
  return controller.enqueue(encodedFrame);
990
986
  });
@@ -1058,7 +1054,9 @@ class FrameCryptor extends BaseFrameCryptor {
1058
1054
  workerLogger.debug('resetting to initial material');
1059
1055
  this.keys.setKeyFromMaterial(initialMaterial.material, keyIndex);
1060
1056
  }
1057
+ this.keys.hasValidKey = false;
1061
1058
  workerLogger.warn('maximum ratchet attempts exceeded, resetting key');
1059
+ this.emit(CryptorEvent.Error, new CryptorError("valid key missing for participant ".concat(this.participantId), CryptorErrorReason.MissingKey));
1062
1060
  }
1063
1061
  } else {
1064
1062
  throw new CryptorError('Decryption failed, most likely because of an invalid key', CryptorErrorReason.InvalidKey);
@@ -1253,6 +1251,7 @@ class ParticipantKeyHandler extends EventEmitter {
1253
1251
  this.keyProviderOptions = keyProviderOptions;
1254
1252
  this.ratchetPromiseMap = new Map();
1255
1253
  this.participantId = participantId;
1254
+ this.hasValidKey = false;
1256
1255
  }
1257
1256
  setEnabled(enabled) {
1258
1257
  this.enabled = enabled;
@@ -1289,6 +1288,19 @@ class ParticipantKeyHandler extends EventEmitter {
1289
1288
  this.ratchetPromiseMap.set(currentKeyIndex, ratchetPromise);
1290
1289
  return ratchetPromise;
1291
1290
  }
1291
+ /**
1292
+ * takes in a key material with `deriveBits` and `deriveKey` set as key usages
1293
+ * and derives encryption keys from the material and sets it on the key ring buffer
1294
+ * together with the material
1295
+ * also resets the valid key property and updates the currentKeyIndex
1296
+ */
1297
+ setKey(material) {
1298
+ let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1299
+ return __awaiter(this, void 0, void 0, function* () {
1300
+ yield this.setKeyFromMaterial(material, keyIndex);
1301
+ this.hasValidKey = true;
1302
+ });
1303
+ }
1292
1304
  /**
1293
1305
  * takes in a key material with `deriveBits` and `deriveKey` set as key usages
1294
1306
  * and derives encryption keys from the material and sets it on the key ring buffer
@@ -1319,6 +1331,7 @@ class ParticipantKeyHandler extends EventEmitter {
1319
1331
  setCurrentKeyIndex(index) {
1320
1332
  return __awaiter(this, void 0, void 0, function* () {
1321
1333
  this.currentKeyIndex = index % this.cryptoKeyRing.length;
1334
+ this.hasValidKey = true;
1322
1335
  });
1323
1336
  }
1324
1337
  isEnabled() {
@@ -1386,7 +1399,7 @@ onmessage = ev => {
1386
1399
  workerLogger.debug('set shared key');
1387
1400
  setSharedKey(data.key, data.keyIndex);
1388
1401
  } else if (data.participantId) {
1389
- getParticipantKeyHandler(data.participantId).setKeyFromMaterial(data.key, data.keyIndex);
1402
+ getParticipantKeyHandler(data.participantId).setKey(data.key, data.keyIndex);
1390
1403
  } else {
1391
1404
  workerLogger.error('no participant Id was provided and shared key usage is disabled');
1392
1405
  }
@@ -1403,9 +1416,16 @@ onmessage = ev => {
1403
1416
  });
1404
1417
  break;
1405
1418
  case 'ratchetRequest':
1406
- getParticipantKeyHandler(data.participantId).ratchetKey(data.keyIndex);
1419
+ handleRatchetRequest(data);
1407
1420
  }
1408
1421
  };
1422
+ function handleRatchetRequest(data) {
1423
+ return __awaiter(this, void 0, void 0, function* () {
1424
+ const keyHandler = getParticipantKeyHandler(data.participantId);
1425
+ yield keyHandler.ratchetKey(data.keyIndex);
1426
+ keyHandler.hasValidKey = true;
1427
+ });
1428
+ }
1409
1429
  function getTrackCryptor(participantId, trackId) {
1410
1430
  let cryptor = participantCryptors.find(c => c.getTrackId() === trackId);
1411
1431
  if (!cryptor) {
@@ -1436,7 +1456,7 @@ function getParticipantKeyHandler(participantId) {
1436
1456
  if (!keys) {
1437
1457
  keys = new ParticipantKeyHandler(participantId, true, keyProviderOptions);
1438
1458
  if (sharedKey) {
1439
- keys.setKeyFromMaterial(sharedKey);
1459
+ keys.setKey(sharedKey);
1440
1460
  }
1441
1461
  participantKeys.set(participantId, keys);
1442
1462
  }
@@ -1473,9 +1493,9 @@ function setEncryptionEnabled(enable, participantId) {
1473
1493
  function setSharedKey(key, index) {
1474
1494
  workerLogger.debug('setting shared key');
1475
1495
  sharedKey = key;
1476
- publisherKeys === null || publisherKeys === void 0 ? void 0 : publisherKeys.setKeyFromMaterial(key, index);
1496
+ publisherKeys === null || publisherKeys === void 0 ? void 0 : publisherKeys.setKey(key, index);
1477
1497
  for (const [, keyHandler] of participantKeys) {
1478
- keyHandler.setKeyFromMaterial(key, index);
1498
+ keyHandler.setKey(key, index);
1479
1499
  }
1480
1500
  }
1481
1501
  function setupCryptorErrorEvents(cryptor) {