livekit-client 2.15.6 → 2.15.8

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 (173) 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 +253 -118
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +1892 -153
  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/connectionHelper/checks/publishVideo.d.ts.map +1 -1
  10. package/dist/src/e2ee/E2eeManager.d.ts +16 -2
  11. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  12. package/dist/src/e2ee/types.d.ts +35 -1
  13. package/dist/src/e2ee/types.d.ts.map +1 -1
  14. package/dist/src/e2ee/utils.d.ts +2 -0
  15. package/dist/src/e2ee/utils.d.ts.map +1 -1
  16. package/dist/src/e2ee/worker/DataCryptor.d.ts +15 -0
  17. package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -0
  18. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +3 -2
  19. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  20. package/dist/src/e2ee/worker/sifPayload.d.ts +6 -6
  21. package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -1
  22. package/dist/src/index.d.ts +5 -3
  23. package/dist/src/index.d.ts.map +1 -1
  24. package/dist/src/logger.d.ts +1 -0
  25. package/dist/src/logger.d.ts.map +1 -1
  26. package/dist/src/options.d.ts +4 -2
  27. package/dist/src/options.d.ts.map +1 -1
  28. package/dist/src/room/PCTransport.d.ts.map +1 -1
  29. package/dist/src/room/RTCEngine.d.ts +5 -2
  30. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  31. package/dist/src/room/Room.d.ts +3 -2
  32. package/dist/src/room/Room.d.ts.map +1 -1
  33. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +2 -2
  34. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -1
  35. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -1
  36. package/dist/src/room/errors.d.ts +2 -1
  37. package/dist/src/room/errors.d.ts.map +1 -1
  38. package/dist/src/room/participant/LocalParticipant.d.ts +1 -3
  39. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  40. package/dist/src/room/participant/Participant.d.ts +2 -2
  41. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  42. package/dist/src/room/token-source/TokenSource.d.ts +70 -0
  43. package/dist/src/room/token-source/TokenSource.d.ts.map +1 -0
  44. package/dist/src/room/token-source/types.d.ts +68 -0
  45. package/dist/src/room/token-source/types.d.ts.map +1 -0
  46. package/dist/src/room/token-source/utils.d.ts +5 -0
  47. package/dist/src/room/token-source/utils.d.ts.map +1 -0
  48. package/dist/src/room/track/LocalTrack.d.ts +1 -1
  49. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  50. package/dist/src/room/track/options.d.ts +7 -3
  51. package/dist/src/room/track/options.d.ts.map +1 -1
  52. package/dist/src/room/track/utils.d.ts.map +1 -1
  53. package/dist/src/room/types.d.ts +1 -0
  54. package/dist/src/room/types.d.ts.map +1 -1
  55. package/dist/src/room/utils.d.ts +2 -1
  56. package/dist/src/room/utils.d.ts.map +1 -1
  57. package/dist/src/utils/camelToSnakeCase.d.ts +8 -0
  58. package/dist/src/utils/camelToSnakeCase.d.ts.map +1 -0
  59. package/dist/ts4.2/{src/e2ee → e2ee}/E2eeManager.d.ts +16 -2
  60. package/dist/ts4.2/{src/e2ee → e2ee}/types.d.ts +35 -1
  61. package/dist/ts4.2/{src/e2ee → e2ee}/utils.d.ts +3 -0
  62. package/dist/ts4.2/e2ee/worker/DataCryptor.d.ts +15 -0
  63. package/dist/ts4.2/{src/e2ee → e2ee}/worker/ParticipantKeyHandler.d.ts +3 -2
  64. package/dist/ts4.2/{src/e2ee → e2ee}/worker/sifPayload.d.ts +6 -6
  65. package/dist/ts4.2/{src/index.d.ts → index.d.ts} +5 -3
  66. package/dist/ts4.2/{src/logger.d.ts → logger.d.ts} +1 -0
  67. package/dist/ts4.2/{src/options.d.ts → options.d.ts} +4 -2
  68. package/dist/ts4.2/{src/room → room}/RTCEngine.d.ts +5 -2
  69. package/dist/ts4.2/{src/room → room}/Room.d.ts +3 -2
  70. package/dist/ts4.2/{src/room → room}/data-stream/incoming/IncomingDataStreamManager.d.ts +2 -1
  71. package/dist/ts4.2/{src/room → room}/errors.d.ts +2 -1
  72. package/dist/ts4.2/{src/room → room}/participant/LocalParticipant.d.ts +1 -3
  73. package/dist/ts4.2/{src/room → room}/participant/Participant.d.ts +2 -2
  74. package/dist/ts4.2/room/token-source/TokenSource.d.ts +71 -0
  75. package/dist/ts4.2/room/token-source/types.d.ts +68 -0
  76. package/dist/ts4.2/room/token-source/utils.d.ts +5 -0
  77. package/dist/ts4.2/{src/room → room}/track/LocalTrack.d.ts +1 -1
  78. package/dist/ts4.2/{src/room → room}/track/options.d.ts +10 -3
  79. package/dist/ts4.2/{src/room → room}/types.d.ts +1 -0
  80. package/dist/ts4.2/{src/room → room}/utils.d.ts +2 -1
  81. package/dist/ts4.2/utils/camelToSnakeCase.d.ts +8 -0
  82. package/package.json +14 -12
  83. package/src/connectionHelper/checks/publishVideo.ts +5 -0
  84. package/src/e2ee/E2eeManager.ts +94 -2
  85. package/src/e2ee/types.ts +44 -1
  86. package/src/e2ee/utils.ts +16 -0
  87. package/src/e2ee/worker/DataCryptor.test.ts +271 -0
  88. package/src/e2ee/worker/DataCryptor.ts +147 -0
  89. package/src/e2ee/worker/ParticipantKeyHandler.ts +4 -3
  90. package/src/e2ee/worker/e2ee.worker.ts +47 -0
  91. package/src/e2ee/worker/sifPayload.ts +10 -6
  92. package/src/index.ts +14 -1
  93. package/src/logger.ts +1 -0
  94. package/src/options.ts +8 -2
  95. package/src/room/PCTransport.ts +14 -5
  96. package/src/room/RTCEngine.ts +55 -6
  97. package/src/room/Room.ts +39 -17
  98. package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +64 -17
  99. package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +7 -0
  100. package/src/room/errors.ts +3 -0
  101. package/src/room/participant/LocalParticipant.ts +17 -29
  102. package/src/room/participant/Participant.ts +6 -1
  103. package/src/room/token-source/TokenSource.ts +285 -0
  104. package/src/room/token-source/types.ts +84 -0
  105. package/src/room/token-source/utils.ts +35 -0
  106. package/src/room/track/LocalAudioTrack.ts +1 -1
  107. package/src/room/track/LocalTrack.ts +1 -1
  108. package/src/room/track/options.ts +12 -4
  109. package/src/room/track/utils.ts +10 -2
  110. package/src/room/types.ts +1 -0
  111. package/src/room/utils.ts +8 -4
  112. package/src/utils/camelToSnakeCase.ts +16 -0
  113. /package/dist/ts4.2/{src/api → api}/SignalClient.d.ts +0 -0
  114. /package/dist/ts4.2/{src/api → api}/utils.d.ts +0 -0
  115. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/ConnectionCheck.d.ts +0 -0
  116. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/Checker.d.ts +0 -0
  117. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/cloudRegion.d.ts +0 -0
  118. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/connectionProtocol.d.ts +0 -0
  119. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/publishAudio.d.ts +0 -0
  120. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/publishVideo.d.ts +0 -0
  121. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/reconnect.d.ts +0 -0
  122. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/turn.d.ts +0 -0
  123. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/webrtc.d.ts +0 -0
  124. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/websocket.d.ts +0 -0
  125. /package/dist/ts4.2/{src/e2ee → e2ee}/KeyProvider.d.ts +0 -0
  126. /package/dist/ts4.2/{src/e2ee → e2ee}/constants.d.ts +0 -0
  127. /package/dist/ts4.2/{src/e2ee → e2ee}/errors.d.ts +0 -0
  128. /package/dist/ts4.2/{src/e2ee → e2ee}/events.d.ts +0 -0
  129. /package/dist/ts4.2/{src/e2ee → e2ee}/index.d.ts +0 -0
  130. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/FrameCryptor.d.ts +0 -0
  131. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/e2ee.worker.d.ts +0 -0
  132. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/naluUtils.d.ts +0 -0
  133. /package/dist/ts4.2/{src/room → room}/DefaultReconnectPolicy.d.ts +0 -0
  134. /package/dist/ts4.2/{src/room → room}/DeviceManager.d.ts +0 -0
  135. /package/dist/ts4.2/{src/room → room}/PCTransport.d.ts +0 -0
  136. /package/dist/ts4.2/{src/room → room}/PCTransportManager.d.ts +0 -0
  137. /package/dist/ts4.2/{src/room → room}/ReconnectPolicy.d.ts +0 -0
  138. /package/dist/ts4.2/{src/room → room}/RegionUrlProvider.d.ts +0 -0
  139. /package/dist/ts4.2/{src/room → room}/attribute-typings.d.ts +0 -0
  140. /package/dist/ts4.2/{src/room → room}/data-stream/incoming/StreamReader.d.ts +0 -0
  141. /package/dist/ts4.2/{src/room → room}/data-stream/outgoing/OutgoingDataStreamManager.d.ts +0 -0
  142. /package/dist/ts4.2/{src/room → room}/data-stream/outgoing/StreamWriter.d.ts +0 -0
  143. /package/dist/ts4.2/{src/room → room}/defaults.d.ts +0 -0
  144. /package/dist/ts4.2/{src/room → room}/events.d.ts +0 -0
  145. /package/dist/ts4.2/{src/room → room}/participant/ParticipantTrackPermission.d.ts +0 -0
  146. /package/dist/ts4.2/{src/room → room}/participant/RemoteParticipant.d.ts +0 -0
  147. /package/dist/ts4.2/{src/room → room}/participant/publishUtils.d.ts +0 -0
  148. /package/dist/ts4.2/{src/room → room}/rpc.d.ts +0 -0
  149. /package/dist/ts4.2/{src/room → room}/stats.d.ts +0 -0
  150. /package/dist/ts4.2/{src/room → room}/timers.d.ts +0 -0
  151. /package/dist/ts4.2/{src/room → room}/track/LocalAudioTrack.d.ts +0 -0
  152. /package/dist/ts4.2/{src/room → room}/track/LocalTrackPublication.d.ts +0 -0
  153. /package/dist/ts4.2/{src/room → room}/track/LocalVideoTrack.d.ts +0 -0
  154. /package/dist/ts4.2/{src/room → room}/track/RemoteAudioTrack.d.ts +0 -0
  155. /package/dist/ts4.2/{src/room → room}/track/RemoteTrack.d.ts +0 -0
  156. /package/dist/ts4.2/{src/room → room}/track/RemoteTrackPublication.d.ts +0 -0
  157. /package/dist/ts4.2/{src/room → room}/track/RemoteVideoTrack.d.ts +0 -0
  158. /package/dist/ts4.2/{src/room → room}/track/Track.d.ts +0 -0
  159. /package/dist/ts4.2/{src/room → room}/track/TrackPublication.d.ts +0 -0
  160. /package/dist/ts4.2/{src/room → room}/track/create.d.ts +0 -0
  161. /package/dist/ts4.2/{src/room → room}/track/facingMode.d.ts +0 -0
  162. /package/dist/ts4.2/{src/room → room}/track/processor/types.d.ts +0 -0
  163. /package/dist/ts4.2/{src/room → room}/track/record.d.ts +0 -0
  164. /package/dist/ts4.2/{src/room → room}/track/types.d.ts +0 -0
  165. /package/dist/ts4.2/{src/room → room}/track/utils.d.ts +0 -0
  166. /package/dist/ts4.2/{src/test → test}/MockMediaStreamTrack.d.ts +0 -0
  167. /package/dist/ts4.2/{src/test → test}/mocks.d.ts +0 -0
  168. /package/dist/ts4.2/{src/utils → utils}/AsyncQueue.d.ts +0 -0
  169. /package/dist/ts4.2/{src/utils → utils}/browserParser.d.ts +0 -0
  170. /package/dist/ts4.2/{src/utils → utils}/cloneDeep.d.ts +0 -0
  171. /package/dist/ts4.2/{src/utils → utils}/dataPacketBuffer.d.ts +0 -0
  172. /package/dist/ts4.2/{src/utils → utils}/ttlmap.d.ts +0 -0
  173. /package/dist/ts4.2/{src/version.d.ts → version.d.ts} +0 -0
@@ -369,6 +369,7 @@ var LoggerNames;
369
369
  (function (LoggerNames) {
370
370
  LoggerNames["Default"] = "livekit";
371
371
  LoggerNames["Room"] = "livekit-room";
372
+ LoggerNames["TokenSource"] = "livekit-token-source";
372
373
  LoggerNames["Participant"] = "livekit-participant";
373
374
  LoggerNames["Track"] = "livekit-track";
374
375
  LoggerNames["Publication"] = "livekit-track-publication";
@@ -516,6 +517,8 @@ var DataStreamErrorReason;
516
517
  DataStreamErrorReason[DataStreamErrorReason["Incomplete"] = 4] = "Incomplete";
517
518
  // Unable to register a stream handler more than once.
518
519
  DataStreamErrorReason[DataStreamErrorReason["HandlerAlreadyRegistered"] = 7] = "HandlerAlreadyRegistered";
520
+ // Encryption type mismatch.
521
+ DataStreamErrorReason[DataStreamErrorReason["EncryptionTypeMismatch"] = 8] = "EncryptionTypeMismatch";
519
522
  })(DataStreamErrorReason || (DataStreamErrorReason = {}));
520
523
  var MediaDeviceFailure;
521
524
  (function (MediaDeviceFailure) {
@@ -586,6 +589,218 @@ var CryptorEvent;
586
589
  CryptorEvent["Error"] = "cryptorError";
587
590
  })(CryptorEvent || (CryptorEvent = {}));
588
591
 
592
+ function isVideoFrame(frame) {
593
+ return 'type' in frame;
594
+ }
595
+ function importKey(keyBytes_1) {
596
+ return __awaiter(this, arguments, void 0, function (keyBytes) {
597
+ let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
598
+ name: ENCRYPTION_ALGORITHM
599
+ };
600
+ let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
601
+ return function* () {
602
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
603
+ return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
604
+ }();
605
+ });
606
+ }
607
+ function getAlgoOptions(algorithmName, salt) {
608
+ const textEncoder = new TextEncoder();
609
+ const encodedSalt = textEncoder.encode(salt);
610
+ switch (algorithmName) {
611
+ case 'HKDF':
612
+ return {
613
+ name: 'HKDF',
614
+ salt: encodedSalt,
615
+ hash: 'SHA-256',
616
+ info: new ArrayBuffer(128)
617
+ };
618
+ case 'PBKDF2':
619
+ {
620
+ return {
621
+ name: 'PBKDF2',
622
+ salt: encodedSalt,
623
+ hash: 'SHA-256',
624
+ iterations: 100000
625
+ };
626
+ }
627
+ default:
628
+ throw new Error("algorithm ".concat(algorithmName, " is currently unsupported"));
629
+ }
630
+ }
631
+ /**
632
+ * Derives a set of keys from the master key.
633
+ * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1
634
+ */
635
+ function deriveKeys(material, salt) {
636
+ return __awaiter(this, void 0, void 0, function* () {
637
+ const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
638
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF
639
+ // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams
640
+ const encryptionKey = yield crypto.subtle.deriveKey(algorithmOptions, material, {
641
+ name: ENCRYPTION_ALGORITHM,
642
+ length: 128
643
+ }, false, ['encrypt', 'decrypt']);
644
+ return {
645
+ material,
646
+ encryptionKey
647
+ };
648
+ });
649
+ }
650
+ /**
651
+ * Ratchets a key. See
652
+ * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
653
+ */
654
+ function ratchet(material, salt) {
655
+ return __awaiter(this, void 0, void 0, function* () {
656
+ const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
657
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits
658
+ return crypto.subtle.deriveBits(algorithmOptions, material, 256);
659
+ });
660
+ }
661
+ function needsRbspUnescaping(frameData) {
662
+ for (var i = 0; i < frameData.length - 3; i++) {
663
+ if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;
664
+ }
665
+ return false;
666
+ }
667
+ function parseRbsp(stream) {
668
+ const dataOut = [];
669
+ var length = stream.length;
670
+ for (var i = 0; i < stream.length;) {
671
+ // Be careful about over/underflow here. byte_length_ - 3 can underflow, and
672
+ // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
673
+ // above, and that expression will produce the number of bytes left in
674
+ // the stream including the byte at i.
675
+ if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {
676
+ // Two rbsp bytes.
677
+ dataOut.push(stream[i++]);
678
+ dataOut.push(stream[i++]);
679
+ // Skip the emulation byte.
680
+ i++;
681
+ } else {
682
+ // Single rbsp byte.
683
+ dataOut.push(stream[i++]);
684
+ }
685
+ }
686
+ return new Uint8Array(dataOut);
687
+ }
688
+ const kZerosInStartSequence = 2;
689
+ const kEmulationByte = 3;
690
+ function writeRbsp(data_in) {
691
+ const dataOut = [];
692
+ var numConsecutiveZeros = 0;
693
+ for (var i = 0; i < data_in.length; ++i) {
694
+ var byte = data_in[i];
695
+ if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {
696
+ // Need to escape.
697
+ dataOut.push(kEmulationByte);
698
+ numConsecutiveZeros = 0;
699
+ }
700
+ dataOut.push(byte);
701
+ if (byte == 0) {
702
+ ++numConsecutiveZeros;
703
+ } else {
704
+ numConsecutiveZeros = 0;
705
+ }
706
+ }
707
+ return new Uint8Array(dataOut);
708
+ }
709
+
710
+ class DataCryptor {
711
+ static makeIV(timestamp) {
712
+ const iv = new ArrayBuffer(12);
713
+ const ivView = new DataView(iv);
714
+ const randomBytes = crypto.getRandomValues(new Uint32Array(1));
715
+ ivView.setUint32(0, randomBytes[0]);
716
+ ivView.setUint32(4, timestamp);
717
+ ivView.setUint32(8, timestamp - DataCryptor.sendCount % 0xffff);
718
+ DataCryptor.sendCount++;
719
+ return iv;
720
+ }
721
+ static encrypt(data, keys) {
722
+ return __awaiter(this, void 0, void 0, function* () {
723
+ const iv = DataCryptor.makeIV(performance.now());
724
+ const keySet = yield keys.getKeySet();
725
+ if (!keySet) {
726
+ throw new Error('No key set found');
727
+ }
728
+ const cipherText = yield crypto.subtle.encrypt({
729
+ name: ENCRYPTION_ALGORITHM,
730
+ iv
731
+ }, keySet.encryptionKey, new Uint8Array(data));
732
+ return {
733
+ payload: new Uint8Array(cipherText),
734
+ iv: new Uint8Array(iv),
735
+ keyIndex: keys.getCurrentKeyIndex()
736
+ };
737
+ });
738
+ }
739
+ static decrypt(data_1, iv_1, keys_1) {
740
+ return __awaiter(this, arguments, void 0, function (data, iv, keys) {
741
+ let keyIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
742
+ let initialMaterial = arguments.length > 4 ? arguments[4] : undefined;
743
+ let ratchetOpts = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
744
+ ratchetCount: 0
745
+ };
746
+ return function* () {
747
+ const keySet = yield keys.getKeySet(keyIndex);
748
+ if (!keySet) {
749
+ throw new Error('No key set found');
750
+ }
751
+ try {
752
+ const plainText = yield crypto.subtle.decrypt({
753
+ name: ENCRYPTION_ALGORITHM,
754
+ iv
755
+ }, keySet.encryptionKey, new Uint8Array(data));
756
+ return {
757
+ payload: new Uint8Array(plainText)
758
+ };
759
+ } catch (error) {
760
+ if (keys.keyProviderOptions.ratchetWindowSize > 0) {
761
+ if (ratchetOpts.ratchetCount < keys.keyProviderOptions.ratchetWindowSize) {
762
+ workerLogger.debug("DataCryptor: ratcheting key attempt ".concat(ratchetOpts.ratchetCount, " of ").concat(keys.keyProviderOptions.ratchetWindowSize, ", for data packet"));
763
+ let ratchetedKeySet;
764
+ let ratchetResult;
765
+ if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === keys.getKeySet(keyIndex)) {
766
+ // only ratchet if the currently set key is still the same as the one used to decrypt this frame
767
+ // if not, it might be that a different frame has already ratcheted and we try with that one first
768
+ ratchetResult = yield keys.ratchetKey(keyIndex, false);
769
+ ratchetedKeySet = yield deriveKeys(ratchetResult.cryptoKey, keys.keyProviderOptions.ratchetSalt);
770
+ }
771
+ const decryptedData = yield DataCryptor.decrypt(data, iv, keys, keyIndex, initialMaterial, {
772
+ ratchetCount: ratchetOpts.ratchetCount + 1,
773
+ encryptionKey: ratchetedKeySet === null || ratchetedKeySet === void 0 ? void 0 : ratchetedKeySet.encryptionKey
774
+ });
775
+ if (decryptedData && ratchetedKeySet) {
776
+ // before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key
777
+ // if it's not, a new key might have been set already, which we don't want to override
778
+ if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === keys.getKeySet(keyIndex)) {
779
+ keys.setKeySet(ratchetedKeySet, keyIndex, ratchetResult);
780
+ // decryption was successful, set the new key index to reflect the ratcheted key set
781
+ keys.setCurrentKeyIndex(keyIndex);
782
+ }
783
+ }
784
+ return decryptedData;
785
+ } else {
786
+ /**
787
+ * Because we only set a new key once decryption has been successful,
788
+ * we can be sure that we don't need to reset the key to the initial material at this point
789
+ * as the key has not been updated on the keyHandler instance
790
+ */
791
+ workerLogger.warn('DataCryptor: maximum ratchet attempts exceeded');
792
+ throw new CryptorError("DataCryptor: valid key missing for participant ".concat(keys.participantIdentity), CryptorErrorReason.InvalidKey, keys.participantIdentity);
793
+ }
794
+ } else {
795
+ throw new CryptorError("DataCryptor: Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey, keys.participantIdentity);
796
+ }
797
+ }
798
+ }();
799
+ });
800
+ }
801
+ }
802
+ DataCryptor.sendCount = 0;
803
+
589
804
  var events = {exports: {}};
590
805
 
591
806
  var hasRequiredEvents;
@@ -973,124 +1188,6 @@ function requireEvents() {
973
1188
 
974
1189
  var eventsExports = requireEvents();
975
1190
 
976
- function isVideoFrame(frame) {
977
- return 'type' in frame;
978
- }
979
- function importKey(keyBytes_1) {
980
- return __awaiter(this, arguments, void 0, function (keyBytes) {
981
- let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
982
- name: ENCRYPTION_ALGORITHM
983
- };
984
- let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
985
- return function* () {
986
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
987
- return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
988
- }();
989
- });
990
- }
991
- function getAlgoOptions(algorithmName, salt) {
992
- const textEncoder = new TextEncoder();
993
- const encodedSalt = textEncoder.encode(salt);
994
- switch (algorithmName) {
995
- case 'HKDF':
996
- return {
997
- name: 'HKDF',
998
- salt: encodedSalt,
999
- hash: 'SHA-256',
1000
- info: new ArrayBuffer(128)
1001
- };
1002
- case 'PBKDF2':
1003
- {
1004
- return {
1005
- name: 'PBKDF2',
1006
- salt: encodedSalt,
1007
- hash: 'SHA-256',
1008
- iterations: 100000
1009
- };
1010
- }
1011
- default:
1012
- throw new Error("algorithm ".concat(algorithmName, " is currently unsupported"));
1013
- }
1014
- }
1015
- /**
1016
- * Derives a set of keys from the master key.
1017
- * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1
1018
- */
1019
- function deriveKeys(material, salt) {
1020
- return __awaiter(this, void 0, void 0, function* () {
1021
- const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
1022
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF
1023
- // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams
1024
- const encryptionKey = yield crypto.subtle.deriveKey(algorithmOptions, material, {
1025
- name: ENCRYPTION_ALGORITHM,
1026
- length: 128
1027
- }, false, ['encrypt', 'decrypt']);
1028
- return {
1029
- material,
1030
- encryptionKey
1031
- };
1032
- });
1033
- }
1034
- /**
1035
- * Ratchets a key. See
1036
- * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
1037
- */
1038
- function ratchet(material, salt) {
1039
- return __awaiter(this, void 0, void 0, function* () {
1040
- const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
1041
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits
1042
- return crypto.subtle.deriveBits(algorithmOptions, material, 256);
1043
- });
1044
- }
1045
- function needsRbspUnescaping(frameData) {
1046
- for (var i = 0; i < frameData.length - 3; i++) {
1047
- if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;
1048
- }
1049
- return false;
1050
- }
1051
- function parseRbsp(stream) {
1052
- const dataOut = [];
1053
- var length = stream.length;
1054
- for (var i = 0; i < stream.length;) {
1055
- // Be careful about over/underflow here. byte_length_ - 3 can underflow, and
1056
- // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
1057
- // above, and that expression will produce the number of bytes left in
1058
- // the stream including the byte at i.
1059
- if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {
1060
- // Two rbsp bytes.
1061
- dataOut.push(stream[i++]);
1062
- dataOut.push(stream[i++]);
1063
- // Skip the emulation byte.
1064
- i++;
1065
- } else {
1066
- // Single rbsp byte.
1067
- dataOut.push(stream[i++]);
1068
- }
1069
- }
1070
- return new Uint8Array(dataOut);
1071
- }
1072
- const kZerosInStartSequence = 2;
1073
- const kEmulationByte = 3;
1074
- function writeRbsp(data_in) {
1075
- const dataOut = [];
1076
- var numConsecutiveZeros = 0;
1077
- for (var i = 0; i < data_in.length; ++i) {
1078
- var byte = data_in[i];
1079
- if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {
1080
- // Need to escape.
1081
- dataOut.push(kEmulationByte);
1082
- numConsecutiveZeros = 0;
1083
- }
1084
- dataOut.push(byte);
1085
- if (byte == 0) {
1086
- ++numConsecutiveZeros;
1087
- } else {
1088
- numConsecutiveZeros = 0;
1089
- }
1090
- }
1091
- return new Uint8Array(dataOut);
1092
- }
1093
-
1094
1191
  /**
1095
1192
  * NALU (Network Abstraction Layer Unit) utilities for H.264 and H.265 video processing
1096
1193
  * Contains functions for parsing and working with NALUs in video frames
@@ -2082,6 +2179,44 @@ onmessage = ev => {
2082
2179
  let pubCryptor = getTrackCryptor(data.participantIdentity, data.trackId);
2083
2180
  pubCryptor.setupTransform(kind, data.readableStream, data.writableStream, data.trackId, data.isReuse, data.codec);
2084
2181
  break;
2182
+ case 'encryptDataRequest':
2183
+ const {
2184
+ payload: encryptedPayload,
2185
+ iv,
2186
+ keyIndex
2187
+ } = yield DataCryptor.encrypt(data.payload, getParticipantKeyHandler(data.participantIdentity));
2188
+ console.log('encrypted payload', {
2189
+ original: data.payload,
2190
+ encrypted: encryptedPayload,
2191
+ iv
2192
+ });
2193
+ postMessage({
2194
+ kind: 'encryptDataResponse',
2195
+ data: {
2196
+ payload: encryptedPayload,
2197
+ iv,
2198
+ keyIndex,
2199
+ uuid: data.uuid
2200
+ }
2201
+ });
2202
+ break;
2203
+ case 'decryptDataRequest':
2204
+ const {
2205
+ payload: decryptedPayload
2206
+ } = yield DataCryptor.decrypt(data.payload, data.iv, getParticipantKeyHandler(data.participantIdentity), data.keyIndex);
2207
+ console.log('decrypted payload', {
2208
+ original: data.payload,
2209
+ decrypted: decryptedPayload,
2210
+ iv: data.iv
2211
+ });
2212
+ postMessage({
2213
+ kind: 'decryptDataResponse',
2214
+ data: {
2215
+ payload: decryptedPayload,
2216
+ uuid: data.uuid
2217
+ }
2218
+ });
2219
+ break;
2085
2220
  case 'setKey':
2086
2221
  if (useSharedKey) {
2087
2222
  yield setSharedKey(data.key, data.keyIndex);