livekit-client 2.0.2 → 2.0.3

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 (40) 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 +52 -17
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +69 -40
  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/KeyProvider.d.ts +1 -1
  10. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts +1 -0
  12. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  13. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +2 -2
  14. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  15. package/dist/src/room/Room.d.ts +1 -0
  16. package/dist/src/room/Room.d.ts.map +1 -1
  17. package/dist/src/room/events.d.ts +5 -1
  18. package/dist/src/room/events.d.ts.map +1 -1
  19. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  20. package/dist/src/room/track/LocalTrack.d.ts +1 -0
  21. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  22. package/dist/src/room/track/Track.d.ts +2 -0
  23. package/dist/src/room/track/Track.d.ts.map +1 -1
  24. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +1 -1
  25. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +1 -0
  26. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +2 -2
  27. package/dist/ts4.2/src/room/Room.d.ts +1 -0
  28. package/dist/ts4.2/src/room/events.d.ts +5 -1
  29. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
  30. package/dist/ts4.2/src/room/track/Track.d.ts +2 -0
  31. package/package.json +1 -1
  32. package/src/e2ee/KeyProvider.ts +6 -1
  33. package/src/e2ee/worker/FrameCryptor.ts +26 -0
  34. package/src/e2ee/worker/ParticipantKeyHandler.ts +9 -5
  35. package/src/e2ee/worker/e2ee.worker.ts +16 -17
  36. package/src/room/Room.ts +18 -4
  37. package/src/room/events.ts +4 -0
  38. package/src/room/track/LocalAudioTrack.ts +1 -0
  39. package/src/room/track/LocalTrack.ts +42 -33
  40. package/src/room/track/Track.ts +2 -0
@@ -987,6 +987,13 @@ class FrameCryptor extends BaseFrameCryptor {
987
987
  this.sifTrailer = (_a = opts.sifTrailer) !== null && _a !== void 0 ? _a : Uint8Array.from([]);
988
988
  this.sifGuard = new SifGuard();
989
989
  }
990
+ get logContext() {
991
+ return {
992
+ identity: this.participantIdentity,
993
+ trackId: this.trackId,
994
+ fallbackCodec: this.videoCodec
995
+ };
996
+ }
990
997
  /**
991
998
  * Assign a different participant to the cryptor.
992
999
  * useful for transceiver re-use
@@ -999,6 +1006,7 @@ class FrameCryptor extends BaseFrameCryptor {
999
1006
  this.sifGuard.reset();
1000
1007
  }
1001
1008
  unsetParticipant() {
1009
+ workerLogger.debug('unsetting participant', this.logContext);
1002
1010
  this.participantIdentity = undefined;
1003
1011
  }
1004
1012
  isEnabled() {
@@ -1035,6 +1043,11 @@ class FrameCryptor extends BaseFrameCryptor {
1035
1043
  });
1036
1044
  this.videoCodec = codec;
1037
1045
  }
1046
+ workerLogger.debug('Setting up frame cryptor transform', Object.assign({
1047
+ operation,
1048
+ passedTrackId: trackId,
1049
+ codec
1050
+ }, this.logContext));
1038
1051
  const transformFn = operation === 'encode' ? this.encodeFunction : this.decodeFunction;
1039
1052
  const transformStream = new TransformStream({
1040
1053
  transform: transformFn.bind(this)
@@ -1046,6 +1059,9 @@ class FrameCryptor extends BaseFrameCryptor {
1046
1059
  this.trackId = trackId;
1047
1060
  }
1048
1061
  setSifTrailer(trailer) {
1062
+ workerLogger.debug('setting SIF trailer', Object.assign(Object.assign({}, this.logContext), {
1063
+ trailer
1064
+ }));
1049
1065
  this.sifTrailer = trailer;
1050
1066
  }
1051
1067
  /**
@@ -1089,6 +1105,7 @@ class FrameCryptor extends BaseFrameCryptor {
1089
1105
  if (encryptionKey) {
1090
1106
  const iv = this.makeIV((_a = encodedFrame.getMetadata().synchronizationSource) !== null && _a !== void 0 ? _a : -1, encodedFrame.timestamp);
1091
1107
  let frameInfo = this.getUnencryptedBytes(encodedFrame);
1108
+ workerLogger.debug('frameInfo for encoded frame', Object.assign(Object.assign({}, frameInfo), this.logContext));
1092
1109
  // Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.
1093
1110
  const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
1094
1111
  // Frame trailer contains the R|IV_LENGTH and key index
@@ -1125,6 +1142,7 @@ class FrameCryptor extends BaseFrameCryptor {
1125
1142
  workerLogger.error(e);
1126
1143
  }
1127
1144
  } else {
1145
+ workerLogger.debug('failed to decrypt, emitting error', this.logContext);
1128
1146
  this.emit(CryptorEvent.Error, new CryptorError("encryption key missing for encoding", CryptorErrorReason.MissingKey));
1129
1147
  }
1130
1148
  });
@@ -1140,10 +1158,12 @@ class FrameCryptor extends BaseFrameCryptor {
1140
1158
  if (!this.isEnabled() ||
1141
1159
  // skip for decryption for empty dtx frames
1142
1160
  encodedFrame.data.byteLength === 0) {
1161
+ workerLogger.debug('skipping empty frame', this.logContext);
1143
1162
  this.sifGuard.recordUserFrame();
1144
1163
  return controller.enqueue(encodedFrame);
1145
1164
  }
1146
1165
  if (isFrameServerInjected(encodedFrame.data, this.sifTrailer)) {
1166
+ workerLogger.debug('enqueue SIF', this.logContext);
1147
1167
  this.sifGuard.recordSif();
1148
1168
  if (this.sifGuard.isSifAllowed()) {
1149
1169
  encodedFrame.data = encodedFrame.data.slice(0, encodedFrame.data.byteLength - this.sifTrailer.byteLength);
@@ -1162,6 +1182,7 @@ class FrameCryptor extends BaseFrameCryptor {
1162
1182
  const decodedFrame = yield this.decryptFrame(encodedFrame, keyIndex);
1163
1183
  this.keys.decryptionSuccess();
1164
1184
  if (decodedFrame) {
1185
+ workerLogger.debug('enqueue decrypted frame', this.logContext);
1165
1186
  return controller.enqueue(decodedFrame);
1166
1187
  }
1167
1188
  } catch (error) {
@@ -1199,6 +1220,7 @@ class FrameCryptor extends BaseFrameCryptor {
1199
1220
  throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));
1200
1221
  }
1201
1222
  let frameInfo = this.getUnencryptedBytes(encodedFrame);
1223
+ workerLogger.debug('frameInfo for decoded frame', Object.assign(Object.assign({}, frameInfo), this.logContext));
1202
1224
  // Construct frame trailer. Similar to the frame header described in
1203
1225
  // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
1204
1226
  // but we put it at the end.
@@ -1361,6 +1383,9 @@ class FrameCryptor extends BaseFrameCryptor {
1361
1383
  // @ts-expect-error payloadType is not yet part of the typescript definition and currently not supported in Safari
1362
1384
  const payloadType = frame.getMetadata().payloadType;
1363
1385
  const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
1386
+ workerLogger.debug('reading codec from frame', Object.assign({
1387
+ codec
1388
+ }, this.logContext));
1364
1389
  return codec;
1365
1390
  }
1366
1391
  }
@@ -1548,18 +1573,21 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
1548
1573
  }
1549
1574
  /**
1550
1575
  * takes in a key material with `deriveBits` and `deriveKey` set as key usages
1551
- * and derives encryption keys from the material and sets it on the key ring buffer
1576
+ * and derives encryption keys from the material and sets it on the key ring buffers
1552
1577
  * together with the material
1553
1578
  * also updates the currentKeyIndex
1554
1579
  */
1555
- setKeyFromMaterial(material) {
1556
- let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1580
+ setKeyFromMaterial(material, keyIndex) {
1557
1581
  let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1558
1582
  return __awaiter(this, void 0, void 0, function* () {
1559
- const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : -1;
1560
- workerLogger.debug("setting new key with index ".concat(newIndex));
1561
1583
  const keySet = yield deriveKeys(material, this.keyProviderOptions.ratchetSalt);
1562
- this.setKeySet(keySet, newIndex >= 0 ? newIndex : this.currentKeyIndex, emitRatchetEvent);
1584
+ const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : this.currentKeyIndex;
1585
+ workerLogger.debug("setting new key with index ".concat(keyIndex), {
1586
+ usage: material.usages,
1587
+ algorithm: material.algorithm,
1588
+ ratchetSalt: this.keyProviderOptions.ratchetSalt
1589
+ });
1590
+ this.setKeySet(keySet, newIndex, emitRatchetEvent);
1563
1591
  if (newIndex >= 0) this.currentKeyIndex = newIndex;
1564
1592
  });
1565
1593
  }
@@ -1594,7 +1622,6 @@ const participantKeys = new Map();
1594
1622
  let sharedKeyHandler;
1595
1623
  let isEncryptionEnabled = false;
1596
1624
  let useSharedKey = false;
1597
- let sharedKey;
1598
1625
  let sifTrailer;
1599
1626
  let keyProviderOptions = KEY_PROVIDER_DEFAULTS;
1600
1627
  workerLogger.setDefaultLevel('info');
@@ -1633,10 +1660,9 @@ onmessage = ev => {
1633
1660
  break;
1634
1661
  case 'setKey':
1635
1662
  if (useSharedKey) {
1636
- workerLogger.warn('set shared key');
1637
1663
  setSharedKey(data.key, data.keyIndex);
1638
1664
  } else if (data.participantIdentity) {
1639
- workerLogger.warn("set participant sender key ".concat(data.participantIdentity, " index ").concat(data.keyIndex));
1665
+ workerLogger.info("set participant sender key ".concat(data.participantIdentity, " index ").concat(data.keyIndex));
1640
1666
  getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);
1641
1667
  } else {
1642
1668
  workerLogger.error('no participant Id was provided and shared key usage is disabled');
@@ -1680,7 +1706,7 @@ function handleRatchetRequest(data) {
1680
1706
  });
1681
1707
  }
1682
1708
  function getTrackCryptor(participantIdentity, trackId) {
1683
- let cryptor = participantCryptors.find(c => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId);
1709
+ let cryptor = participantCryptors.find(c => c.getTrackId() === trackId);
1684
1710
  if (!cryptor) {
1685
1711
  workerLogger.info('creating new cryptor for', {
1686
1712
  participantIdentity
@@ -1709,9 +1735,6 @@ function getParticipantKeyHandler(participantIdentity) {
1709
1735
  let keys = participantKeys.get(participantIdentity);
1710
1736
  if (!keys) {
1711
1737
  keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);
1712
- if (sharedKey) {
1713
- keys.setKey(sharedKey);
1714
- }
1715
1738
  keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);
1716
1739
  participantKeys.set(participantIdentity, keys);
1717
1740
  }
@@ -1719,20 +1742,32 @@ function getParticipantKeyHandler(participantIdentity) {
1719
1742
  }
1720
1743
  function getSharedKeyHandler() {
1721
1744
  if (!sharedKeyHandler) {
1745
+ workerLogger.debug('creating new shared key handler');
1722
1746
  sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);
1723
1747
  }
1724
1748
  return sharedKeyHandler;
1725
1749
  }
1726
1750
  function unsetCryptorParticipant(trackId, participantIdentity) {
1727
- var _a;
1728
- (_a = participantCryptors.find(c => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId)) === null || _a === void 0 ? void 0 : _a.unsetParticipant();
1751
+ const cryptor = participantCryptors.find(c => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId);
1752
+ if (!cryptor) {
1753
+ workerLogger.warn('Could not unset participant on cryptor', {
1754
+ trackId,
1755
+ participantIdentity
1756
+ });
1757
+ } else {
1758
+ cryptor.unsetParticipant();
1759
+ }
1729
1760
  }
1730
1761
  function setEncryptionEnabled(enable, participantIdentity) {
1762
+ workerLogger.debug("setting encryption enabled for all tracks of ".concat(participantIdentity), {
1763
+ enable
1764
+ });
1731
1765
  encryptionEnabledMap.set(participantIdentity, enable);
1732
1766
  }
1733
1767
  function setSharedKey(key, index) {
1734
- workerLogger.debug('setting shared key');
1735
- sharedKey = key;
1768
+ workerLogger.info('set shared key', {
1769
+ index
1770
+ });
1736
1771
  getSharedKeyHandler().setKey(key, index);
1737
1772
  }
1738
1773
  function setupCryptorErrorEvents(cryptor) {