livekit-client 1.13.0 → 1.13.2
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.
- 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 +122 -105
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +172 -109
- 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/E2eeManager.d.ts +4 -3
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/KeyProvider.d.ts +7 -6
- package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
- package/dist/src/e2ee/events.d.ts +34 -0
- package/dist/src/e2ee/events.d.ts.map +1 -0
- package/dist/src/e2ee/index.d.ts +1 -0
- package/dist/src/e2ee/index.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +17 -33
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +15 -12
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +2 -1
- package/dist/src/room/track/processor/types.d.ts.map +1 -1
- package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +4 -3
- package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +7 -6
- package/dist/ts4.2/src/e2ee/events.d.ts +34 -0
- package/dist/ts4.2/src/e2ee/index.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/types.d.ts +17 -33
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +15 -12
- package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +6 -8
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/ts4.2/src/room/track/processor/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/e2ee/E2eeManager.ts +105 -77
- package/src/e2ee/KeyProvider.ts +23 -13
- package/src/e2ee/events.ts +48 -0
- package/src/e2ee/index.ts +1 -0
- package/src/e2ee/types.ts +19 -41
- package/src/e2ee/worker/FrameCryptor.ts +51 -43
- package/src/e2ee/worker/ParticipantKeyHandler.ts +25 -27
- package/src/e2ee/worker/e2ee.worker.ts +61 -68
- package/src/room/PCTransport.ts +12 -2
- package/src/room/RTCEngine.ts +0 -1
- package/src/room/Room.ts +20 -15
- package/src/room/participant/LocalParticipant.ts +5 -1
- package/src/room/track/LocalTrack.ts +18 -10
- package/src/room/track/facingMode.ts +1 -1
- package/src/room/track/processor/types.ts +2 -1
| @@ -392,6 +392,26 @@ class CryptorError extends LivekitError { | |
| 392 392 | 
             
              }
         | 
| 393 393 | 
             
            }
         | 
| 394 394 |  | 
| 395 | 
            +
            var KeyProviderEvent;
         | 
| 396 | 
            +
            (function (KeyProviderEvent) {
         | 
| 397 | 
            +
              KeyProviderEvent["SetKey"] = "setKey";
         | 
| 398 | 
            +
              KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
         | 
| 399 | 
            +
              KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
         | 
| 400 | 
            +
            })(KeyProviderEvent || (KeyProviderEvent = {}));
         | 
| 401 | 
            +
            var KeyHandlerEvent;
         | 
| 402 | 
            +
            (function (KeyHandlerEvent) {
         | 
| 403 | 
            +
              KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
         | 
| 404 | 
            +
            })(KeyHandlerEvent || (KeyHandlerEvent = {}));
         | 
| 405 | 
            +
            var EncryptionEvent;
         | 
| 406 | 
            +
            (function (EncryptionEvent) {
         | 
| 407 | 
            +
              EncryptionEvent["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
         | 
| 408 | 
            +
              EncryptionEvent["EncryptionError"] = "encryptionError";
         | 
| 409 | 
            +
            })(EncryptionEvent || (EncryptionEvent = {}));
         | 
| 410 | 
            +
            var CryptorEvent;
         | 
| 411 | 
            +
            (function (CryptorEvent) {
         | 
| 412 | 
            +
              CryptorEvent["Error"] = "cryptorError";
         | 
| 413 | 
            +
            })(CryptorEvent || (CryptorEvent = {}));
         | 
| 414 | 
            +
             | 
| 395 415 | 
             
            var events = {exports: {}};
         | 
| 396 416 |  | 
| 397 417 | 
             
            var R = typeof Reflect === 'object' ? Reflect : null;
         | 
| @@ -773,10 +793,6 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) { | |
| 773 793 | 
             
            }
         | 
| 774 794 | 
             
            var eventsExports = events.exports;
         | 
| 775 795 |  | 
| 776 | 
            -
            const CryptorEvent = {
         | 
| 777 | 
            -
              Error: 'cryptorError'
         | 
| 778 | 
            -
            };
         | 
| 779 | 
            -
             | 
| 780 796 | 
             
            var AudioPresets;
         | 
| 781 797 | 
             
            (function (AudioPresets) {
         | 
| 782 798 | 
             
              AudioPresets.telephone = {
         | 
| @@ -903,6 +919,7 @@ class SifGuard { | |
| 903 919 | 
             
              }
         | 
| 904 920 | 
             
            }
         | 
| 905 921 |  | 
| 922 | 
            +
            const encryptionEnabledMap = new Map();
         | 
| 906 923 | 
             
            class BaseFrameCryptor extends eventsExports.EventEmitter {
         | 
| 907 924 | 
             
              encodeFunction(encodedFrame, controller) {
         | 
| 908 925 | 
             
                throw Error('not implemented for subclass');
         | 
| @@ -921,7 +938,7 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 921 938 | 
             
                super();
         | 
| 922 939 | 
             
                this.sendCounts = new Map();
         | 
| 923 940 | 
             
                this.keys = opts.keys;
         | 
| 924 | 
            -
                this. | 
| 941 | 
            +
                this.participantIdentity = opts.participantIdentity;
         | 
| 925 942 | 
             
                this.rtpMap = new Map();
         | 
| 926 943 | 
             
                this.keyProviderOptions = opts.keyProviderOptions;
         | 
| 927 944 | 
             
                this.sifTrailer = (_a = opts.sifTrailer) !== null && _a !== void 0 ? _a : Uint8Array.from([]);
         | 
| @@ -934,15 +951,22 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 934 951 | 
             
               * @param keys
         | 
| 935 952 | 
             
               */
         | 
| 936 953 | 
             
              setParticipant(id, keys) {
         | 
| 937 | 
            -
                this. | 
| 954 | 
            +
                this.participantIdentity = id;
         | 
| 938 955 | 
             
                this.keys = keys;
         | 
| 939 956 | 
             
                this.sifGuard.reset();
         | 
| 940 957 | 
             
              }
         | 
| 941 958 | 
             
              unsetParticipant() {
         | 
| 942 | 
            -
                this. | 
| 959 | 
            +
                this.participantIdentity = undefined;
         | 
| 960 | 
            +
              }
         | 
| 961 | 
            +
              isEnabled() {
         | 
| 962 | 
            +
                if (this.participantIdentity) {
         | 
| 963 | 
            +
                  return encryptionEnabledMap.get(this.participantIdentity);
         | 
| 964 | 
            +
                } else {
         | 
| 965 | 
            +
                  return undefined;
         | 
| 966 | 
            +
                }
         | 
| 943 967 | 
             
              }
         | 
| 944 | 
            -
               | 
| 945 | 
            -
                return this. | 
| 968 | 
            +
              getParticipantIdentity() {
         | 
| 969 | 
            +
                return this.participantIdentity;
         | 
| 946 970 | 
             
              }
         | 
| 947 971 | 
             
              getTrackId() {
         | 
| 948 972 | 
             
                return this.trackId;
         | 
| @@ -974,10 +998,13 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 974 998 | 
             
                });
         | 
| 975 999 | 
             
                readable.pipeThrough(transformStream).pipeTo(writable).catch(e => {
         | 
| 976 1000 | 
             
                  workerLogger.warn(e);
         | 
| 977 | 
            -
                  this.emit( | 
| 1001 | 
            +
                  this.emit(CryptorEvent.Error, e instanceof CryptorError ? e : new CryptorError(e.message));
         | 
| 978 1002 | 
             
                });
         | 
| 979 1003 | 
             
                this.trackId = trackId;
         | 
| 980 1004 | 
             
              }
         | 
| 1005 | 
            +
              setSifTrailer(trailer) {
         | 
| 1006 | 
            +
                this.sifTrailer = trailer;
         | 
| 1007 | 
            +
              }
         | 
| 981 1008 | 
             
              /**
         | 
| 982 1009 | 
             
               * Function that will be injected in a stream and will encrypt the given encoded frames.
         | 
| 983 1010 | 
             
               *
         | 
| @@ -1003,14 +1030,18 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1003 1030 | 
             
              encodeFunction(encodedFrame, controller) {
         | 
| 1004 1031 | 
             
                var _a;
         | 
| 1005 1032 | 
             
                return __awaiter(this, void 0, void 0, function* () {
         | 
| 1006 | 
            -
                  if (!this. | 
| 1033 | 
            +
                  if (!this.isEnabled() ||
         | 
| 1007 1034 | 
             
                  // skip for encryption for empty dtx frames
         | 
| 1008 1035 | 
             
                  encodedFrame.data.byteLength === 0) {
         | 
| 1009 1036 | 
             
                    return controller.enqueue(encodedFrame);
         | 
| 1010 1037 | 
             
                  }
         | 
| 1038 | 
            +
                  const keySet = this.keys.getKeySet();
         | 
| 1039 | 
            +
                  if (!keySet) {
         | 
| 1040 | 
            +
                    throw new TypeError("key set not found for ".concat(this.participantIdentity, " at index ").concat(this.keys.getCurrentKeyIndex()));
         | 
| 1041 | 
            +
                  }
         | 
| 1011 1042 | 
             
                  const {
         | 
| 1012 1043 | 
             
                    encryptionKey
         | 
| 1013 | 
            -
                  } =  | 
| 1044 | 
            +
                  } = keySet;
         | 
| 1014 1045 | 
             
                  const keyIndex = this.keys.getCurrentKeyIndex();
         | 
| 1015 1046 | 
             
                  if (encryptionKey) {
         | 
| 1016 1047 | 
             
                    const iv = this.makeIV((_a = encodedFrame.getMetadata().synchronizationSource) !== null && _a !== void 0 ? _a : -1, encodedFrame.timestamp);
         | 
| @@ -1058,7 +1089,7 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1058 1089 | 
             
               */
         | 
| 1059 1090 | 
             
              decodeFunction(encodedFrame, controller) {
         | 
| 1060 1091 | 
             
                return __awaiter(this, void 0, void 0, function* () {
         | 
| 1061 | 
            -
                  if (!this. | 
| 1092 | 
            +
                  if (!this.isEnabled() ||
         | 
| 1062 1093 | 
             
                  // skip for decryption for empty dtx frames
         | 
| 1063 1094 | 
             
                  encodedFrame.data.byteLength === 0) {
         | 
| 1064 1095 | 
             
                    this.sifGuard.recordUserFrame();
         | 
| @@ -1087,8 +1118,7 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1087 1118 | 
             
                    } catch (error) {
         | 
| 1088 1119 | 
             
                      if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {
         | 
| 1089 1120 | 
             
                        if (this.keys.hasValidKey) {
         | 
| 1090 | 
            -
                           | 
| 1091 | 
            -
                          this.emit(CryptorEvent.Error, new CryptorError("invalid key for participant ".concat(this.participantId), CryptorErrorReason.InvalidKey));
         | 
| 1121 | 
            +
                          this.emit(CryptorEvent.Error, error);
         | 
| 1092 1122 | 
             
                          this.keys.decryptionFailure();
         | 
| 1093 1123 | 
             
                        }
         | 
| 1094 1124 | 
             
                      } else {
         | 
| @@ -1100,7 +1130,7 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1100 1130 | 
             
                  } else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {
         | 
| 1101 1131 | 
             
                    // emit an error in case the key index is out of bounds but the key handler thinks we still have a valid key
         | 
| 1102 1132 | 
             
                    workerLogger.warn('skipping decryption due to missing key at index');
         | 
| 1103 | 
            -
                    this.emit(CryptorEvent.Error, new CryptorError("missing key at index for participant ".concat(this. | 
| 1133 | 
            +
                    this.emit(CryptorEvent.Error, new CryptorError("missing key at index for participant ".concat(this.participantIdentity), CryptorErrorReason.MissingKey));
         | 
| 1104 1134 | 
             
                  }
         | 
| 1105 1135 | 
             
                });
         | 
| 1106 1136 | 
             
              }
         | 
| @@ -1116,6 +1146,9 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1116 1146 | 
             
                var _a;
         | 
| 1117 1147 | 
             
                return __awaiter(this, void 0, void 0, function* () {
         | 
| 1118 1148 | 
             
                  const keySet = this.keys.getKeySet(keyIndex);
         | 
| 1149 | 
            +
                  if (!ratchetOpts.encryptionKey && !keySet) {
         | 
| 1150 | 
            +
                    throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));
         | 
| 1151 | 
            +
                  }
         | 
| 1119 1152 | 
             
                  // Construct frame trailer. Similar to the frame header described in
         | 
| 1120 1153 | 
             
                  // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
         | 
| 1121 1154 | 
             
                  // but we put it at the end.
         | 
| @@ -1173,11 +1206,11 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1173 1206 | 
             
                          workerLogger.debug('resetting to initial material');
         | 
| 1174 1207 | 
             
                          this.keys.setKeyFromMaterial(initialMaterial.material, keyIndex);
         | 
| 1175 1208 | 
             
                        }
         | 
| 1176 | 
            -
                        workerLogger.warn('maximum ratchet attempts exceeded | 
| 1177 | 
            -
                        throw new CryptorError("valid key missing for participant ".concat(this. | 
| 1209 | 
            +
                        workerLogger.warn('maximum ratchet attempts exceeded');
         | 
| 1210 | 
            +
                        throw new CryptorError("valid key missing for participant ".concat(this.participantIdentity), CryptorErrorReason.InvalidKey);
         | 
| 1178 1211 | 
             
                      }
         | 
| 1179 1212 | 
             
                    } else {
         | 
| 1180 | 
            -
                      throw new CryptorError( | 
| 1213 | 
            +
                      throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
         | 
| 1181 1214 | 
             
                    }
         | 
| 1182 1215 | 
             
                  }
         | 
| 1183 1216 | 
             
                });
         | 
| @@ -1265,9 +1298,6 @@ class FrameCryptor extends BaseFrameCryptor { | |
| 1265 1298 | 
             
                const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
         | 
| 1266 1299 | 
             
                return codec;
         | 
| 1267 1300 | 
             
              }
         | 
| 1268 | 
            -
              setSifTrailer(trailer) {
         | 
| 1269 | 
            -
                this.sifTrailer = trailer;
         | 
| 1270 | 
            -
              }
         | 
| 1271 1301 | 
             
            }
         | 
| 1272 1302 | 
             
            /**
         | 
| 1273 1303 | 
             
             * Slice the NALUs present in the supplied buffer, assuming it is already byte-aligned
         | 
| @@ -1370,28 +1400,24 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter { | |
| 1370 1400 | 
             
              get hasValidKey() {
         | 
| 1371 1401 | 
             
                return this._hasValidKey;
         | 
| 1372 1402 | 
             
              }
         | 
| 1373 | 
            -
              constructor( | 
| 1403 | 
            +
              constructor(participantIdentity, keyProviderOptions) {
         | 
| 1374 1404 | 
             
                super();
         | 
| 1375 1405 | 
             
                this.decryptionFailureCount = 0;
         | 
| 1376 1406 | 
             
                this._hasValidKey = true;
         | 
| 1377 1407 | 
             
                this.currentKeyIndex = 0;
         | 
| 1378 | 
            -
                this.cryptoKeyRing = new Array(KEYRING_SIZE);
         | 
| 1379 | 
            -
                this.enabled = isEnabled;
         | 
| 1408 | 
            +
                this.cryptoKeyRing = new Array(KEYRING_SIZE).fill(undefined);
         | 
| 1380 1409 | 
             
                this.keyProviderOptions = keyProviderOptions;
         | 
| 1381 1410 | 
             
                this.ratchetPromiseMap = new Map();
         | 
| 1382 | 
            -
                this. | 
| 1411 | 
            +
                this.participantIdentity = participantIdentity;
         | 
| 1383 1412 | 
             
                this.resetKeyStatus();
         | 
| 1384 1413 | 
             
              }
         | 
| 1385 | 
            -
              setEnabled(enabled) {
         | 
| 1386 | 
            -
                this.enabled = enabled;
         | 
| 1387 | 
            -
              }
         | 
| 1388 1414 | 
             
              decryptionFailure() {
         | 
| 1389 1415 | 
             
                if (this.keyProviderOptions.failureTolerance < 0) {
         | 
| 1390 1416 | 
             
                  return;
         | 
| 1391 1417 | 
             
                }
         | 
| 1392 1418 | 
             
                this.decryptionFailureCount += 1;
         | 
| 1393 1419 | 
             
                if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {
         | 
| 1394 | 
            -
                  workerLogger.warn("key for ".concat(this. | 
| 1420 | 
            +
                  workerLogger.warn("key for ".concat(this.participantIdentity, " is being marked as invalid"));
         | 
| 1395 1421 | 
             
                  this._hasValidKey = false;
         | 
| 1396 1422 | 
             
                }
         | 
| 1397 1423 | 
             
              }
         | 
| @@ -1415,19 +1441,23 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter { | |
| 1415 1441 | 
             
               */
         | 
| 1416 1442 | 
             
              ratchetKey(keyIndex) {
         | 
| 1417 1443 | 
             
                let setKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
         | 
| 1418 | 
            -
                const currentKeyIndex = keyIndex !== null && keyIndex !== void 0 ? keyIndex :  | 
| 1444 | 
            +
                const currentKeyIndex = keyIndex !== null && keyIndex !== void 0 ? keyIndex : this.getCurrentKeyIndex();
         | 
| 1419 1445 | 
             
                const existingPromise = this.ratchetPromiseMap.get(currentKeyIndex);
         | 
| 1420 1446 | 
             
                if (typeof existingPromise !== 'undefined') {
         | 
| 1421 1447 | 
             
                  return existingPromise;
         | 
| 1422 1448 | 
             
                }
         | 
| 1423 1449 | 
             
                const ratchetPromise = new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
         | 
| 1424 1450 | 
             
                  try {
         | 
| 1425 | 
            -
                    const  | 
| 1451 | 
            +
                    const keySet = this.getKeySet(currentKeyIndex);
         | 
| 1452 | 
            +
                    if (!keySet) {
         | 
| 1453 | 
            +
                      throw new TypeError("Cannot ratchet key without a valid keyset of participant ".concat(this.participantIdentity));
         | 
| 1454 | 
            +
                    }
         | 
| 1455 | 
            +
                    const currentMaterial = keySet.material;
         | 
| 1426 1456 | 
             
                    const newMaterial = yield importKey(yield ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt), currentMaterial.algorithm.name, 'derive');
         | 
| 1427 1457 | 
             
                    if (setKey) {
         | 
| 1428 1458 | 
             
                      this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);
         | 
| 1459 | 
            +
                      this.emit(KeyHandlerEvent.KeyRatcheted, newMaterial, this.participantIdentity, currentKeyIndex);
         | 
| 1429 1460 | 
             
                    }
         | 
| 1430 | 
            -
                    this.emit('keyRatcheted', newMaterial, keyIndex, this.participantId);
         | 
| 1431 1461 | 
             
                    resolve(newMaterial);
         | 
| 1432 1462 | 
             
                  } catch (e) {
         | 
| 1433 1463 | 
             
                    reject(e);
         | 
| @@ -1471,12 +1501,10 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter { | |
| 1471 1501 | 
             
              }
         | 
| 1472 1502 | 
             
              setKeySet(keySet, keyIndex) {
         | 
| 1473 1503 | 
             
                let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
         | 
| 1474 | 
            -
                 | 
| 1475 | 
            -
             | 
| 1476 | 
            -
                   | 
| 1477 | 
            -
             | 
| 1478 | 
            -
                  }
         | 
| 1479 | 
            -
                });
         | 
| 1504 | 
            +
                this.cryptoKeyRing[keyIndex % this.cryptoKeyRing.length] = keySet;
         | 
| 1505 | 
            +
                if (emitRatchetEvent) {
         | 
| 1506 | 
            +
                  this.emit(KeyHandlerEvent.KeyRatcheted, keySet.material, this.participantIdentity, keyIndex);
         | 
| 1507 | 
            +
                }
         | 
| 1480 1508 | 
             
              }
         | 
| 1481 1509 | 
             
              setCurrentKeyIndex(index) {
         | 
| 1482 1510 | 
             
                return __awaiter(this, void 0, void 0, function* () {
         | 
| @@ -1484,9 +1512,6 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter { | |
| 1484 1512 | 
             
                  this.resetKeyStatus();
         | 
| 1485 1513 | 
             
                });
         | 
| 1486 1514 | 
             
              }
         | 
| 1487 | 
            -
              isEnabled() {
         | 
| 1488 | 
            -
                return this.enabled;
         | 
| 1489 | 
            -
              }
         | 
| 1490 1515 | 
             
              getCurrentKeyIndex() {
         | 
| 1491 1516 | 
             
                return this.currentKeyIndex;
         | 
| 1492 1517 | 
             
              }
         | 
| @@ -1502,8 +1527,7 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter { | |
| 1502 1527 |  | 
| 1503 1528 | 
             
            const participantCryptors = [];
         | 
| 1504 1529 | 
             
            const participantKeys = new Map();
         | 
| 1505 | 
            -
            let  | 
| 1506 | 
            -
            let publisherKeys;
         | 
| 1530 | 
            +
            let sharedKeyHandler;
         | 
| 1507 1531 | 
             
            let isEncryptionEnabled = false;
         | 
| 1508 1532 | 
             
            let useSharedKey = false;
         | 
| 1509 1533 | 
             
            let sharedKey;
         | 
| @@ -1521,36 +1545,35 @@ onmessage = ev => { | |
| 1521 1545 | 
             
                  keyProviderOptions = data.keyProviderOptions;
         | 
| 1522 1546 | 
             
                  useSharedKey = !!data.keyProviderOptions.sharedKey;
         | 
| 1523 1547 | 
             
                  // acknowledge init successful
         | 
| 1524 | 
            -
                  const  | 
| 1525 | 
            -
                    kind: ' | 
| 1548 | 
            +
                  const ackMsg = {
         | 
| 1549 | 
            +
                    kind: 'initAck',
         | 
| 1526 1550 | 
             
                    data: {
         | 
| 1527 1551 | 
             
                      enabled: isEncryptionEnabled
         | 
| 1528 1552 | 
             
                    }
         | 
| 1529 1553 | 
             
                  };
         | 
| 1530 | 
            -
                   | 
| 1531 | 
            -
                  publisherKeys.on('keyRatcheted', emitRatchetedKeys);
         | 
| 1532 | 
            -
                  postMessage(enableMsg);
         | 
| 1554 | 
            +
                  postMessage(ackMsg);
         | 
| 1533 1555 | 
             
                  break;
         | 
| 1534 1556 | 
             
                case 'enable':
         | 
| 1535 | 
            -
                  setEncryptionEnabled(data.enabled, data. | 
| 1557 | 
            +
                  setEncryptionEnabled(data.enabled, data.participantIdentity);
         | 
| 1536 1558 | 
             
                  workerLogger.info('updated e2ee enabled status');
         | 
| 1537 1559 | 
             
                  // acknowledge enable call successful
         | 
| 1538 1560 | 
             
                  postMessage(ev.data);
         | 
| 1539 1561 | 
             
                  break;
         | 
| 1540 1562 | 
             
                case 'decode':
         | 
| 1541 | 
            -
                  let cryptor = getTrackCryptor(data. | 
| 1563 | 
            +
                  let cryptor = getTrackCryptor(data.participantIdentity, data.trackId);
         | 
| 1542 1564 | 
             
                  cryptor.setupTransform(kind, data.readableStream, data.writableStream, data.trackId, data.codec);
         | 
| 1543 1565 | 
             
                  break;
         | 
| 1544 1566 | 
             
                case 'encode':
         | 
| 1545 | 
            -
                  let pubCryptor =  | 
| 1567 | 
            +
                  let pubCryptor = getTrackCryptor(data.participantIdentity, data.trackId);
         | 
| 1546 1568 | 
             
                  pubCryptor.setupTransform(kind, data.readableStream, data.writableStream, data.trackId, data.codec);
         | 
| 1547 1569 | 
             
                  break;
         | 
| 1548 1570 | 
             
                case 'setKey':
         | 
| 1549 1571 | 
             
                  if (useSharedKey) {
         | 
| 1550 | 
            -
                    workerLogger. | 
| 1572 | 
            +
                    workerLogger.warn('set shared key');
         | 
| 1551 1573 | 
             
                    setSharedKey(data.key, data.keyIndex);
         | 
| 1552 | 
            -
                  } else if (data. | 
| 1553 | 
            -
                     | 
| 1574 | 
            +
                  } else if (data.participantIdentity) {
         | 
| 1575 | 
            +
                    workerLogger.warn("set participant sender key ".concat(data.participantIdentity));
         | 
| 1576 | 
            +
                    getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);
         | 
| 1554 1577 | 
             
                  } else {
         | 
| 1555 1578 | 
             
                    workerLogger.error('no participant Id was provided and shared key usage is disabled');
         | 
| 1556 1579 | 
             
                  }
         | 
| @@ -1559,11 +1582,14 @@ onmessage = ev => { | |
| 1559 1582 | 
             
                  unsetCryptorParticipant(data.trackId);
         | 
| 1560 1583 | 
             
                  break;
         | 
| 1561 1584 | 
             
                case 'updateCodec':
         | 
| 1562 | 
            -
                  getTrackCryptor(data. | 
| 1585 | 
            +
                  getTrackCryptor(data.participantIdentity, data.trackId).setVideoCodec(data.codec);
         | 
| 1563 1586 | 
             
                  break;
         | 
| 1564 1587 | 
             
                case 'setRTPMap':
         | 
| 1565 | 
            -
                   | 
| 1566 | 
            -
             | 
| 1588 | 
            +
                  // this is only used for the local participant
         | 
| 1589 | 
            +
                  participantCryptors.forEach(cr => {
         | 
| 1590 | 
            +
                    if (cr.getParticipantIdentity() === data.participantIdentity) {
         | 
| 1591 | 
            +
                      cr.setRtpMap(data.map);
         | 
| 1592 | 
            +
                    }
         | 
| 1567 1593 | 
             
                  });
         | 
| 1568 1594 | 
             
                  break;
         | 
| 1569 1595 | 
             
                case 'ratchetRequest':
         | 
| @@ -1576,86 +1602,77 @@ onmessage = ev => { | |
| 1576 1602 | 
             
            };
         | 
| 1577 1603 | 
             
            function handleRatchetRequest(data) {
         | 
| 1578 1604 | 
             
              return __awaiter(this, void 0, void 0, function* () {
         | 
| 1579 | 
            -
                 | 
| 1580 | 
            -
             | 
| 1581 | 
            -
             | 
| 1605 | 
            +
                if (useSharedKey) {
         | 
| 1606 | 
            +
                  const keyHandler = getSharedKeyHandler();
         | 
| 1607 | 
            +
                  yield keyHandler.ratchetKey(data.keyIndex);
         | 
| 1608 | 
            +
                  keyHandler.resetKeyStatus();
         | 
| 1609 | 
            +
                } else if (data.participantIdentity) {
         | 
| 1610 | 
            +
                  const keyHandler = getParticipantKeyHandler(data.participantIdentity);
         | 
| 1611 | 
            +
                  yield keyHandler.ratchetKey(data.keyIndex);
         | 
| 1612 | 
            +
                  keyHandler.resetKeyStatus();
         | 
| 1613 | 
            +
                } else {
         | 
| 1614 | 
            +
                  workerLogger.error('no participant Id was provided for ratchet request and shared key usage is disabled');
         | 
| 1615 | 
            +
                }
         | 
| 1582 1616 | 
             
              });
         | 
| 1583 1617 | 
             
            }
         | 
| 1584 | 
            -
            function getTrackCryptor( | 
| 1618 | 
            +
            function getTrackCryptor(participantIdentity, trackId) {
         | 
| 1585 1619 | 
             
              let cryptor = participantCryptors.find(c => c.getTrackId() === trackId);
         | 
| 1586 1620 | 
             
              if (!cryptor) {
         | 
| 1587 1621 | 
             
                workerLogger.info('creating new cryptor for', {
         | 
| 1588 | 
            -
                   | 
| 1622 | 
            +
                  participantIdentity
         | 
| 1589 1623 | 
             
                });
         | 
| 1590 1624 | 
             
                if (!keyProviderOptions) {
         | 
| 1591 1625 | 
             
                  throw Error('Missing keyProvider options');
         | 
| 1592 1626 | 
             
                }
         | 
| 1593 1627 | 
             
                cryptor = new FrameCryptor({
         | 
| 1594 | 
            -
                   | 
| 1595 | 
            -
                  keys: getParticipantKeyHandler( | 
| 1628 | 
            +
                  participantIdentity,
         | 
| 1629 | 
            +
                  keys: getParticipantKeyHandler(participantIdentity),
         | 
| 1596 1630 | 
             
                  keyProviderOptions,
         | 
| 1597 1631 | 
             
                  sifTrailer
         | 
| 1598 1632 | 
             
                });
         | 
| 1599 1633 | 
             
                setupCryptorErrorEvents(cryptor);
         | 
| 1600 1634 | 
             
                participantCryptors.push(cryptor);
         | 
| 1601 | 
            -
              } else if ( | 
| 1635 | 
            +
              } else if (participantIdentity !== cryptor.getParticipantIdentity()) {
         | 
| 1602 1636 | 
             
                // assign new participant id to track cryptor and pass in correct key handler
         | 
| 1603 | 
            -
                cryptor.setParticipant( | 
| 1637 | 
            +
                cryptor.setParticipant(participantIdentity, getParticipantKeyHandler(participantIdentity));
         | 
| 1604 1638 | 
             
              }
         | 
| 1605 1639 | 
             
              return cryptor;
         | 
| 1606 1640 | 
             
            }
         | 
| 1607 | 
            -
            function getParticipantKeyHandler( | 
| 1608 | 
            -
              if ( | 
| 1609 | 
            -
                return  | 
| 1641 | 
            +
            function getParticipantKeyHandler(participantIdentity) {
         | 
| 1642 | 
            +
              if (useSharedKey) {
         | 
| 1643 | 
            +
                return getSharedKeyHandler();
         | 
| 1610 1644 | 
             
              }
         | 
| 1611 | 
            -
              let keys = participantKeys.get( | 
| 1645 | 
            +
              let keys = participantKeys.get(participantIdentity);
         | 
| 1612 1646 | 
             
              if (!keys) {
         | 
| 1613 | 
            -
                keys = new ParticipantKeyHandler( | 
| 1647 | 
            +
                keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);
         | 
| 1614 1648 | 
             
                if (sharedKey) {
         | 
| 1615 1649 | 
             
                  keys.setKey(sharedKey);
         | 
| 1616 1650 | 
             
                }
         | 
| 1617 | 
            -
                 | 
| 1651 | 
            +
                keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);
         | 
| 1652 | 
            +
                participantKeys.set(participantIdentity, keys);
         | 
| 1618 1653 | 
             
              }
         | 
| 1619 1654 | 
             
              return keys;
         | 
| 1620 1655 | 
             
            }
         | 
| 1656 | 
            +
            function getSharedKeyHandler() {
         | 
| 1657 | 
            +
              if (!sharedKeyHandler) {
         | 
| 1658 | 
            +
                sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);
         | 
| 1659 | 
            +
              }
         | 
| 1660 | 
            +
              return sharedKeyHandler;
         | 
| 1661 | 
            +
            }
         | 
| 1621 1662 | 
             
            function unsetCryptorParticipant(trackId) {
         | 
| 1622 1663 | 
             
              var _a;
         | 
| 1623 1664 | 
             
              (_a = participantCryptors.find(c => c.getTrackId() === trackId)) === null || _a === void 0 ? void 0 : _a.unsetParticipant();
         | 
| 1624 1665 | 
             
            }
         | 
| 1625 | 
            -
            function  | 
| 1626 | 
            -
               | 
| 1627 | 
            -
              if (!publishCryptor) {
         | 
| 1628 | 
            -
                if (!keyProviderOptions) {
         | 
| 1629 | 
            -
                  throw new TypeError('Missing keyProvider options');
         | 
| 1630 | 
            -
                }
         | 
| 1631 | 
            -
                publishCryptor = new FrameCryptor({
         | 
| 1632 | 
            -
                  keys: publisherKeys,
         | 
| 1633 | 
            -
                  participantId: 'publisher',
         | 
| 1634 | 
            -
                  keyProviderOptions
         | 
| 1635 | 
            -
                });
         | 
| 1636 | 
            -
                setupCryptorErrorEvents(publishCryptor);
         | 
| 1637 | 
            -
                publishCryptors.push(publishCryptor);
         | 
| 1638 | 
            -
              }
         | 
| 1639 | 
            -
              return publishCryptor;
         | 
| 1640 | 
            -
            }
         | 
| 1641 | 
            -
            function setEncryptionEnabled(enable, participantId) {
         | 
| 1642 | 
            -
              if (!participantId) {
         | 
| 1643 | 
            -
                isEncryptionEnabled = enable;
         | 
| 1644 | 
            -
                publisherKeys.setEnabled(enable);
         | 
| 1645 | 
            -
              } else {
         | 
| 1646 | 
            -
                getParticipantKeyHandler(participantId).setEnabled(enable);
         | 
| 1647 | 
            -
              }
         | 
| 1666 | 
            +
            function setEncryptionEnabled(enable, participantIdentity) {
         | 
| 1667 | 
            +
              encryptionEnabledMap.set(participantIdentity, enable);
         | 
| 1648 1668 | 
             
            }
         | 
| 1649 1669 | 
             
            function setSharedKey(key, index) {
         | 
| 1650 1670 | 
             
              workerLogger.debug('setting shared key');
         | 
| 1651 1671 | 
             
              sharedKey = key;
         | 
| 1652 | 
            -
               | 
| 1653 | 
            -
              for (const [, keyHandler] of participantKeys) {
         | 
| 1654 | 
            -
                keyHandler.setKey(key, index);
         | 
| 1655 | 
            -
              }
         | 
| 1672 | 
            +
              getSharedKeyHandler().setKey(key, index);
         | 
| 1656 1673 | 
             
            }
         | 
| 1657 1674 | 
             
            function setupCryptorErrorEvents(cryptor) {
         | 
| 1658 | 
            -
              cryptor.on( | 
| 1675 | 
            +
              cryptor.on(CryptorEvent.Error, error => {
         | 
| 1659 1676 | 
             
                const msg = {
         | 
| 1660 1677 | 
             
                  kind: 'error',
         | 
| 1661 1678 | 
             
                  data: {
         | 
| @@ -1665,11 +1682,11 @@ function setupCryptorErrorEvents(cryptor) { | |
| 1665 1682 | 
             
                postMessage(msg);
         | 
| 1666 1683 | 
             
              });
         | 
| 1667 1684 | 
             
            }
         | 
| 1668 | 
            -
            function emitRatchetedKeys(material, keyIndex) {
         | 
| 1685 | 
            +
            function emitRatchetedKeys(material, participantIdentity, keyIndex) {
         | 
| 1669 1686 | 
             
              const msg = {
         | 
| 1670 1687 | 
             
                kind: "ratchetKey",
         | 
| 1671 1688 | 
             
                data: {
         | 
| 1672 | 
            -
                   | 
| 1689 | 
            +
                  participantIdentity,
         | 
| 1673 1690 | 
             
                  keyIndex,
         | 
| 1674 1691 | 
             
                  material
         | 
| 1675 1692 | 
             
                }
         | 
| @@ -1693,11 +1710,11 @@ if (self.RTCTransformEvent) { | |
| 1693 1710 | 
             
                transformer.handled = true;
         | 
| 1694 1711 | 
             
                const {
         | 
| 1695 1712 | 
             
                  kind,
         | 
| 1696 | 
            -
                   | 
| 1713 | 
            +
                  participantIdentity,
         | 
| 1697 1714 | 
             
                  trackId,
         | 
| 1698 1715 | 
             
                  codec
         | 
| 1699 1716 | 
             
                } = transformer.options;
         | 
| 1700 | 
            -
                const cryptor =  | 
| 1717 | 
            +
                const cryptor = getTrackCryptor(participantIdentity, trackId);
         | 
| 1701 1718 | 
             
                workerLogger.debug('transform', {
         | 
| 1702 1719 | 
             
                  codec
         | 
| 1703 1720 | 
             
                });
         |