@livekit/react-native 2.9.1 → 2.9.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 (34) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/consumer-rules.pro +1 -0
  3. package/android/src/main/AndroidManifest.xml +0 -1
  4. package/ios/AudioUtils.swift +38 -3
  5. package/ios/LiveKitReactNativeModule.swift +76 -79
  6. package/ios/LivekitReactNativeModule.m +7 -3
  7. package/lib/commonjs/audio/MediaRecorder.js +2 -2
  8. package/lib/commonjs/audio/MediaRecorder.js.map +1 -1
  9. package/lib/commonjs/e2ee/RNE2EEManager.js +73 -1
  10. package/lib/commonjs/e2ee/RNE2EEManager.js.map +1 -1
  11. package/lib/commonjs/hooks/useE2EEManager.js +1 -1
  12. package/lib/commonjs/hooks/useE2EEManager.js.map +1 -1
  13. package/lib/commonjs/index.js +10 -3
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/module/audio/MediaRecorder.js +1 -1
  16. package/lib/module/audio/MediaRecorder.js.map +1 -1
  17. package/lib/module/e2ee/RNE2EEManager.js +75 -3
  18. package/lib/module/e2ee/RNE2EEManager.js.map +1 -1
  19. package/lib/module/hooks/useE2EEManager.js +1 -1
  20. package/lib/module/hooks/useE2EEManager.js.map +1 -1
  21. package/lib/module/index.js +10 -4
  22. package/lib/module/index.js.map +1 -1
  23. package/lib/typescript/lib/commonjs/e2ee/RNE2EEManager.d.ts +17 -1
  24. package/lib/typescript/lib/commonjs/index.d.ts +3 -1
  25. package/lib/typescript/lib/module/e2ee/RNE2EEManager.d.ts +17 -1
  26. package/lib/typescript/lib/module/index.d.ts +3 -1
  27. package/lib/typescript/src/e2ee/RNE2EEManager.d.ts +11 -2
  28. package/lib/typescript/src/hooks/useE2EEManager.d.ts +2 -2
  29. package/lib/typescript/src/index.d.ts +13 -2
  30. package/package.json +7 -6
  31. package/src/audio/MediaRecorder.ts +1 -1
  32. package/src/e2ee/RNE2EEManager.ts +117 -2
  33. package/src/hooks/useE2EEManager.ts +3 -2
  34. package/src/index.tsx +22 -3
@@ -34,7 +34,7 @@ android {
34
34
  targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
35
35
  versionCode 1
36
36
  versionName "1.0"
37
-
37
+ consumerProguardFiles 'consumer-rules.pro'
38
38
  }
39
39
 
40
40
  buildTypes {
@@ -0,0 +1 @@
1
+ -keep class com.livekit.** { *; }
@@ -6,7 +6,6 @@
6
6
  <uses-permission android:name="android.permission.CAMERA" />
7
7
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
8
8
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
9
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
10
9
  <uses-permission android:name="android.permission.WAKE_LOCK" />
11
10
  <uses-permission android:name="android.permission.BLUETOOTH" />
12
11
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
@@ -6,7 +6,11 @@ public class AudioUtils {
6
6
  case "default_":
7
7
  .default
8
8
  case "voicePrompt":
9
- .voicePrompt
9
+ if #available(iOS 12.0, *) {
10
+ .voicePrompt
11
+ } else {
12
+ .default
13
+ }
10
14
  case "videoRecording":
11
15
  .videoRecording
12
16
  case "videoChat":
@@ -26,7 +30,7 @@ public class AudioUtils {
26
30
  }
27
31
  return retMode
28
32
  }
29
-
33
+
30
34
  public static func audioSessionCategoryFromString(_ category: String) -> AVAudioSession.Category {
31
35
  let retCategory: AVAudioSession.Category = switch category {
32
36
  case "ambient":
@@ -42,8 +46,39 @@ public class AudioUtils {
42
46
  case "multiRoute":
43
47
  .multiRoute
44
48
  default:
45
- .ambient
49
+ .soloAmbient
46
50
  }
47
51
  return retCategory
48
52
  }
53
+
54
+ public static func audioSessionCategoryOptionsFromStrings(_ options: [String]) -> AVAudioSession.CategoryOptions {
55
+ var categoryOptions: AVAudioSession.CategoryOptions = []
56
+ for option in options {
57
+ switch option {
58
+ case "mixWithOthers":
59
+ categoryOptions.insert(.mixWithOthers)
60
+ case "duckOthers":
61
+ categoryOptions.insert(.duckOthers)
62
+ case "allowBluetooth":
63
+ categoryOptions.insert(.allowBluetooth)
64
+ case "allowBluetoothA2DP":
65
+ categoryOptions.insert(.allowBluetoothA2DP)
66
+ case "allowAirPlay":
67
+ categoryOptions.insert(.allowAirPlay)
68
+ case "defaultToSpeaker":
69
+ categoryOptions.insert(.defaultToSpeaker)
70
+ case "interruptSpokenAudioAndMixWithOthers":
71
+ if #available(iOS 13.0, *) {
72
+ categoryOptions.insert(.interruptSpokenAudioAndMixWithOthers)
73
+ }
74
+ case "overrideMutedMicrophoneInterruption":
75
+ if #available(iOS 14.5, *) {
76
+ categoryOptions.insert(.overrideMutedMicrophoneInterruption)
77
+ }
78
+ default:
79
+ break
80
+ }
81
+ }
82
+ return categoryOptions
83
+ }
49
84
  }
@@ -11,7 +11,7 @@ struct LKEvents {
11
11
 
12
12
  @objc(LivekitReactNativeModule)
13
13
  public class LivekitReactNativeModule: RCTEventEmitter {
14
-
14
+
15
15
  // This cannot be initialized in init as self.bridge is given afterwards.
16
16
  private var _audioRendererManager: AudioRendererManager? = nil
17
17
  public var audioRendererManager: AudioRendererManager {
@@ -19,11 +19,11 @@ public class LivekitReactNativeModule: RCTEventEmitter {
19
19
  if _audioRendererManager == nil {
20
20
  _audioRendererManager = AudioRendererManager(bridge: self.bridge)
21
21
  }
22
-
22
+
23
23
  return _audioRendererManager!
24
24
  }
25
25
  }
26
-
26
+
27
27
  @objc
28
28
  public override init() {
29
29
  super.init()
@@ -31,10 +31,10 @@ public class LivekitReactNativeModule: RCTEventEmitter {
31
31
  config.category = AVAudioSession.Category.playAndRecord.rawValue
32
32
  config.categoryOptions = [.allowAirPlay, .allowBluetooth, .allowBluetoothA2DP, .defaultToSpeaker]
33
33
  config.mode = AVAudioSession.Mode.videoChat.rawValue
34
-
34
+
35
35
  RTCAudioSessionConfiguration.setWebRTC(config)
36
36
  }
37
-
37
+
38
38
  @objc
39
39
  override public static func requiresMainQueueSetup() -> Bool {
40
40
  return false
@@ -48,19 +48,19 @@ public class LivekitReactNativeModule: RCTEventEmitter {
48
48
  options.videoEncoderFactory = simulcastVideoEncoderFactory
49
49
  options.audioProcessingModule = LKAudioProcessingManager.sharedInstance().audioProcessingModule
50
50
  }
51
-
51
+
52
52
  @objc(configureAudio:)
53
53
  public func configureAudio(_ config: NSDictionary) {
54
54
  guard let iOSConfig = config["ios"] as? NSDictionary
55
55
  else {
56
56
  return
57
57
  }
58
-
58
+
59
59
  let defaultOutput = iOSConfig["defaultOutput"] as? String ?? "speaker"
60
-
60
+
61
61
  let rtcConfig = RTCAudioSessionConfiguration()
62
62
  rtcConfig.category = AVAudioSession.Category.playAndRecord.rawValue
63
-
63
+
64
64
  if (defaultOutput == "earpiece") {
65
65
  rtcConfig.categoryOptions = [.allowAirPlay, .allowBluetooth, .allowBluetoothA2DP];
66
66
  rtcConfig.mode = AVAudioSession.Mode.voiceChat.rawValue
@@ -70,17 +70,39 @@ public class LivekitReactNativeModule: RCTEventEmitter {
70
70
  }
71
71
  RTCAudioSessionConfiguration.setWebRTC(rtcConfig)
72
72
  }
73
-
74
- @objc(startAudioSession)
75
- public func startAudioSession() {
76
- // intentionally left empty
73
+
74
+ @objc(startAudioSession:withRejecter:)
75
+ public func startAudioSession(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
76
+ let session = RTCAudioSession.sharedInstance()
77
+ session.lockForConfiguration()
78
+ defer {
79
+ session.unlockForConfiguration()
80
+ }
81
+
82
+ do {
83
+ try session.setActive(true)
84
+ resolve(nil)
85
+ } catch {
86
+ reject("startAudioSession", "Error activating audio session: \(error.localizedDescription)", error)
87
+ }
77
88
  }
78
-
79
- @objc(stopAudioSession)
80
- public func stopAudioSession() {
81
- // intentionally left empty
89
+
90
+ @objc(stopAudioSession:withRejecter:)
91
+ public func stopAudioSession(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
92
+ let session = RTCAudioSession.sharedInstance()
93
+ session.lockForConfiguration()
94
+ defer {
95
+ session.unlockForConfiguration()
96
+ }
97
+
98
+ do {
99
+ try session.setActive(false)
100
+ resolve(nil)
101
+ } catch {
102
+ reject("stopAudioSession", "Error deactivating audio session: \(error.localizedDescription)", error)
103
+ }
82
104
  }
83
-
105
+
84
106
  @objc(showAudioRoutePicker)
85
107
  public func showAudioRoutePicker() {
86
108
  if #available(iOS 11.0, *) {
@@ -95,12 +117,12 @@ public class LivekitReactNativeModule: RCTEventEmitter {
95
117
  }
96
118
  }
97
119
  }
98
-
120
+
99
121
  @objc(getAudioOutputsWithResolver:withRejecter:)
100
122
  public func getAudioOutputs(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock){
101
123
  resolve(["default", "force_speaker"])
102
124
  }
103
-
125
+
104
126
  @objc(selectAudioOutput:withResolver:withRejecter:)
105
127
  public func selectAudioOutput(_ deviceId: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
106
128
  let session = AVAudioSession.sharedInstance()
@@ -114,78 +136,53 @@ public class LivekitReactNativeModule: RCTEventEmitter {
114
136
  reject("selectAudioOutput error", error.localizedDescription, error)
115
137
  return
116
138
  }
117
-
139
+
118
140
  resolve(nil)
119
141
  }
120
-
121
- @objc(setAppleAudioConfiguration:)
122
- public func setAppleAudioConfiguration(_ configuration: NSDictionary) {
142
+
143
+ @objc(setAppleAudioConfiguration:withResolver:withRejecter:)
144
+ public func setAppleAudioConfiguration(_ configuration: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
123
145
  let session = RTCAudioSession.sharedInstance()
124
146
  let config = RTCAudioSessionConfiguration.webRTC()
125
-
147
+
126
148
  let appleAudioCategory = configuration["audioCategory"] as? String
127
149
  let appleAudioCategoryOptions = configuration["audioCategoryOptions"] as? [String]
128
150
  let appleAudioMode = configuration["audioMode"] as? String
129
-
151
+
130
152
  session.lockForConfiguration()
131
-
132
- var categoryChanged = false
133
-
134
- if let appleAudioCategoryOptions = appleAudioCategoryOptions {
135
- categoryChanged = true
136
-
137
- var newOptions: AVAudioSession.CategoryOptions = []
138
- for option in appleAudioCategoryOptions {
139
- if option == "mixWithOthers" {
140
- newOptions.insert(.mixWithOthers)
141
- } else if option == "duckOthers" {
142
- newOptions.insert(.duckOthers)
143
- } else if option == "allowBluetooth" {
144
- newOptions.insert(.allowBluetooth)
145
- } else if option == "allowBluetoothA2DP" {
146
- newOptions.insert(.allowBluetoothA2DP)
147
- } else if option == "allowAirPlay" {
148
- newOptions.insert(.allowAirPlay)
149
- } else if option == "defaultToSpeaker" {
150
- newOptions.insert(.defaultToSpeaker)
151
- }
152
- }
153
- config.categoryOptions = newOptions
153
+ defer {
154
+ session.unlockForConfiguration()
154
155
  }
155
-
156
+
156
157
  if let appleAudioCategory = appleAudioCategory {
157
- categoryChanged = true
158
158
  config.category = AudioUtils.audioSessionCategoryFromString(appleAudioCategory).rawValue
159
159
  }
160
-
161
- if categoryChanged {
162
- do {
163
- try session.setCategory(AVAudioSession.Category(rawValue: config.category), with: config.categoryOptions)
164
- } catch {
165
- NSLog("Error setting category: %@", error.localizedDescription)
166
- }
160
+
161
+ if let appleAudioCategoryOptions = appleAudioCategoryOptions {
162
+ config.categoryOptions = AudioUtils.audioSessionCategoryOptionsFromStrings(appleAudioCategoryOptions)
167
163
  }
168
-
164
+
169
165
  if let appleAudioMode = appleAudioMode {
170
- let mode = AudioUtils.audioSessionModeFromString(appleAudioMode)
171
- config.mode = mode.rawValue
172
- do {
173
- try session.setMode(mode)
174
- } catch {
175
- NSLog("Error setting mode: %@", error.localizedDescription)
176
- }
166
+ config.mode = AudioUtils.audioSessionModeFromString(appleAudioMode).rawValue
177
167
  }
178
-
179
- session.unlockForConfiguration()
168
+
169
+ do {
170
+ try session.setConfiguration(config)
171
+ resolve(nil)
172
+ } catch {
173
+ reject("setAppleAudioConfiguration", "Error setting category: \(error.localizedDescription)", error)
174
+ return
175
+ }
176
+
180
177
  }
181
-
178
+
182
179
  @objc(createAudioSinkListener:trackId:)
183
180
  public func createAudioSinkListener(_ pcId: NSNumber, trackId: String) -> String {
184
181
  let renderer = AudioSinkRenderer(eventEmitter: self)
185
182
  let reactTag = self.audioRendererManager.registerRenderer(renderer)
186
183
  renderer.reactTag = reactTag
187
184
  self.audioRendererManager.attach(renderer: renderer, pcId: pcId, trackId: trackId)
188
-
185
+
189
186
  return reactTag
190
187
  }
191
188
 
@@ -193,7 +190,7 @@ public class LivekitReactNativeModule: RCTEventEmitter {
193
190
  public func deleteAudioSinkListener(_ reactTag: String, pcId: NSNumber, trackId: String) -> Any? {
194
191
  self.audioRendererManager.detach(rendererByTag: reactTag, pcId: pcId, trackId: trackId)
195
192
  self.audioRendererManager.unregisterRenderer(forReactTag: reactTag)
196
-
193
+
197
194
  return nil
198
195
  }
199
196
 
@@ -203,7 +200,7 @@ public class LivekitReactNativeModule: RCTEventEmitter {
203
200
  let reactTag = self.audioRendererManager.registerRenderer(renderer)
204
201
  renderer.reactTag = reactTag
205
202
  self.audioRendererManager.attach(renderer: renderer, pcId: pcId, trackId: trackId)
206
-
203
+
207
204
  return reactTag
208
205
  }
209
206
 
@@ -211,7 +208,7 @@ public class LivekitReactNativeModule: RCTEventEmitter {
211
208
  public func deleteVolumeProcessor(_ reactTag: String, pcId: NSNumber, trackId: String) -> Any? {
212
209
  self.audioRendererManager.detach(rendererByTag: reactTag, pcId: pcId, trackId: trackId)
213
210
  self.audioRendererManager.unregisterRenderer(forReactTag: reactTag)
214
-
211
+
215
212
  return nil
216
213
  }
217
214
 
@@ -221,7 +218,7 @@ public class LivekitReactNativeModule: RCTEventEmitter {
221
218
  let minFrequency = (options["minFrequency"] as? NSNumber)?.floatValue ?? 1000
222
219
  let maxFrequency = (options["maxFrequency"] as? NSNumber)?.floatValue ?? 8000
223
220
  let intervalMs = (options["updateInterval"] as? NSNumber)?.floatValue ?? 40
224
-
221
+
225
222
  let renderer = MultibandVolumeAudioRenderer(
226
223
  bands: bands,
227
224
  minFrequency: minFrequency,
@@ -232,18 +229,18 @@ public class LivekitReactNativeModule: RCTEventEmitter {
232
229
  let reactTag = self.audioRendererManager.registerRenderer(renderer)
233
230
  renderer.reactTag = reactTag
234
231
  self.audioRendererManager.attach(renderer: renderer, pcId: pcId, trackId: trackId)
235
-
232
+
236
233
  return reactTag
237
234
  }
238
-
235
+
239
236
  @objc(deleteMultibandVolumeProcessor:pcId:trackId:)
240
237
  public func deleteMultibandVolumeProcessor(_ reactTag: String, pcId: NSNumber, trackId: String) -> Any? {
241
238
  self.audioRendererManager.detach(rendererByTag: reactTag, pcId: pcId, trackId: trackId)
242
239
  self.audioRendererManager.unregisterRenderer(forReactTag: reactTag)
243
-
240
+
244
241
  return nil
245
242
  }
246
-
243
+
247
244
  @objc(setDefaultAudioTrackVolume:)
248
245
  public func setDefaultAudioTrackVolume(_ volume: NSNumber) -> Any? {
249
246
  let options = WebRTCModuleOptions.sharedInstance()
@@ -251,7 +248,7 @@ public class LivekitReactNativeModule: RCTEventEmitter {
251
248
 
252
249
  return nil
253
250
  }
254
-
251
+
255
252
  override public func supportedEvents() -> [String]! {
256
253
  return [
257
254
  LKEvents.kEventVolumeProcessed,
@@ -5,8 +5,10 @@
5
5
  @interface RCT_EXTERN_MODULE(LivekitReactNativeModule, RCTEventEmitter)
6
6
 
7
7
  RCT_EXTERN_METHOD(configureAudio:(NSDictionary *) config)
8
- RCT_EXTERN_METHOD(startAudioSession)
9
- RCT_EXTERN_METHOD(stopAudioSession)
8
+ RCT_EXTERN_METHOD(startAudioSession:(RCTPromiseResolveBlock)resolve
9
+ withRejecter:(RCTPromiseRejectBlock)reject)
10
+ RCT_EXTERN_METHOD(stopAudioSession:(RCTPromiseResolveBlock)resolve
11
+ withRejecter:(RCTPromiseRejectBlock)reject)
10
12
 
11
13
  RCT_EXTERN_METHOD(setDefaultAudioTrackVolume:(nonnull NSNumber *) volume)
12
14
 
@@ -19,7 +21,9 @@ RCT_EXTERN_METHOD(selectAudioOutput:(NSString *)deviceId
19
21
 
20
22
 
21
23
  /// Configure audio config for WebRTC
22
- RCT_EXTERN_METHOD(setAppleAudioConfiguration:(NSDictionary *) configuration)
24
+ RCT_EXTERN_METHOD(setAppleAudioConfiguration:(NSDictionary *)configuration
25
+ withResolver:(RCTPromiseResolveBlock)resolve
26
+ withRejecter:(RCTPromiseRejectBlock)reject)
23
27
 
24
28
  RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(createAudioSinkListener:(nonnull NSNumber *)pcId
25
29
  trackId:(nonnull NSString *)trackId)
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.MediaRecorder = void 0;
7
7
  var _EventEmitter = require("../events/EventEmitter");
8
8
  var _index = require("event-target-shim/index");
9
- var _reactNativeQuickBase = require("react-native-quick-base64");
9
+ var _base64Js = require("base64-js");
10
10
  var _LKNativeModule = _interopRequireDefault(require("../LKNativeModule"));
11
11
  var _logger = require("../logger");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -92,7 +92,7 @@ class MediaRecorder extends _index.EventTarget {
92
92
  }
93
93
  dispatchData() {
94
94
  let combinedStr = this._parts.reduce((sum, cur) => sum + cur, '');
95
- let data = (0, _reactNativeQuickBase.toByteArray)(combinedStr);
95
+ let data = (0, _base64Js.toByteArray)(combinedStr);
96
96
  this._parts = [];
97
97
  this.dispatchEvent(new BlobEvent('dataavailable', {
98
98
  data: {
@@ -1 +1 @@
1
- {"version":3,"names":["_EventEmitter","require","_index","_reactNativeQuickBase","_LKNativeModule","_interopRequireDefault","_logger","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","MediaRecorder","EventTarget","constructor","stream","undefined","registerListener","audioTracks","getAudioTracks","length","mediaStreamTrack","peerConnectionId","_peerConnectionId","mediaStreamTrackId","id","_reactTag","LiveKitModule","createAudioSinkListener","addListener","event","state","str","data","_parts","push","unregisterListener","log","error","deleteAudioSinkListener","pause","dispatchEvent","Event","resume","start","stop","dispatchData","requestData","combinedStr","reduce","sum","cur","toByteArray","BlobEvent","byteArray","exports","type","eventInitDict","proto","prototype","defineEventAttribute"],"sources":["MediaRecorder.ts"],"sourcesContent":["import type { MediaStream } from '@livekit/react-native-webrtc';\nimport { addListener } from '../events/EventEmitter';\nimport {\n EventTarget,\n Event,\n defineEventAttribute,\n} from 'event-target-shim/index';\nimport { toByteArray } from 'react-native-quick-base64';\nimport LiveKitModule from '../LKNativeModule';\nimport { log } from '../logger';\n\n// typeof MediaRecorder\n// const Tester = (stream: MediaStream) => {\n// return new AudioRecorder(stream) satisfies MediaRecorder;\n// };\n\ntype MediaRecorderState = 'inactive' | 'recording' | 'paused';\ntype MediaRecorderEventMap = {\n dataavailable: BlobEvent<'dataavailable'>;\n error: Event<'error'>;\n pause: Event<'pause'>;\n resume: Event<'resume'>;\n start: Event<'start'>;\n stop: Event<'stop'>;\n};\n\n/**\n * A MediaRecord implementation only meant for recording audio streams.\n *\n * @private\n */\nexport class MediaRecorder extends EventTarget<MediaRecorderEventMap> {\n mimeType: String = 'audio/pcm';\n audioBitsPerSecond: number = 0; // TODO?\n state: MediaRecorderState = 'inactive';\n stream: MediaStream;\n videoBitsPerSecond: number = 0; // TODO?\n audioBitrateMode = 'constant';\n\n _reactTag: string | undefined = undefined;\n _parts: string[] = [];\n constructor(stream: MediaStream) {\n super();\n this.stream = stream;\n }\n\n registerListener() {\n let audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length !== 1) {\n return;\n }\n const mediaStreamTrack = audioTracks[0];\n const peerConnectionId = mediaStreamTrack._peerConnectionId ?? -1;\n const mediaStreamTrackId = mediaStreamTrack?.id;\n this._reactTag = LiveKitModule.createAudioSinkListener(\n peerConnectionId,\n mediaStreamTrackId\n );\n addListener(this, 'LK_AUDIO_DATA', (event: any) => {\n if (\n this._reactTag &&\n event.id === this._reactTag &&\n this.state === 'recording'\n ) {\n let str = event.data as string;\n this._parts.push(str);\n }\n });\n }\n\n unregisterListener() {\n if (this._reactTag) {\n let audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length !== 1) {\n log.error(\"couldn't find any audio tracks to record from!\");\n return;\n }\n const mediaStreamTrack = audioTracks[0];\n const peerConnectionId = mediaStreamTrack._peerConnectionId ?? -1;\n const mediaStreamTrackId = mediaStreamTrack?.id;\n\n LiveKitModule.deleteAudioSinkListener(\n this._reactTag,\n peerConnectionId,\n mediaStreamTrackId\n );\n }\n }\n\n pause() {\n this.state = 'paused';\n this.dispatchEvent(new Event('pause'));\n }\n\n resume() {\n this.state = 'recording';\n this.dispatchEvent(new Event('resume'));\n }\n\n start() {\n this.registerListener();\n this.state = 'recording';\n this.dispatchEvent(new Event('start'));\n }\n\n stop() {\n // dispatch data must come before stopping.\n this.dispatchData();\n\n this.unregisterListener();\n this.state = 'inactive';\n this.dispatchEvent(new Event('stop'));\n }\n\n requestData() {\n this.dispatchData();\n }\n dispatchData() {\n let combinedStr = this._parts.reduce((sum, cur) => sum + cur, '');\n let data = toByteArray(combinedStr);\n this._parts = [];\n this.dispatchEvent(\n new BlobEvent('dataavailable', { data: { byteArray: data } })\n );\n }\n}\n\n/**\n * @eventClass\n * This event is fired whenever the Track is changed in PeerConnection.\n * @param {TRACK_EVENTS} type - The type of event.\n * @param {IRTCTrackEventInitDict} eventInitDict - The event init properties.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/track_event MDN} for details.\n */\nclass BlobEvent<TEventType extends string> extends Event<TEventType> {\n /** @eventProperty */\n readonly data: { byteArray: Uint8Array };\n\n constructor(\n type: TEventType,\n eventInitDict: { data: { byteArray: Uint8Array } } & Event.EventInit\n ) {\n super(type, eventInitDict);\n this.data = eventInitDict.data;\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaRecorder.prototype;\n\ndefineEventAttribute(proto, 'dataavailable');\ndefineEventAttribute(proto, 'error');\ndefineEventAttribute(proto, 'pause');\ndefineEventAttribute(proto, 'resume');\ndefineEventAttribute(proto, 'start');\ndefineEventAttribute(proto, 'stop');\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_EventEmitter","require","_index","_base64Js","_LKNativeModule","_interopRequireDefault","_logger","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","MediaRecorder","EventTarget","constructor","stream","undefined","registerListener","audioTracks","getAudioTracks","length","mediaStreamTrack","peerConnectionId","_peerConnectionId","mediaStreamTrackId","id","_reactTag","LiveKitModule","createAudioSinkListener","addListener","event","state","str","data","_parts","push","unregisterListener","log","error","deleteAudioSinkListener","pause","dispatchEvent","Event","resume","start","stop","dispatchData","requestData","combinedStr","reduce","sum","cur","toByteArray","BlobEvent","byteArray","exports","type","eventInitDict","proto","prototype","defineEventAttribute"],"sources":["MediaRecorder.ts"],"sourcesContent":["import type { MediaStream } from '@livekit/react-native-webrtc';\nimport { addListener } from '../events/EventEmitter';\nimport {\n EventTarget,\n Event,\n defineEventAttribute,\n} from 'event-target-shim/index';\nimport { toByteArray } from 'base64-js';\nimport LiveKitModule from '../LKNativeModule';\nimport { log } from '../logger';\n\n// typeof MediaRecorder\n// const Tester = (stream: MediaStream) => {\n// return new AudioRecorder(stream) satisfies MediaRecorder;\n// };\n\ntype MediaRecorderState = 'inactive' | 'recording' | 'paused';\ntype MediaRecorderEventMap = {\n dataavailable: BlobEvent<'dataavailable'>;\n error: Event<'error'>;\n pause: Event<'pause'>;\n resume: Event<'resume'>;\n start: Event<'start'>;\n stop: Event<'stop'>;\n};\n\n/**\n * A MediaRecord implementation only meant for recording audio streams.\n *\n * @private\n */\nexport class MediaRecorder extends EventTarget<MediaRecorderEventMap> {\n mimeType: String = 'audio/pcm';\n audioBitsPerSecond: number = 0; // TODO?\n state: MediaRecorderState = 'inactive';\n stream: MediaStream;\n videoBitsPerSecond: number = 0; // TODO?\n audioBitrateMode = 'constant';\n\n _reactTag: string | undefined = undefined;\n _parts: string[] = [];\n constructor(stream: MediaStream) {\n super();\n this.stream = stream;\n }\n\n registerListener() {\n let audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length !== 1) {\n return;\n }\n const mediaStreamTrack = audioTracks[0];\n const peerConnectionId = mediaStreamTrack._peerConnectionId ?? -1;\n const mediaStreamTrackId = mediaStreamTrack?.id;\n this._reactTag = LiveKitModule.createAudioSinkListener(\n peerConnectionId,\n mediaStreamTrackId\n );\n addListener(this, 'LK_AUDIO_DATA', (event: any) => {\n if (\n this._reactTag &&\n event.id === this._reactTag &&\n this.state === 'recording'\n ) {\n let str = event.data as string;\n this._parts.push(str);\n }\n });\n }\n\n unregisterListener() {\n if (this._reactTag) {\n let audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length !== 1) {\n log.error(\"couldn't find any audio tracks to record from!\");\n return;\n }\n const mediaStreamTrack = audioTracks[0];\n const peerConnectionId = mediaStreamTrack._peerConnectionId ?? -1;\n const mediaStreamTrackId = mediaStreamTrack?.id;\n\n LiveKitModule.deleteAudioSinkListener(\n this._reactTag,\n peerConnectionId,\n mediaStreamTrackId\n );\n }\n }\n\n pause() {\n this.state = 'paused';\n this.dispatchEvent(new Event('pause'));\n }\n\n resume() {\n this.state = 'recording';\n this.dispatchEvent(new Event('resume'));\n }\n\n start() {\n this.registerListener();\n this.state = 'recording';\n this.dispatchEvent(new Event('start'));\n }\n\n stop() {\n // dispatch data must come before stopping.\n this.dispatchData();\n\n this.unregisterListener();\n this.state = 'inactive';\n this.dispatchEvent(new Event('stop'));\n }\n\n requestData() {\n this.dispatchData();\n }\n dispatchData() {\n let combinedStr = this._parts.reduce((sum, cur) => sum + cur, '');\n let data = toByteArray(combinedStr);\n this._parts = [];\n this.dispatchEvent(\n new BlobEvent('dataavailable', { data: { byteArray: data } })\n );\n }\n}\n\n/**\n * @eventClass\n * This event is fired whenever the Track is changed in PeerConnection.\n * @param {TRACK_EVENTS} type - The type of event.\n * @param {IRTCTrackEventInitDict} eventInitDict - The event init properties.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/track_event MDN} for details.\n */\nclass BlobEvent<TEventType extends string> extends Event<TEventType> {\n /** @eventProperty */\n readonly data: { byteArray: Uint8Array };\n\n constructor(\n type: TEventType,\n eventInitDict: { data: { byteArray: Uint8Array } } & Event.EventInit\n ) {\n super(type, eventInitDict);\n this.data = eventInitDict.data;\n }\n}\n\n/**\n * Define the `onxxx` event handlers.\n */\nconst proto = MediaRecorder.prototype;\n\ndefineEventAttribute(proto, 'dataavailable');\ndefineEventAttribute(proto, 'error');\ndefineEventAttribute(proto, 'pause');\ndefineEventAttribute(proto, 'resume');\ndefineEventAttribute(proto, 'start');\ndefineEventAttribute(proto, 'stop');\n"],"mappings":"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","ignoreList":[]}
@@ -15,15 +15,28 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
15
15
  * @experimental
16
16
  */
17
17
  class RNE2EEManager extends _events.default {
18
- constructor(keyProvider) {
18
+ constructor(keyProvider, dcEncryptionEnabled = false) {
19
19
  super();
20
20
  _defineProperty(this, "room", void 0);
21
21
  _defineProperty(this, "frameCryptors", new Map());
22
22
  _defineProperty(this, "keyProvider", void 0);
23
23
  _defineProperty(this, "algorithm", _reactNativeWebrtc.RTCFrameCryptorAlgorithm.kAesGcm);
24
24
  _defineProperty(this, "encryptionEnabled", false);
25
+ _defineProperty(this, "dataChannelEncryptionEnabled", false);
26
+ _defineProperty(this, "dataPacketCryptorLock", new _livekitClient.Mutex());
27
+ _defineProperty(this, "dataPacketCryptor", undefined);
25
28
  this.keyProvider = keyProvider;
26
29
  this.encryptionEnabled = false;
30
+ this.dataChannelEncryptionEnabled = dcEncryptionEnabled;
31
+ }
32
+ get isEnabled() {
33
+ return this.encryptionEnabled;
34
+ }
35
+ get isDataChannelEncryptionEnabled() {
36
+ return this.isEnabled && this.dataChannelEncryptionEnabled;
37
+ }
38
+ set isDataChannelEncryptionEnabled(value) {
39
+ this.dataChannelEncryptionEnabled = value;
27
40
  }
28
41
  setup(room) {
29
42
  if (this.room !== room) {
@@ -51,6 +64,11 @@ class RNE2EEManager extends _events.default {
51
64
  await frameCryptor.setEnabled(false);
52
65
  await frameCryptor.dispose();
53
66
  }
67
+ }).on(_livekitClient.RoomEvent.SignalConnected, () => {
68
+ if (!this.room) {
69
+ throw new TypeError(`expected room to be present on signal connect`);
70
+ }
71
+ this.setParticipantCryptorEnabled(this.room.localParticipant.isE2EEEnabled, this.room.localParticipant.identity);
54
72
  });
55
73
  }
56
74
  async setupE2EESender(publication, participant) {
@@ -80,6 +98,60 @@ class RNE2EEManager extends _events.default {
80
98
  setSifTrailer(trailer) {
81
99
  this.keyProvider.setSifTrailer(trailer);
82
100
  }
101
+ async getDataPacketCryptor() {
102
+ let dataPacketCryptor = this.dataPacketCryptor;
103
+ if (dataPacketCryptor) {
104
+ return dataPacketCryptor;
105
+ }
106
+ let unlock = await this.dataPacketCryptorLock.lock();
107
+ try {
108
+ dataPacketCryptor = this.dataPacketCryptor;
109
+ if (dataPacketCryptor) {
110
+ return dataPacketCryptor;
111
+ }
112
+ dataPacketCryptor = await _reactNativeWebrtc.RTCDataPacketCryptorFactory.createDataPacketCryptor(this.algorithm, this.keyProvider.rtcKeyProvider);
113
+ this.dataPacketCryptor = dataPacketCryptor;
114
+ return dataPacketCryptor;
115
+ } finally {
116
+ unlock();
117
+ }
118
+ }
119
+ async encryptData(data) {
120
+ let room = this.room;
121
+ if (!room) {
122
+ throw new Error("e2eemanager isn't setup with room!");
123
+ }
124
+ let participantId = room.localParticipant.identity;
125
+ let dataPacketCryptor = await this.getDataPacketCryptor();
126
+ let encryptedPacket = await dataPacketCryptor.encrypt(participantId, this.keyProvider.getLatestKeyIndex(participantId), data);
127
+ if (!encryptedPacket) {
128
+ throw new Error('encryption for packet failed');
129
+ }
130
+ return {
131
+ uuid: '',
132
+ //not used
133
+ payload: encryptedPacket.payload,
134
+ iv: encryptedPacket.iv,
135
+ keyIndex: encryptedPacket.keyIndex
136
+ };
137
+ }
138
+ async handleEncryptedData(payload, iv, participantIdentity, keyIndex) {
139
+ let packet = {
140
+ payload,
141
+ iv,
142
+ keyIndex
143
+ };
144
+ let dataPacketCryptor = await this.getDataPacketCryptor();
145
+ let decryptedData = await dataPacketCryptor.decrypt(participantIdentity, packet);
146
+ if (!decryptedData) {
147
+ throw new Error('decryption for packet failed');
148
+ }
149
+ return {
150
+ uuid: '',
151
+ //not used
152
+ payload: decryptedData
153
+ };
154
+ }
83
155
 
84
156
  // Utility methods
85
157
  //////////////////////
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNativeWebrtc","require","_livekitClient","_events","_interopRequireDefault","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","RNE2EEManager","EventEmitter","constructor","keyProvider","Map","RTCFrameCryptorAlgorithm","kAesGcm","encryptionEnabled","setup","room","setupEventListeners","localParticipant","on","ParticipantEvent","LocalTrackPublished","publication","setupE2EESender","LocalTrackUnpublished","frameCryptor","findTrackCryptor","trackSid","frameCryptors","delete","setEnabled","dispose","RoomEvent","TrackSubscribed","_track","pub","participant","setupE2EEReceiver","TrackUnsubscribed","_participant","isEncrypted","createFrameCryptorForSender","track","sender","identity","set","setKeyIndex","getLatestKeyIndex","createFrameCryptorForReceiver","receiver","setSifTrailer","trailer","trackId","get","participantId","RTCFrameCryptorFactory","createFrameCryptorForRtpSender","algorithm","rtcKeyProvider","createFrameCryptorForRtpReceiver","setupEngine","_engine","setParticipantCryptorEnabled","enabled","participantIdentity","_this$room","emit","EncryptionEvent","ParticipantEncryptionStatusChanged","_this$room2","getParticipantByIdentity","exports"],"sources":["RNE2EEManager.ts"],"sourcesContent":["import {\n RTCFrameCryptorAlgorithm,\n RTCFrameCryptorFactory,\n RTCRtpReceiver,\n type RTCFrameCryptor,\n type RTCRtpSender,\n} from '@livekit/react-native-webrtc';\nimport {\n LocalParticipant,\n LocalTrackPublication,\n ParticipantEvent,\n RemoteParticipant,\n RemoteTrackPublication,\n RoomEvent,\n type Room,\n type BaseE2EEManager,\n type E2EEManagerCallbacks,\n EncryptionEvent,\n} from 'livekit-client';\nimport type RNKeyProvider from './RNKeyProvider';\nimport type RTCEngine from 'livekit-client/dist/src/room/RTCEngine';\nimport EventEmitter from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\n\n/**\n * @experimental\n */\nexport default class RNE2EEManager\n extends (EventEmitter as new () => TypedEventEmitter<E2EEManagerCallbacks>)\n implements BaseE2EEManager\n{\n private room?: Room;\n private frameCryptors: Map<string, RTCFrameCryptor> = new Map();\n private keyProvider: RNKeyProvider;\n private algorithm: RTCFrameCryptorAlgorithm =\n RTCFrameCryptorAlgorithm.kAesGcm;\n\n private encryptionEnabled: boolean = false;\n\n constructor(keyProvider: RNKeyProvider) {\n super();\n this.keyProvider = keyProvider;\n this.encryptionEnabled = false;\n }\n\n setup(room: Room) {\n if (this.room !== room) {\n this.room = room;\n this.setupEventListeners(room);\n }\n }\n\n private setupEventListeners(room: Room) {\n room.localParticipant\n .on(ParticipantEvent.LocalTrackPublished, async (publication) => {\n this.setupE2EESender(publication, room.localParticipant);\n })\n .on(ParticipantEvent.LocalTrackUnpublished, async (publication) => {\n let frameCryptor = this.findTrackCryptor(publication.trackSid);\n if (frameCryptor) {\n this.frameCryptors.delete(publication.trackSid);\n await frameCryptor.setEnabled(false);\n await frameCryptor.dispose();\n }\n });\n\n room\n .on(RoomEvent.TrackSubscribed, (_track, pub, participant) => {\n this.setupE2EEReceiver(pub, participant);\n })\n .on(\n RoomEvent.TrackUnsubscribed,\n async (_track, publication, _participant) => {\n let frameCryptor = this.findTrackCryptor(publication.trackSid);\n if (frameCryptor) {\n this.frameCryptors.delete(publication.trackSid);\n await frameCryptor.setEnabled(false);\n await frameCryptor.dispose();\n }\n }\n );\n }\n\n private async setupE2EESender(\n publication: LocalTrackPublication,\n participant: LocalParticipant\n ) {\n if (!publication.isEncrypted) {\n return;\n }\n\n var frameCryptor = this.findTrackCryptor(publication.trackSid);\n\n if (!frameCryptor) {\n frameCryptor = this.createFrameCryptorForSender(\n publication.track!.sender,\n participant.identity\n );\n\n this.frameCryptors.set(publication.trackSid, frameCryptor);\n frameCryptor.setEnabled(true);\n frameCryptor.setKeyIndex(\n this.keyProvider.getLatestKeyIndex(participant.identity)\n );\n }\n }\n\n private async setupE2EEReceiver(\n publication: RemoteTrackPublication,\n participant: RemoteParticipant\n ) {\n if (!publication.isEncrypted) {\n return;\n }\n\n var frameCryptor = this.findTrackCryptor(publication.trackSid);\n\n if (!frameCryptor) {\n frameCryptor = this.createFrameCryptorForReceiver(\n publication.track!.receiver,\n participant.identity\n );\n\n this.frameCryptors.set(publication.trackSid, frameCryptor);\n frameCryptor.setEnabled(true);\n frameCryptor.setKeyIndex(\n this.keyProvider.getLatestKeyIndex(participant.identity)\n );\n }\n }\n\n setSifTrailer(trailer: Uint8Array): void {\n this.keyProvider.setSifTrailer(trailer);\n }\n\n // Utility methods\n //////////////////////\n\n private findTrackCryptor(trackId: string): RTCFrameCryptor | undefined {\n return this.frameCryptors.get(trackId);\n }\n\n private createFrameCryptorForSender(\n sender: RTCRtpSender,\n participantId: string\n ): RTCFrameCryptor {\n return RTCFrameCryptorFactory.createFrameCryptorForRtpSender(\n participantId,\n sender,\n this.algorithm,\n this.keyProvider.rtcKeyProvider\n );\n }\n\n private createFrameCryptorForReceiver(\n receiver: RTCRtpReceiver,\n participantId: string\n ): RTCFrameCryptor {\n return RTCFrameCryptorFactory.createFrameCryptorForRtpReceiver(\n participantId,\n receiver,\n this.algorithm,\n this.keyProvider.rtcKeyProvider\n );\n }\n\n setupEngine(_engine: RTCEngine): void {\n // No-op\n }\n setParticipantCryptorEnabled(\n enabled: boolean,\n participantIdentity: string\n ): void {\n if (\n this.encryptionEnabled !== enabled &&\n participantIdentity === this.room?.localParticipant.identity\n ) {\n this.encryptionEnabled = enabled;\n this.emit(\n EncryptionEvent.ParticipantEncryptionStatusChanged,\n enabled,\n this.room!.localParticipant\n );\n } else {\n const participant =\n this.room?.getParticipantByIdentity(participantIdentity);\n if (!participant) {\n throw TypeError(\n `couldn't set encryption status, participant not found ${participantIdentity}`\n );\n }\n this.emit(\n EncryptionEvent.ParticipantEncryptionStatusChanged,\n enabled,\n participant\n );\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNativeWebrtc","require","_livekitClient","_events","_interopRequireDefault","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","RNE2EEManager","EventEmitter","constructor","keyProvider","dcEncryptionEnabled","Map","RTCFrameCryptorAlgorithm","kAesGcm","Mutex","undefined","encryptionEnabled","dataChannelEncryptionEnabled","isEnabled","isDataChannelEncryptionEnabled","setup","room","setupEventListeners","localParticipant","on","ParticipantEvent","LocalTrackPublished","publication","setupE2EESender","LocalTrackUnpublished","frameCryptor","findTrackCryptor","trackSid","frameCryptors","delete","setEnabled","dispose","RoomEvent","TrackSubscribed","_track","pub","participant","setupE2EEReceiver","TrackUnsubscribed","_participant","SignalConnected","setParticipantCryptorEnabled","isE2EEEnabled","identity","isEncrypted","createFrameCryptorForSender","track","sender","set","setKeyIndex","getLatestKeyIndex","createFrameCryptorForReceiver","receiver","setSifTrailer","trailer","getDataPacketCryptor","dataPacketCryptor","unlock","dataPacketCryptorLock","lock","RTCDataPacketCryptorFactory","createDataPacketCryptor","algorithm","rtcKeyProvider","encryptData","data","Error","participantId","encryptedPacket","encrypt","uuid","payload","iv","keyIndex","handleEncryptedData","participantIdentity","packet","decryptedData","decrypt","trackId","get","RTCFrameCryptorFactory","createFrameCryptorForRtpSender","createFrameCryptorForRtpReceiver","setupEngine","_engine","enabled","_this$room","emit","EncryptionEvent","ParticipantEncryptionStatusChanged","_this$room2","getParticipantByIdentity","exports"],"sources":["RNE2EEManager.ts"],"sourcesContent":["import {\n RTCDataPacketCryptor,\n RTCDataPacketCryptorFactory,\n RTCFrameCryptorAlgorithm,\n RTCFrameCryptorFactory,\n RTCRtpReceiver,\n type RTCEncryptedPacket,\n type RTCFrameCryptor,\n type RTCRtpSender,\n} from '@livekit/react-native-webrtc';\nimport {\n LocalParticipant,\n LocalTrackPublication,\n ParticipantEvent,\n RemoteParticipant,\n RemoteTrackPublication,\n RoomEvent,\n type Room,\n type BaseE2EEManager,\n type E2EEManagerCallbacks,\n EncryptionEvent,\n type DecryptDataResponseMessage,\n type EncryptDataResponseMessage,\n Mutex,\n} from 'livekit-client';\nimport type RNKeyProvider from './RNKeyProvider';\nimport type RTCEngine from 'livekit-client/dist/src/room/RTCEngine';\nimport EventEmitter from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\n\n/**\n * @experimental\n */\nexport default class RNE2EEManager\n extends (EventEmitter as new () => TypedEventEmitter<E2EEManagerCallbacks>)\n implements BaseE2EEManager\n{\n private room?: Room;\n private frameCryptors: Map<string, RTCFrameCryptor> = new Map();\n private keyProvider: RNKeyProvider;\n private algorithm: RTCFrameCryptorAlgorithm =\n RTCFrameCryptorAlgorithm.kAesGcm;\n\n private encryptionEnabled: boolean = false;\n private dataChannelEncryptionEnabled: boolean = false;\n\n private dataPacketCryptorLock = new Mutex();\n private dataPacketCryptor: RTCDataPacketCryptor | undefined = undefined;\n constructor(\n keyProvider: RNKeyProvider,\n dcEncryptionEnabled: boolean = false\n ) {\n super();\n this.keyProvider = keyProvider;\n this.encryptionEnabled = false;\n this.dataChannelEncryptionEnabled = dcEncryptionEnabled;\n }\n\n get isEnabled(): boolean {\n return this.encryptionEnabled;\n }\n get isDataChannelEncryptionEnabled(): boolean {\n return this.isEnabled && this.dataChannelEncryptionEnabled;\n }\n set isDataChannelEncryptionEnabled(value: boolean) {\n this.dataChannelEncryptionEnabled = value;\n }\n\n setup(room: Room) {\n if (this.room !== room) {\n this.room = room;\n this.setupEventListeners(room);\n }\n }\n\n private setupEventListeners(room: Room) {\n room.localParticipant\n .on(ParticipantEvent.LocalTrackPublished, async (publication) => {\n this.setupE2EESender(publication, room.localParticipant);\n })\n .on(ParticipantEvent.LocalTrackUnpublished, async (publication) => {\n let frameCryptor = this.findTrackCryptor(publication.trackSid);\n if (frameCryptor) {\n this.frameCryptors.delete(publication.trackSid);\n await frameCryptor.setEnabled(false);\n await frameCryptor.dispose();\n }\n });\n\n room\n .on(RoomEvent.TrackSubscribed, (_track, pub, participant) => {\n this.setupE2EEReceiver(pub, participant);\n })\n .on(\n RoomEvent.TrackUnsubscribed,\n async (_track, publication, _participant) => {\n let frameCryptor = this.findTrackCryptor(publication.trackSid);\n if (frameCryptor) {\n this.frameCryptors.delete(publication.trackSid);\n await frameCryptor.setEnabled(false);\n await frameCryptor.dispose();\n }\n }\n )\n .on(RoomEvent.SignalConnected, () => {\n if (!this.room) {\n throw new TypeError(`expected room to be present on signal connect`);\n }\n this.setParticipantCryptorEnabled(\n this.room.localParticipant.isE2EEEnabled,\n this.room.localParticipant.identity\n );\n });\n }\n\n private async setupE2EESender(\n publication: LocalTrackPublication,\n participant: LocalParticipant\n ) {\n if (!publication.isEncrypted) {\n return;\n }\n\n var frameCryptor = this.findTrackCryptor(publication.trackSid);\n\n if (!frameCryptor) {\n frameCryptor = this.createFrameCryptorForSender(\n publication.track!.sender,\n participant.identity\n );\n\n this.frameCryptors.set(publication.trackSid, frameCryptor);\n frameCryptor.setEnabled(true);\n frameCryptor.setKeyIndex(\n this.keyProvider.getLatestKeyIndex(participant.identity)\n );\n }\n }\n\n private async setupE2EEReceiver(\n publication: RemoteTrackPublication,\n participant: RemoteParticipant\n ) {\n if (!publication.isEncrypted) {\n return;\n }\n\n var frameCryptor = this.findTrackCryptor(publication.trackSid);\n\n if (!frameCryptor) {\n frameCryptor = this.createFrameCryptorForReceiver(\n publication.track!.receiver,\n participant.identity\n );\n\n this.frameCryptors.set(publication.trackSid, frameCryptor);\n frameCryptor.setEnabled(true);\n frameCryptor.setKeyIndex(\n this.keyProvider.getLatestKeyIndex(participant.identity)\n );\n }\n }\n\n setSifTrailer(trailer: Uint8Array): void {\n this.keyProvider.setSifTrailer(trailer);\n }\n\n private async getDataPacketCryptor(): Promise<RTCDataPacketCryptor> {\n let dataPacketCryptor = this.dataPacketCryptor;\n if (dataPacketCryptor) {\n return dataPacketCryptor;\n }\n\n let unlock = await this.dataPacketCryptorLock.lock();\n\n try {\n dataPacketCryptor = this.dataPacketCryptor;\n if (dataPacketCryptor) {\n return dataPacketCryptor;\n }\n\n dataPacketCryptor =\n await RTCDataPacketCryptorFactory.createDataPacketCryptor(\n this.algorithm,\n this.keyProvider.rtcKeyProvider\n );\n\n this.dataPacketCryptor = dataPacketCryptor;\n return dataPacketCryptor;\n } finally {\n unlock();\n }\n }\n async encryptData(\n data: Uint8Array\n ): Promise<EncryptDataResponseMessage['data']> {\n let room = this.room;\n if (!room) {\n throw new Error(\"e2eemanager isn't setup with room!\");\n }\n\n let participantId = room.localParticipant.identity;\n\n let dataPacketCryptor = await this.getDataPacketCryptor();\n\n let encryptedPacket = await dataPacketCryptor.encrypt(\n participantId,\n this.keyProvider.getLatestKeyIndex(participantId),\n data\n );\n\n if (!encryptedPacket) {\n throw new Error('encryption for packet failed');\n }\n return {\n uuid: '', //not used\n payload: encryptedPacket.payload,\n iv: encryptedPacket.iv,\n keyIndex: encryptedPacket.keyIndex,\n };\n }\n\n async handleEncryptedData(\n payload: Uint8Array,\n iv: Uint8Array,\n participantIdentity: string,\n keyIndex: number\n ): Promise<DecryptDataResponseMessage['data']> {\n let packet = {\n payload,\n iv,\n keyIndex,\n } satisfies RTCEncryptedPacket;\n\n let dataPacketCryptor = await this.getDataPacketCryptor();\n let decryptedData = await dataPacketCryptor.decrypt(\n participantIdentity,\n packet\n );\n\n if (!decryptedData) {\n throw new Error('decryption for packet failed');\n }\n\n return {\n uuid: '', //not used\n payload: decryptedData,\n } satisfies DecryptDataResponseMessage['data'];\n }\n\n // Utility methods\n //////////////////////\n\n private findTrackCryptor(trackId: string): RTCFrameCryptor | undefined {\n return this.frameCryptors.get(trackId);\n }\n\n private createFrameCryptorForSender(\n sender: RTCRtpSender,\n participantId: string\n ): RTCFrameCryptor {\n return RTCFrameCryptorFactory.createFrameCryptorForRtpSender(\n participantId,\n sender,\n this.algorithm,\n this.keyProvider.rtcKeyProvider\n );\n }\n\n private createFrameCryptorForReceiver(\n receiver: RTCRtpReceiver,\n participantId: string\n ): RTCFrameCryptor {\n return RTCFrameCryptorFactory.createFrameCryptorForRtpReceiver(\n participantId,\n receiver,\n this.algorithm,\n this.keyProvider.rtcKeyProvider\n );\n }\n\n setupEngine(_engine: RTCEngine): void {\n // No-op\n }\n setParticipantCryptorEnabled(\n enabled: boolean,\n participantIdentity: string\n ): void {\n if (\n this.encryptionEnabled !== enabled &&\n participantIdentity === this.room?.localParticipant.identity\n ) {\n this.encryptionEnabled = enabled;\n this.emit(\n EncryptionEvent.ParticipantEncryptionStatusChanged,\n enabled,\n this.room!.localParticipant\n );\n } else {\n const participant =\n this.room?.getParticipantByIdentity(participantIdentity);\n if (!participant) {\n throw TypeError(\n `couldn't set encryption status, participant not found ${participantIdentity}`\n );\n }\n this.emit(\n EncryptionEvent.ParticipantEncryptionStatusChanged,\n enabled,\n participant\n );\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -13,7 +13,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
13
13
  */
14
14
  function useRNE2EEManager(options) {
15
15
  let [keyProvider] = (0, _react.useState)(() => new _.RNKeyProvider(options.keyProviderOptions ?? {}));
16
- let [e2eeManager] = (0, _react.useState)(() => new _RNE2EEManager.default(keyProvider));
16
+ let [e2eeManager] = (0, _react.useState)(() => new _RNE2EEManager.default(keyProvider, false));
17
17
  (0, _react.useEffect)(() => {
18
18
  let setup = async () => {
19
19
  try {