@abrar71/lib-jitsi-meet 0.0.0

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 (350) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +26 -0
  3. package/dist/esm/JitsiConference.js +3692 -0
  4. package/dist/esm/JitsiConference.js.map +1 -0
  5. package/dist/esm/JitsiConferenceErrors.js +126 -0
  6. package/dist/esm/JitsiConferenceErrors.js.map +1 -0
  7. package/dist/esm/JitsiConferenceEventManager.js +424 -0
  8. package/dist/esm/JitsiConferenceEventManager.js.map +1 -0
  9. package/dist/esm/JitsiConferenceEvents.js +431 -0
  10. package/dist/esm/JitsiConferenceEvents.js.map +1 -0
  11. package/dist/esm/JitsiConnection.js +187 -0
  12. package/dist/esm/JitsiConnection.js.map +1 -0
  13. package/dist/esm/JitsiConnectionErrors.js +52 -0
  14. package/dist/esm/JitsiConnectionErrors.js.map +1 -0
  15. package/dist/esm/JitsiConnectionEvents.js +57 -0
  16. package/dist/esm/JitsiConnectionEvents.js.map +1 -0
  17. package/dist/esm/JitsiMediaDevices.js +221 -0
  18. package/dist/esm/JitsiMediaDevices.js.map +1 -0
  19. package/dist/esm/JitsiMediaDevicesEvents.js +29 -0
  20. package/dist/esm/JitsiMediaDevicesEvents.js.map +1 -0
  21. package/dist/esm/JitsiMeetJS.js +499 -0
  22. package/dist/esm/JitsiMeetJS.js.map +1 -0
  23. package/dist/esm/JitsiParticipant.js +323 -0
  24. package/dist/esm/JitsiParticipant.js.map +1 -0
  25. package/dist/esm/JitsiTrackError.js +122 -0
  26. package/dist/esm/JitsiTrackError.js.map +1 -0
  27. package/dist/esm/JitsiTrackErrors.js +91 -0
  28. package/dist/esm/JitsiTrackErrors.js.map +1 -0
  29. package/dist/esm/JitsiTrackEvents.js +60 -0
  30. package/dist/esm/JitsiTrackEvents.js.map +1 -0
  31. package/dist/esm/JitsiTranscriptionStatus.js +15 -0
  32. package/dist/esm/JitsiTranscriptionStatus.js.map +1 -0
  33. package/dist/esm/modules/RTC/BridgeChannel.js +398 -0
  34. package/dist/esm/modules/RTC/BridgeChannel.js.map +1 -0
  35. package/dist/esm/modules/RTC/JitsiLocalTrack.js +896 -0
  36. package/dist/esm/modules/RTC/JitsiLocalTrack.js.map +1 -0
  37. package/dist/esm/modules/RTC/JitsiRemoteTrack.js +427 -0
  38. package/dist/esm/modules/RTC/JitsiRemoteTrack.js.map +1 -0
  39. package/dist/esm/modules/RTC/JitsiTrack.js +453 -0
  40. package/dist/esm/modules/RTC/JitsiTrack.js.map +1 -0
  41. package/dist/esm/modules/RTC/MockClasses.js +388 -0
  42. package/dist/esm/modules/RTC/MockClasses.js.map +1 -0
  43. package/dist/esm/modules/RTC/RTC.js +658 -0
  44. package/dist/esm/modules/RTC/RTC.js.map +1 -0
  45. package/dist/esm/modules/RTC/RTCUtils.js +762 -0
  46. package/dist/esm/modules/RTC/RTCUtils.js.map +1 -0
  47. package/dist/esm/modules/RTC/ScreenObtainer.js +380 -0
  48. package/dist/esm/modules/RTC/ScreenObtainer.js.map +1 -0
  49. package/dist/esm/modules/RTC/TPCUtils.js +803 -0
  50. package/dist/esm/modules/RTC/TPCUtils.js.map +1 -0
  51. package/dist/esm/modules/RTC/TraceablePeerConnection.js +2223 -0
  52. package/dist/esm/modules/RTC/TraceablePeerConnection.js.map +1 -0
  53. package/dist/esm/modules/RTCStats/DefaulLogStorage.js +35 -0
  54. package/dist/esm/modules/RTCStats/DefaulLogStorage.js.map +1 -0
  55. package/dist/esm/modules/RTCStats/RTCStats.js +219 -0
  56. package/dist/esm/modules/RTCStats/RTCStats.js.map +1 -0
  57. package/dist/esm/modules/RTCStats/RTCStatsEvents.js +92 -0
  58. package/dist/esm/modules/RTCStats/RTCStatsEvents.js.map +1 -0
  59. package/dist/esm/modules/RTCStats/interfaces.js +2 -0
  60. package/dist/esm/modules/RTCStats/interfaces.js.map +1 -0
  61. package/dist/esm/modules/browser/BrowserCapabilities.js +345 -0
  62. package/dist/esm/modules/browser/BrowserCapabilities.js.map +1 -0
  63. package/dist/esm/modules/browser/index.js +3 -0
  64. package/dist/esm/modules/browser/index.js.map +1 -0
  65. package/dist/esm/modules/connectivity/ConnectionQuality.js +389 -0
  66. package/dist/esm/modules/connectivity/ConnectionQuality.js.map +1 -0
  67. package/dist/esm/modules/connectivity/IceFailedHandling.js +84 -0
  68. package/dist/esm/modules/connectivity/IceFailedHandling.js.map +1 -0
  69. package/dist/esm/modules/connectivity/NetworkInfo.js +49 -0
  70. package/dist/esm/modules/connectivity/NetworkInfo.js.map +1 -0
  71. package/dist/esm/modules/connectivity/TrackStreamingStatus.js +453 -0
  72. package/dist/esm/modules/connectivity/TrackStreamingStatus.js.map +1 -0
  73. package/dist/esm/modules/detection/ActiveDeviceDetector.js +79 -0
  74. package/dist/esm/modules/detection/ActiveDeviceDetector.js.map +1 -0
  75. package/dist/esm/modules/detection/DetectionEvents.js +58 -0
  76. package/dist/esm/modules/detection/DetectionEvents.js.map +1 -0
  77. package/dist/esm/modules/detection/NoAudioSignalDetection.js +127 -0
  78. package/dist/esm/modules/detection/NoAudioSignalDetection.js.map +1 -0
  79. package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js +47 -0
  80. package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js.map +1 -0
  81. package/dist/esm/modules/detection/TrackVADEmitter.js +190 -0
  82. package/dist/esm/modules/detection/TrackVADEmitter.js.map +1 -0
  83. package/dist/esm/modules/detection/VADAudioAnalyser.js +199 -0
  84. package/dist/esm/modules/detection/VADAudioAnalyser.js.map +1 -0
  85. package/dist/esm/modules/detection/VADNoiseDetection.js +168 -0
  86. package/dist/esm/modules/detection/VADNoiseDetection.js.map +1 -0
  87. package/dist/esm/modules/detection/VADReportingService.js +203 -0
  88. package/dist/esm/modules/detection/VADReportingService.js.map +1 -0
  89. package/dist/esm/modules/detection/VADTalkMutedDetection.js +131 -0
  90. package/dist/esm/modules/detection/VADTalkMutedDetection.js.map +1 -0
  91. package/dist/esm/modules/e2ee/Context.js +274 -0
  92. package/dist/esm/modules/e2ee/Context.js.map +1 -0
  93. package/dist/esm/modules/e2ee/E2EEContext.js +158 -0
  94. package/dist/esm/modules/e2ee/E2EEContext.js.map +1 -0
  95. package/dist/esm/modules/e2ee/E2EEErrors.js +10 -0
  96. package/dist/esm/modules/e2ee/E2EEErrors.js.map +1 -0
  97. package/dist/esm/modules/e2ee/E2EEncryption.js +87 -0
  98. package/dist/esm/modules/e2ee/E2EEncryption.js.map +1 -0
  99. package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js +24 -0
  100. package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js.map +1 -0
  101. package/dist/esm/modules/e2ee/KeyHandler.js +137 -0
  102. package/dist/esm/modules/e2ee/KeyHandler.js.map +1 -0
  103. package/dist/esm/modules/e2ee/ManagedKeyHandler.js +182 -0
  104. package/dist/esm/modules/e2ee/ManagedKeyHandler.js.map +1 -0
  105. package/dist/esm/modules/e2ee/OlmAdapter.js +860 -0
  106. package/dist/esm/modules/e2ee/OlmAdapter.js.map +1 -0
  107. package/dist/esm/modules/e2ee/SAS.js +128 -0
  108. package/dist/esm/modules/e2ee/SAS.js.map +1 -0
  109. package/dist/esm/modules/e2ee/Worker.js +102 -0
  110. package/dist/esm/modules/e2ee/Worker.js.map +1 -0
  111. package/dist/esm/modules/e2ee/crypto-utils.js +53 -0
  112. package/dist/esm/modules/e2ee/crypto-utils.js.map +1 -0
  113. package/dist/esm/modules/e2ee/utils.js +15 -0
  114. package/dist/esm/modules/e2ee/utils.js.map +1 -0
  115. package/dist/esm/modules/e2eping/e2eping.js +314 -0
  116. package/dist/esm/modules/e2eping/e2eping.js.map +1 -0
  117. package/dist/esm/modules/flags/FeatureFlags.js +36 -0
  118. package/dist/esm/modules/flags/FeatureFlags.js.map +1 -0
  119. package/dist/esm/modules/litemode/LiteModeContext.js +50 -0
  120. package/dist/esm/modules/litemode/LiteModeContext.js.map +1 -0
  121. package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js +98 -0
  122. package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js.map +1 -0
  123. package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js +348 -0
  124. package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js.map +1 -0
  125. package/dist/esm/modules/proxyconnection/ProxyConnectionService.js +279 -0
  126. package/dist/esm/modules/proxyconnection/ProxyConnectionService.js.map +1 -0
  127. package/dist/esm/modules/proxyconnection/constants.js +14 -0
  128. package/dist/esm/modules/proxyconnection/constants.js.map +1 -0
  129. package/dist/esm/modules/qualitycontrol/CodecSelection.js +222 -0
  130. package/dist/esm/modules/qualitycontrol/CodecSelection.js.map +1 -0
  131. package/dist/esm/modules/qualitycontrol/MockClasses.js +120 -0
  132. package/dist/esm/modules/qualitycontrol/MockClasses.js.map +1 -0
  133. package/dist/esm/modules/qualitycontrol/QualityController.js +366 -0
  134. package/dist/esm/modules/qualitycontrol/QualityController.js.map +1 -0
  135. package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js +73 -0
  136. package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js.map +1 -0
  137. package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js +216 -0
  138. package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js.map +1 -0
  139. package/dist/esm/modules/qualitycontrol/SendVideoController.js +133 -0
  140. package/dist/esm/modules/qualitycontrol/SendVideoController.js.map +1 -0
  141. package/dist/esm/modules/recording/JibriSession.js +279 -0
  142. package/dist/esm/modules/recording/JibriSession.js.map +1 -0
  143. package/dist/esm/modules/recording/RecordingManager.js +257 -0
  144. package/dist/esm/modules/recording/RecordingManager.js.map +1 -0
  145. package/dist/esm/modules/recording/recordingConstants.js +21 -0
  146. package/dist/esm/modules/recording/recordingConstants.js.map +1 -0
  147. package/dist/esm/modules/recording/recordingXMLUtils.js +69 -0
  148. package/dist/esm/modules/recording/recordingXMLUtils.js.map +1 -0
  149. package/dist/esm/modules/red/red.js +108 -0
  150. package/dist/esm/modules/red/red.js.map +1 -0
  151. package/dist/esm/modules/sdp/LocalSdpMunger.js +143 -0
  152. package/dist/esm/modules/sdp/LocalSdpMunger.js.map +1 -0
  153. package/dist/esm/modules/sdp/RtxModifier.js +179 -0
  154. package/dist/esm/modules/sdp/RtxModifier.js.map +1 -0
  155. package/dist/esm/modules/sdp/SDP.js +848 -0
  156. package/dist/esm/modules/sdp/SDP.js.map +1 -0
  157. package/dist/esm/modules/sdp/SDPDiffer.js +96 -0
  158. package/dist/esm/modules/sdp/SDPDiffer.js.map +1 -0
  159. package/dist/esm/modules/sdp/SDPUtil.js +798 -0
  160. package/dist/esm/modules/sdp/SDPUtil.js.map +1 -0
  161. package/dist/esm/modules/sdp/SampleSdpStrings.js +589 -0
  162. package/dist/esm/modules/sdp/SampleSdpStrings.js.map +1 -0
  163. package/dist/esm/modules/sdp/SdpSimulcast.js +196 -0
  164. package/dist/esm/modules/sdp/SdpSimulcast.js.map +1 -0
  165. package/dist/esm/modules/sdp/SdpTransformUtil.js +337 -0
  166. package/dist/esm/modules/sdp/SdpTransformUtil.js.map +1 -0
  167. package/dist/esm/modules/sdp/constants.js +2 -0
  168. package/dist/esm/modules/sdp/constants.js.map +1 -0
  169. package/dist/esm/modules/settings/Settings.js +95 -0
  170. package/dist/esm/modules/settings/Settings.js.map +1 -0
  171. package/dist/esm/modules/statistics/AnalyticsAdapter.js +277 -0
  172. package/dist/esm/modules/statistics/AnalyticsAdapter.js.map +1 -0
  173. package/dist/esm/modules/statistics/AvgRTPStatsReporter.js +817 -0
  174. package/dist/esm/modules/statistics/AvgRTPStatsReporter.js.map +1 -0
  175. package/dist/esm/modules/statistics/LocalStatsCollector.js +149 -0
  176. package/dist/esm/modules/statistics/LocalStatsCollector.js.map +1 -0
  177. package/dist/esm/modules/statistics/PreCallTest.js +15 -0
  178. package/dist/esm/modules/statistics/PreCallTest.js.map +1 -0
  179. package/dist/esm/modules/statistics/RTPStatsCollector.js +601 -0
  180. package/dist/esm/modules/statistics/RTPStatsCollector.js.map +1 -0
  181. package/dist/esm/modules/statistics/SpeakerStats.js +163 -0
  182. package/dist/esm/modules/statistics/SpeakerStats.js.map +1 -0
  183. package/dist/esm/modules/statistics/SpeakerStatsCollector.js +161 -0
  184. package/dist/esm/modules/statistics/SpeakerStatsCollector.js.map +1 -0
  185. package/dist/esm/modules/statistics/constants.js +7 -0
  186. package/dist/esm/modules/statistics/constants.js.map +1 -0
  187. package/dist/esm/modules/statistics/statistics.js +362 -0
  188. package/dist/esm/modules/statistics/statistics.js.map +1 -0
  189. package/dist/esm/modules/util/AsyncQueue.js +102 -0
  190. package/dist/esm/modules/util/AsyncQueue.js.map +1 -0
  191. package/dist/esm/modules/util/Deferred.js +41 -0
  192. package/dist/esm/modules/util/Deferred.js.map +1 -0
  193. package/dist/esm/modules/util/EventEmitter.js +17 -0
  194. package/dist/esm/modules/util/EventEmitter.js.map +1 -0
  195. package/dist/esm/modules/util/EventEmitterForwarder.js +52 -0
  196. package/dist/esm/modules/util/EventEmitterForwarder.js.map +1 -0
  197. package/dist/esm/modules/util/Listenable.js +106 -0
  198. package/dist/esm/modules/util/Listenable.js.map +1 -0
  199. package/dist/esm/modules/util/MathUtil.js +103 -0
  200. package/dist/esm/modules/util/MathUtil.js.map +1 -0
  201. package/dist/esm/modules/util/RandomUtil.js +66 -0
  202. package/dist/esm/modules/util/RandomUtil.js.map +1 -0
  203. package/dist/esm/modules/util/Retry.js +15 -0
  204. package/dist/esm/modules/util/Retry.js.map +1 -0
  205. package/dist/esm/modules/util/ScriptUtil.js +58 -0
  206. package/dist/esm/modules/util/ScriptUtil.js.map +1 -0
  207. package/dist/esm/modules/util/StringUtils.js +21 -0
  208. package/dist/esm/modules/util/StringUtils.js.map +1 -0
  209. package/dist/esm/modules/util/TestUtils.js +14 -0
  210. package/dist/esm/modules/util/TestUtils.js.map +1 -0
  211. package/dist/esm/modules/util/UsernameGenerator.js +436 -0
  212. package/dist/esm/modules/util/UsernameGenerator.js.map +1 -0
  213. package/dist/esm/modules/util/XMLUtils.js +135 -0
  214. package/dist/esm/modules/util/XMLUtils.js.map +1 -0
  215. package/dist/esm/modules/version/ComponentsVersions.js +52 -0
  216. package/dist/esm/modules/version/ComponentsVersions.js.map +1 -0
  217. package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js +137 -0
  218. package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js.map +1 -0
  219. package/dist/esm/modules/videosipgw/VideoSIPGW.js +102 -0
  220. package/dist/esm/modules/videosipgw/VideoSIPGW.js.map +1 -0
  221. package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js +65 -0
  222. package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js.map +1 -0
  223. package/dist/esm/modules/watchRTC/WatchRTC.js +69 -0
  224. package/dist/esm/modules/watchRTC/WatchRTC.js.map +1 -0
  225. package/dist/esm/modules/watchRTC/functions.js +31 -0
  226. package/dist/esm/modules/watchRTC/functions.js.map +1 -0
  227. package/dist/esm/modules/watchRTC/interfaces.js +2 -0
  228. package/dist/esm/modules/watchRTC/interfaces.js.map +1 -0
  229. package/dist/esm/modules/webaudio/AudioMixer.js +74 -0
  230. package/dist/esm/modules/webaudio/AudioMixer.js.map +1 -0
  231. package/dist/esm/modules/webaudio/WebAudioUtils.js +13 -0
  232. package/dist/esm/modules/webaudio/WebAudioUtils.js.map +1 -0
  233. package/dist/esm/modules/xmpp/AVModeration.js +156 -0
  234. package/dist/esm/modules/xmpp/AVModeration.js.map +1 -0
  235. package/dist/esm/modules/xmpp/BreakoutRooms.js +230 -0
  236. package/dist/esm/modules/xmpp/BreakoutRooms.js.map +1 -0
  237. package/dist/esm/modules/xmpp/Caps.js +223 -0
  238. package/dist/esm/modules/xmpp/Caps.js.map +1 -0
  239. package/dist/esm/modules/xmpp/ChatRoom.js +1877 -0
  240. package/dist/esm/modules/xmpp/ChatRoom.js.map +1 -0
  241. package/dist/esm/modules/xmpp/ConnectionPlugin.js +37 -0
  242. package/dist/esm/modules/xmpp/ConnectionPlugin.js.map +1 -0
  243. package/dist/esm/modules/xmpp/FileSharing.js +95 -0
  244. package/dist/esm/modules/xmpp/FileSharing.js.map +1 -0
  245. package/dist/esm/modules/xmpp/JingleHelperFunctions.js +168 -0
  246. package/dist/esm/modules/xmpp/JingleHelperFunctions.js.map +1 -0
  247. package/dist/esm/modules/xmpp/JingleSession.js +166 -0
  248. package/dist/esm/modules/xmpp/JingleSession.js.map +1 -0
  249. package/dist/esm/modules/xmpp/JingleSessionPC.js +1969 -0
  250. package/dist/esm/modules/xmpp/JingleSessionPC.js.map +1 -0
  251. package/dist/esm/modules/xmpp/JingleSessionState.js +23 -0
  252. package/dist/esm/modules/xmpp/JingleSessionState.js.map +1 -0
  253. package/dist/esm/modules/xmpp/Lobby.js +384 -0
  254. package/dist/esm/modules/xmpp/Lobby.js.map +1 -0
  255. package/dist/esm/modules/xmpp/MediaSessionEvents.js +12 -0
  256. package/dist/esm/modules/xmpp/MediaSessionEvents.js.map +1 -0
  257. package/dist/esm/modules/xmpp/MockClasses.js +77 -0
  258. package/dist/esm/modules/xmpp/MockClasses.js.map +1 -0
  259. package/dist/esm/modules/xmpp/Polls.js +87 -0
  260. package/dist/esm/modules/xmpp/Polls.js.map +1 -0
  261. package/dist/esm/modules/xmpp/ResumeTask.js +149 -0
  262. package/dist/esm/modules/xmpp/ResumeTask.js.map +1 -0
  263. package/dist/esm/modules/xmpp/RoomMetadata.js +96 -0
  264. package/dist/esm/modules/xmpp/RoomMetadata.js.map +1 -0
  265. package/dist/esm/modules/xmpp/SignalingLayerImpl.js +313 -0
  266. package/dist/esm/modules/xmpp/SignalingLayerImpl.js.map +1 -0
  267. package/dist/esm/modules/xmpp/StropheErrorHandler.js +53 -0
  268. package/dist/esm/modules/xmpp/StropheErrorHandler.js.map +1 -0
  269. package/dist/esm/modules/xmpp/StropheLastSuccess.js +52 -0
  270. package/dist/esm/modules/xmpp/StropheLastSuccess.js.map +1 -0
  271. package/dist/esm/modules/xmpp/XmppConnection.js +579 -0
  272. package/dist/esm/modules/xmpp/XmppConnection.js.map +1 -0
  273. package/dist/esm/modules/xmpp/moderator.js +524 -0
  274. package/dist/esm/modules/xmpp/moderator.js.map +1 -0
  275. package/dist/esm/modules/xmpp/sha1.js +165 -0
  276. package/dist/esm/modules/xmpp/sha1.js.map +1 -0
  277. package/dist/esm/modules/xmpp/strophe.disco.js +222 -0
  278. package/dist/esm/modules/xmpp/strophe.disco.js.map +1 -0
  279. package/dist/esm/modules/xmpp/strophe.emuc.js +206 -0
  280. package/dist/esm/modules/xmpp/strophe.emuc.js.map +1 -0
  281. package/dist/esm/modules/xmpp/strophe.jingle.js +404 -0
  282. package/dist/esm/modules/xmpp/strophe.jingle.js.map +1 -0
  283. package/dist/esm/modules/xmpp/strophe.logger.js +44 -0
  284. package/dist/esm/modules/xmpp/strophe.logger.js.map +1 -0
  285. package/dist/esm/modules/xmpp/strophe.ping.js +170 -0
  286. package/dist/esm/modules/xmpp/strophe.ping.js.map +1 -0
  287. package/dist/esm/modules/xmpp/strophe.rayo.js +117 -0
  288. package/dist/esm/modules/xmpp/strophe.rayo.js.map +1 -0
  289. package/dist/esm/modules/xmpp/strophe.stream-management.js +365 -0
  290. package/dist/esm/modules/xmpp/strophe.stream-management.js.map +1 -0
  291. package/dist/esm/modules/xmpp/strophe.util.js +116 -0
  292. package/dist/esm/modules/xmpp/strophe.util.js.map +1 -0
  293. package/dist/esm/modules/xmpp/xmpp.js +973 -0
  294. package/dist/esm/modules/xmpp/xmpp.js.map +1 -0
  295. package/dist/esm/service/RTC/BridgeVideoType.js +24 -0
  296. package/dist/esm/service/RTC/BridgeVideoType.js.map +1 -0
  297. package/dist/esm/service/RTC/CameraFacingMode.js +21 -0
  298. package/dist/esm/service/RTC/CameraFacingMode.js.map +1 -0
  299. package/dist/esm/service/RTC/CodecMimeType.js +36 -0
  300. package/dist/esm/service/RTC/CodecMimeType.js.map +1 -0
  301. package/dist/esm/service/RTC/MediaDirection.js +23 -0
  302. package/dist/esm/service/RTC/MediaDirection.js.map +1 -0
  303. package/dist/esm/service/RTC/MediaType.js +20 -0
  304. package/dist/esm/service/RTC/MediaType.js.map +1 -0
  305. package/dist/esm/service/RTC/RTCEvents.js +111 -0
  306. package/dist/esm/service/RTC/RTCEvents.js.map +1 -0
  307. package/dist/esm/service/RTC/ReceiverAudioSubscription.js +27 -0
  308. package/dist/esm/service/RTC/ReceiverAudioSubscription.js.map +1 -0
  309. package/dist/esm/service/RTC/Resolutions.js +56 -0
  310. package/dist/esm/service/RTC/Resolutions.js.map +1 -0
  311. package/dist/esm/service/RTC/SignalingEvents.js +42 -0
  312. package/dist/esm/service/RTC/SignalingEvents.js.map +1 -0
  313. package/dist/esm/service/RTC/SignalingLayer.js +153 -0
  314. package/dist/esm/service/RTC/SignalingLayer.js.map +1 -0
  315. package/dist/esm/service/RTC/StandardVideoQualitySettings.js +180 -0
  316. package/dist/esm/service/RTC/StandardVideoQualitySettings.js.map +1 -0
  317. package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js +36 -0
  318. package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js.map +1 -0
  319. package/dist/esm/service/RTC/VideoType.js +19 -0
  320. package/dist/esm/service/RTC/VideoType.js.map +1 -0
  321. package/dist/esm/service/authentication/AuthenticationEvents.js +13 -0
  322. package/dist/esm/service/authentication/AuthenticationEvents.js.map +1 -0
  323. package/dist/esm/service/connectivity/ConnectionQualityEvents.js +13 -0
  324. package/dist/esm/service/connectivity/ConnectionQualityEvents.js.map +1 -0
  325. package/dist/esm/service/connectivity/Constants.js +3 -0
  326. package/dist/esm/service/connectivity/Constants.js.map +1 -0
  327. package/dist/esm/service/e2eping/E2ePingEvents.js +8 -0
  328. package/dist/esm/service/e2eping/E2ePingEvents.js.map +1 -0
  329. package/dist/esm/service/statistics/AnalyticsEvents.js +521 -0
  330. package/dist/esm/service/statistics/AnalyticsEvents.js.map +1 -0
  331. package/dist/esm/service/statistics/Events.js +36 -0
  332. package/dist/esm/service/statistics/Events.js.map +1 -0
  333. package/dist/esm/service/statistics/constants.js +2 -0
  334. package/dist/esm/service/statistics/constants.js.map +1 -0
  335. package/dist/esm/service/xmpp/XMPPEvents.js +359 -0
  336. package/dist/esm/service/xmpp/XMPPEvents.js.map +1 -0
  337. package/dist/esm/service/xmpp/XMPPExtensioProtocols.js +64 -0
  338. package/dist/esm/service/xmpp/XMPPExtensioProtocols.js.map +1 -0
  339. package/dist/esm/test-setup-polyfill.js +34 -0
  340. package/dist/esm/test-setup-polyfill.js.map +1 -0
  341. package/dist/esm/tools/gen-version.js +15 -0
  342. package/dist/esm/tools/gen-version.js.map +1 -0
  343. package/dist/esm/version.js +3 -0
  344. package/dist/esm/version.js.map +1 -0
  345. package/dist/umd/lib-jitsi-meet.e2ee-worker.js +484 -0
  346. package/dist/umd/lib-jitsi-meet.min.js +3 -0
  347. package/dist/umd/lib-jitsi-meet.min.js.LICENSE.txt +18 -0
  348. package/dist/umd/lib-jitsi-meet.min.map +1 -0
  349. package/package.json +93 -0
  350. package/types/index.d.ts +16180 -0
@@ -0,0 +1,860 @@
1
+ /* global Olm */
2
+ import { safeJsonParse as _safeJsonParse } from '@jitsi/js-utils/json';
3
+ import { getLogger } from '@jitsi/logger';
4
+ import base64js from 'base64-js';
5
+ import { isEqual } from 'lodash-es';
6
+ import { v4 as uuidv4 } from 'uuid';
7
+ import { JitsiConferenceEvents } from '../../JitsiConferenceEvents';
8
+ import Deferred from '../util/Deferred';
9
+ import Listenable from '../util/Listenable';
10
+ import { FEATURE_E2EE, JITSI_MEET_MUC_TYPE } from '../xmpp/xmpp';
11
+ import { E2EEErrors } from './E2EEErrors';
12
+ import { generateSas } from './SAS';
13
+ const logger = getLogger('e2ee:OlmAdapter');
14
+ const REQ_TIMEOUT = 5 * 1000;
15
+ const OLM_MESSAGE_TYPE = 'olm';
16
+ const OLM_MESSAGE_TYPES = {
17
+ ERROR: 'error',
18
+ KEY_INFO: 'key-info',
19
+ KEY_INFO_ACK: 'key-info-ack',
20
+ SAS_ACCEPT: 'sas-accept',
21
+ SAS_KEY: 'sas-key',
22
+ SAS_MAC: 'sas-mac',
23
+ SAS_START: 'sas-start',
24
+ SESSION_ACK: 'session-ack',
25
+ SESSION_INIT: 'session-init'
26
+ };
27
+ const OLM_SAS_NUM_BYTES = 6;
28
+ const OLM_KEY_VERIFICATION_MAC_INFO = 'Jitsi-KEY_VERIFICATION_MAC';
29
+ const OLM_KEY_VERIFICATION_MAC_KEY_IDS = 'Jitsi-KEY_IDS';
30
+ const kOlmData = Symbol('OlmData');
31
+ const OlmAdapterEvents = {
32
+ PARTICIPANT_E2EE_CHANNEL_READY: 'olm.participant_e2ee_channel_ready',
33
+ PARTICIPANT_KEY_UPDATED: 'olm.partitipant_key_updated',
34
+ PARTICIPANT_SAS_AVAILABLE: 'olm.participant_sas_available',
35
+ PARTICIPANT_SAS_READY: 'olm.participant_sas_ready',
36
+ PARTICIPANT_VERIFICATION_COMPLETED: 'olm.participant_verification_completed'
37
+ };
38
+ /**
39
+ * This class implements an End-to-End Encrypted communication channel between every two peers
40
+ * in the conference. This channel uses libolm to achieve E2EE.
41
+ *
42
+ * The created channel is then used to exchange the secret key that each participant will use
43
+ * to encrypt the actual media (see {@link E2EEContext}).
44
+ *
45
+ * A simple JSON message based protocol is implemented, which follows a request - response model:
46
+ * - session-init: Initiates an olm session establishment procedure. This message will be sent
47
+ * by the participant who just joined, to everyone else.
48
+ * - session-ack: Completes the olm session etablishment. This messsage may contain ancilliary
49
+ * encrypted data, more specifically the sender's current key.
50
+ * - key-info: Includes the sender's most up to date key information.
51
+ * - key-info-ack: Acknowledges the reception of a key-info request. In addition, it may contain
52
+ * the sender's key information, if available.
53
+ * - error: Indicates a request processing error has occurred.
54
+ *
55
+ * These requessts and responses are transport independent. Currently they are sent using XMPP
56
+ * MUC private messages.
57
+ */
58
+ export class OlmAdapter extends Listenable {
59
+ /**
60
+ * Creates an adapter instance for the given conference.
61
+ */
62
+ constructor(conference) {
63
+ super();
64
+ this._conf = conference;
65
+ this._init = new Deferred();
66
+ this._mediaKey = undefined;
67
+ this._mediaKeyIndex = -1;
68
+ this._reqs = new Map();
69
+ this._sessionInitialization = undefined;
70
+ if (OlmAdapter.isSupported()) {
71
+ this._bootstrapOlm();
72
+ this._conf.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, this._onEndpointMessageReceived.bind(this));
73
+ this._conf.on(JitsiConferenceEvents.CONFERENCE_LEFT, this._onConferenceLeft.bind(this));
74
+ this._conf.on(JitsiConferenceEvents.USER_LEFT, this._onParticipantLeft.bind(this));
75
+ this._conf.on(JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED, this._onParticipantPropertyChanged.bind(this));
76
+ }
77
+ else {
78
+ this._init.reject(new Error('Olm not supported'));
79
+ }
80
+ }
81
+ /**
82
+ * Returns the current participants conference ID.
83
+ *
84
+ * @returns {string}
85
+ */
86
+ get myId() {
87
+ return this._conf.myUserId();
88
+ }
89
+ /**
90
+ * Starts new olm sessions with every other participant that has the participantId "smaller" the localParticipantId.
91
+ */
92
+ async initSessions() {
93
+ if (this._sessionInitialization) {
94
+ throw new Error('OlmAdapter initSessions called multiple times');
95
+ }
96
+ else {
97
+ this._sessionInitialization = new Deferred();
98
+ await this._init;
99
+ const promises = [];
100
+ const localParticipantId = this._conf.myUserId();
101
+ for (const participant of this._conf.getParticipants()) {
102
+ if (participant.hasFeature(FEATURE_E2EE) && localParticipantId < participant.getId()) {
103
+ promises.push(this._sendSessionInit(participant));
104
+ }
105
+ }
106
+ await Promise.allSettled(promises);
107
+ // TODO: retry failed ones.
108
+ this._sessionInitialization.resolve();
109
+ this._sessionInitialization = undefined;
110
+ }
111
+ }
112
+ /**
113
+ * Indicates if olm is supported on the current platform.
114
+ *
115
+ * @returns {boolean}
116
+ */
117
+ static isSupported() {
118
+ return typeof window.Olm !== 'undefined';
119
+ }
120
+ /**
121
+ * Updates the current participant key and distributes it to all participants in the conference
122
+ * by sending a key-info message.
123
+ *
124
+ * @param {Uint8Array|boolean} key - The new key.
125
+ * @retrns {Promise<Number>}
126
+ */
127
+ async updateKey(key) {
128
+ // Store it locally for new sessions.
129
+ this._mediaKey = key;
130
+ this._mediaKeyIndex++;
131
+ // Broadcast it.
132
+ const promises = [];
133
+ for (const participant of this._conf.getParticipants()) {
134
+ const pId = participant.getId();
135
+ const olmData = this._getParticipantOlmData(participant);
136
+ // TODO: skip those who don't support E2EE.
137
+ if (!olmData.session) {
138
+ logger.warn(`Tried to send key to participant ${pId} but we have no session`);
139
+ // eslint-disable-next-line no-continue
140
+ continue;
141
+ }
142
+ const uuid = uuidv4();
143
+ const data = {
144
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
145
+ olm: {
146
+ data: {
147
+ ciphertext: this._encryptKeyInfo(olmData.session),
148
+ uuid
149
+ },
150
+ type: OLM_MESSAGE_TYPES.KEY_INFO
151
+ }
152
+ };
153
+ const d = new Deferred();
154
+ d.setRejectTimeout(REQ_TIMEOUT);
155
+ d.catch(() => {
156
+ this._reqs.delete(uuid);
157
+ });
158
+ this._reqs.set(uuid, d);
159
+ promises.push(d);
160
+ this._sendMessage(data, pId);
161
+ }
162
+ await Promise.allSettled(promises);
163
+ // TODO: retry failed ones?
164
+ return this._mediaKeyIndex;
165
+ }
166
+ /**
167
+ * Updates the current participant key.
168
+ * @param {Uint8Array|boolean} key - The new key.
169
+ * @returns {number}
170
+ */
171
+ updateCurrentMediaKey(key) {
172
+ this._mediaKey = key;
173
+ return this._mediaKeyIndex;
174
+ }
175
+ /**
176
+ * Frees the olmData session for the given participant.
177
+ *
178
+ */
179
+ clearParticipantSession(participant) {
180
+ const olmData = this._getParticipantOlmData(participant);
181
+ if (olmData.session) {
182
+ olmData.session.free();
183
+ olmData.session = undefined;
184
+ }
185
+ }
186
+ /**
187
+ * Frees the olmData sessions for all participants.
188
+ *
189
+ */
190
+ clearAllParticipantsSessions() {
191
+ for (const participant of this._conf.getParticipants()) {
192
+ this.clearParticipantSession(participant);
193
+ }
194
+ }
195
+ /**
196
+ * Sends sacMac if channel verification waas successful.
197
+ *
198
+ */
199
+ markParticipantVerified(participant, isVerified) {
200
+ const olmData = this._getParticipantOlmData(participant);
201
+ const pId = participant.getId();
202
+ if (!isVerified) {
203
+ olmData.sasVerification = undefined;
204
+ logger.warn(`Verification failed for participant ${pId}`);
205
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_CHANNEL_VERIFICATION_FAILED);
206
+ return;
207
+ }
208
+ if (!olmData.sasVerification) {
209
+ logger.warn(`Participant ${pId} does not have valid sasVerification`);
210
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_INVALID_SAS_VERIFICATION);
211
+ return;
212
+ }
213
+ const { sas, sasMacSent } = olmData.sasVerification;
214
+ if (sas && sas.is_their_key_set() && !sasMacSent) {
215
+ this._sendSasMac(participant);
216
+ // Mark the MAC as sent so we don't send it multiple times.
217
+ olmData.sasVerification.sasMacSent = true;
218
+ }
219
+ }
220
+ /**
221
+ * Internal helper to bootstrap the olm library.
222
+ *
223
+ * @returns {Promise<void>}
224
+ * @private
225
+ */
226
+ async _bootstrapOlm() {
227
+ logger.debug('Initializing Olm...');
228
+ try {
229
+ await Olm.init();
230
+ this._olmAccount = new Olm.Account();
231
+ this._olmAccount.create();
232
+ this._idKeys = _safeJsonParse(this._olmAccount.identity_keys());
233
+ logger.debug(`Olm ${Olm.get_library_version().join('.')} initialized`);
234
+ this._init.resolve();
235
+ this._onIdKeysReady(this._idKeys);
236
+ }
237
+ catch (e) {
238
+ logger.error('Failed to initialize Olm', e);
239
+ this._init.reject(e);
240
+ }
241
+ }
242
+ /**
243
+ * Starts the verification process for the given participant as described here
244
+ * https://spec.matrix.org/latest/client-server-api/#short-authentication-string-sas-verification
245
+ *
246
+ * | |
247
+ | m.key.verification.start |
248
+ |-------------------------------->|
249
+ | |
250
+ | m.key.verification.accept |
251
+ |<--------------------------------|
252
+ | |
253
+ | m.key.verification.key |
254
+ |-------------------------------->|
255
+ | |
256
+ | m.key.verification.key |
257
+ |<--------------------------------|
258
+ | |
259
+ | m.key.verification.mac |
260
+ |-------------------------------->|
261
+ | |
262
+ | m.key.verification.mac |
263
+ |<--------------------------------|
264
+ | |
265
+ *
266
+ * @param {JitsiParticipant} participant - The target participant.
267
+ * @returns {Promise<void>}
268
+ * @private
269
+ */
270
+ startVerification(participant) {
271
+ const pId = participant.getId();
272
+ const olmData = this._getParticipantOlmData(participant);
273
+ if (!olmData.session) {
274
+ logger.warn(`Tried to start verification with participant ${pId} but we have no session`);
275
+ return;
276
+ }
277
+ if (olmData.sasVerification) {
278
+ logger.warn(`There is already a verification in progress with participant ${pId}`);
279
+ return;
280
+ }
281
+ olmData.sasVerification = {
282
+ sas: new Olm.SAS(),
283
+ transactionId: uuidv4()
284
+ };
285
+ const startContent = {
286
+ transactionId: olmData.sasVerification.transactionId
287
+ };
288
+ olmData.sasVerification.startContent = startContent;
289
+ olmData.sasVerification.isInitiator = true;
290
+ const startMessage = {
291
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
292
+ olm: {
293
+ data: startContent,
294
+ type: OLM_MESSAGE_TYPES.SAS_START
295
+ }
296
+ };
297
+ this._sendMessage(startMessage, pId);
298
+ }
299
+ /**
300
+ * Publishes our own Olmn id key in presence.
301
+ * @private
302
+ */
303
+ _onIdKeysReady(idKeys) {
304
+ logger.debug(`Olm id key ready: ${idKeys}`);
305
+ // Publish it in presence.
306
+ for (const keyType in idKeys) {
307
+ if (idKeys.hasOwnProperty(keyType)) {
308
+ const key = idKeys[keyType];
309
+ this._conf.setLocalParticipantProperty(`e2ee.idKey.${keyType}`, key);
310
+ }
311
+ }
312
+ }
313
+ /**
314
+ * Event posted when the E2EE signalling channel has been established with the given participant.
315
+ * @private
316
+ */
317
+ _onParticipantE2EEChannelReady(id) {
318
+ logger.debug(`E2EE channel with participant ${id} is ready`);
319
+ }
320
+ /**
321
+ * Internal helper for encrypting the current key information for a given participant.
322
+ *
323
+ * @param {Olm.Session} session - Participant's session.
324
+ * @returns {string} - The encrypted text with the key information.
325
+ * @private
326
+ */
327
+ _encryptKeyInfo(session) {
328
+ const keyInfo = {};
329
+ if (this._mediaKey !== undefined) {
330
+ keyInfo.key = this._mediaKey ? base64js.fromByteArray(this._mediaKey) : false;
331
+ keyInfo.keyIndex = this._mediaKeyIndex;
332
+ }
333
+ return session.encrypt(JSON.stringify(keyInfo));
334
+ }
335
+ /**
336
+ * Internal helper for getting the olm related data associated with a participant.
337
+ *
338
+ * @param {JitsiParticipant} participant - Participant whose data wants to be extracted.
339
+ * @returns {Object}
340
+ * @private
341
+ */
342
+ _getParticipantOlmData(participant) {
343
+ participant[kOlmData] = participant[kOlmData] || {};
344
+ return participant[kOlmData];
345
+ }
346
+ /**
347
+ * Handles leaving the conference, cleaning up olm sessions.
348
+ *
349
+ * @private
350
+ */
351
+ async _onConferenceLeft() {
352
+ logger.debug('Conference left');
353
+ await this._init;
354
+ for (const participant of this._conf.getParticipants()) {
355
+ this._onParticipantLeft(participant.getId(), participant);
356
+ }
357
+ if (this._olmAccount) {
358
+ this._olmAccount.free();
359
+ this._olmAccount = undefined;
360
+ }
361
+ }
362
+ /**
363
+ * Main message handler. Handles 1-to-1 messages received from other participants
364
+ * and send the appropriate replies.
365
+ *
366
+ * @private
367
+ */
368
+ async _onEndpointMessageReceived(participant, payload) {
369
+ if (payload[JITSI_MEET_MUC_TYPE] !== OLM_MESSAGE_TYPE) {
370
+ return;
371
+ }
372
+ if (!payload.olm) {
373
+ logger.warn('Incorrectly formatted message');
374
+ return;
375
+ }
376
+ await this._init;
377
+ const msg = payload.olm;
378
+ const pId = participant.getId();
379
+ const olmData = this._getParticipantOlmData(participant);
380
+ switch (msg.type) {
381
+ case OLM_MESSAGE_TYPES.SESSION_INIT: {
382
+ if (olmData.session) {
383
+ logger.warn(`Participant ${pId} already has a session`);
384
+ this._sendError(participant, 'Session already established');
385
+ }
386
+ else {
387
+ // Create a session for communicating with this participant.
388
+ const session = new Olm.Session();
389
+ session.create_outbound(this._olmAccount, msg.data.idKey, msg.data.otKey);
390
+ olmData.session = session;
391
+ // Send ACK
392
+ const ack = {
393
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
394
+ olm: {
395
+ data: {
396
+ ciphertext: this._encryptKeyInfo(session),
397
+ uuid: msg.data.uuid
398
+ },
399
+ type: OLM_MESSAGE_TYPES.SESSION_ACK
400
+ }
401
+ };
402
+ this._sendMessage(ack, pId);
403
+ this._onParticipantE2EEChannelReady(pId);
404
+ }
405
+ break;
406
+ }
407
+ case OLM_MESSAGE_TYPES.SESSION_ACK: {
408
+ if (olmData.session) {
409
+ logger.warn(`Participant ${pId} already has a session`);
410
+ this._sendError(participant, 'No session found');
411
+ }
412
+ else if (msg.data.uuid === olmData.pendingSessionUuid) {
413
+ const { ciphertext } = msg.data;
414
+ const d = this._reqs.get(msg.data.uuid);
415
+ const session = new Olm.Session();
416
+ session.create_inbound(this._olmAccount, ciphertext.body);
417
+ // Remove OT keys that have been used to setup this session.
418
+ this._olmAccount.remove_one_time_keys(session);
419
+ // Decrypt first message.
420
+ const data = session.decrypt(ciphertext.type, ciphertext.body);
421
+ olmData.session = session;
422
+ olmData.pendingSessionUuid = undefined;
423
+ this._onParticipantE2EEChannelReady(pId);
424
+ this._reqs.delete(msg.data.uuid);
425
+ d.resolve();
426
+ const json = safeJsonParse(data);
427
+ if (json.key) {
428
+ const key = base64js.toByteArray(json.key);
429
+ const keyIndex = json.keyIndex;
430
+ olmData.lastKey = key;
431
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_KEY_UPDATED, pId, key, keyIndex);
432
+ }
433
+ }
434
+ else {
435
+ logger.warn('Received ACK with the wrong UUID');
436
+ this._sendError(participant, 'Invalid UUID');
437
+ }
438
+ break;
439
+ }
440
+ case OLM_MESSAGE_TYPES.ERROR: {
441
+ logger.error(msg.data.error);
442
+ break;
443
+ }
444
+ case OLM_MESSAGE_TYPES.KEY_INFO: {
445
+ if (olmData.session) {
446
+ const { ciphertext } = msg.data;
447
+ const data = olmData.session.decrypt(ciphertext.type, ciphertext.body);
448
+ const json = safeJsonParse(data);
449
+ if (json.key !== undefined && json.keyIndex !== undefined) {
450
+ const key = json.key ? base64js.toByteArray(json.key) : false;
451
+ const keyIndex = json.keyIndex;
452
+ if (!isEqual(olmData.lastKey, key)) {
453
+ olmData.lastKey = key;
454
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_KEY_UPDATED, pId, key, keyIndex);
455
+ }
456
+ // Send ACK.
457
+ const ack = {
458
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
459
+ olm: {
460
+ data: {
461
+ ciphertext: this._encryptKeyInfo(olmData.session),
462
+ uuid: msg.data.uuid
463
+ },
464
+ type: OLM_MESSAGE_TYPES.KEY_INFO_ACK
465
+ }
466
+ };
467
+ this._sendMessage(ack, pId);
468
+ }
469
+ }
470
+ else {
471
+ logger.debug(`Received key info message from ${pId} but we have no session for them!`);
472
+ this._sendError(participant, 'No session found while processing key-info');
473
+ }
474
+ break;
475
+ }
476
+ case OLM_MESSAGE_TYPES.KEY_INFO_ACK: {
477
+ if (olmData.session) {
478
+ const { ciphertext } = msg.data;
479
+ const data = olmData.session.decrypt(ciphertext.type, ciphertext.body);
480
+ const json = safeJsonParse(data);
481
+ if (json.key !== undefined && json.keyIndex !== undefined) {
482
+ const key = json.key ? base64js.toByteArray(json.key) : false;
483
+ const keyIndex = json.keyIndex;
484
+ if (!isEqual(olmData.lastKey, key)) {
485
+ olmData.lastKey = key;
486
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_KEY_UPDATED, pId, key, keyIndex);
487
+ }
488
+ }
489
+ const d = this._reqs.get(msg.data.uuid);
490
+ this._reqs.delete(msg.data.uuid);
491
+ d.resolve();
492
+ }
493
+ else {
494
+ logger.debug(`Received key info ack message from ${pId} but we have no session for them!`);
495
+ this._sendError(participant, 'No session found while processing key-info-ack');
496
+ }
497
+ break;
498
+ }
499
+ case OLM_MESSAGE_TYPES.SAS_START: {
500
+ if (!olmData.session) {
501
+ logger.debug(`Received sas init message from ${pId} but we have no session for them!`);
502
+ this._sendError(participant, 'No session found while processing sas-init');
503
+ return;
504
+ }
505
+ if (olmData.sasVerification?.sas) {
506
+ logger.warn(`SAS already created for participant ${pId}`);
507
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_INVALID_SAS_VERIFICATION);
508
+ return;
509
+ }
510
+ const { transactionId } = msg.data;
511
+ const sas = new Olm.SAS();
512
+ olmData.sasVerification = {
513
+ isInitiator: false,
514
+ sas,
515
+ transactionId
516
+ };
517
+ const pubKey = olmData.sasVerification.sas.get_pubkey();
518
+ const commitment = this._computeCommitment(pubKey, msg.data);
519
+ /* The first phase of the verification process, the Key agreement phase
520
+ https://spec.matrix.org/latest/client-server-api/#short-authentication-string-sas-verification
521
+ */
522
+ const acceptMessage = {
523
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
524
+ olm: {
525
+ data: {
526
+ commitment,
527
+ transactionId
528
+ },
529
+ type: OLM_MESSAGE_TYPES.SAS_ACCEPT
530
+ }
531
+ };
532
+ this._sendMessage(acceptMessage, pId);
533
+ break;
534
+ }
535
+ case OLM_MESSAGE_TYPES.SAS_ACCEPT: {
536
+ if (!olmData.session) {
537
+ logger.debug(`Received sas accept message from ${pId} but we have no session for them!`);
538
+ this._sendError(participant, 'No session found while processing sas-accept');
539
+ return;
540
+ }
541
+ const { commitment, transactionId } = msg.data;
542
+ if (!olmData.sasVerification) {
543
+ logger.warn(`SAS_ACCEPT Participant ${pId} does not have valid sasVerification`);
544
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_INVALID_SAS_VERIFICATION);
545
+ return;
546
+ }
547
+ if (olmData.sasVerification.sasCommitment) {
548
+ logger.debug(`Already received sas commitment message from ${pId}!`);
549
+ this._sendError(participant, 'Already received sas commitment message from ${pId}!');
550
+ return;
551
+ }
552
+ olmData.sasVerification.sasCommitment = commitment;
553
+ const pubKey = olmData.sasVerification.sas.get_pubkey();
554
+ // Send KEY.
555
+ const keyMessage = {
556
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
557
+ olm: {
558
+ data: {
559
+ key: pubKey,
560
+ transactionId
561
+ },
562
+ type: OLM_MESSAGE_TYPES.SAS_KEY
563
+ }
564
+ };
565
+ this._sendMessage(keyMessage, pId);
566
+ olmData.sasVerification.keySent = true;
567
+ break;
568
+ }
569
+ case OLM_MESSAGE_TYPES.SAS_KEY: {
570
+ if (!olmData.session) {
571
+ logger.debug(`Received sas key message from ${pId} but we have no session for them!`);
572
+ this._sendError(participant, 'No session found while processing sas-key');
573
+ return;
574
+ }
575
+ if (!olmData.sasVerification) {
576
+ logger.warn(`SAS_KEY Participant ${pId} does not have valid sasVerification`);
577
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_INVALID_SAS_VERIFICATION);
578
+ return;
579
+ }
580
+ const { isInitiator, sas, sasCommitment, startContent, keySent } = olmData.sasVerification;
581
+ if (sas.is_their_key_set()) {
582
+ logger.warn('SAS already has their key!');
583
+ return;
584
+ }
585
+ const { key: theirKey, transactionId } = msg.data;
586
+ if (sasCommitment) {
587
+ const commitment = this._computeCommitment(theirKey, startContent);
588
+ if (sasCommitment !== commitment) {
589
+ this._sendError(participant, 'OlmAdapter commitments mismatched');
590
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_COMMITMENT_MISMATCHED);
591
+ olmData.sasVerification.free();
592
+ return;
593
+ }
594
+ }
595
+ sas.set_their_key(theirKey);
596
+ const pubKey = sas.get_pubkey();
597
+ const myInfo = `${this.myId}|${pubKey}`;
598
+ const theirInfo = `${pId}|${theirKey}`;
599
+ const info = isInitiator ? `${myInfo}|${theirInfo}` : `${theirInfo}|${myInfo}`;
600
+ const sasBytes = sas.generate_bytes(info, OLM_SAS_NUM_BYTES);
601
+ const generatedSas = generateSas(sasBytes);
602
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_SAS_READY, pId, generatedSas);
603
+ if (keySent) {
604
+ return;
605
+ }
606
+ const keyMessage = {
607
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
608
+ olm: {
609
+ data: {
610
+ key: pubKey,
611
+ transactionId
612
+ },
613
+ type: OLM_MESSAGE_TYPES.SAS_KEY
614
+ }
615
+ };
616
+ this._sendMessage(keyMessage, pId);
617
+ olmData.sasVerification.keySent = true;
618
+ break;
619
+ }
620
+ case OLM_MESSAGE_TYPES.SAS_MAC: {
621
+ if (!olmData.session) {
622
+ logger.debug(`Received sas mac message from ${pId} but we have no session for them!`);
623
+ this._sendError(participant, 'No session found while processing sas-mac');
624
+ return;
625
+ }
626
+ const { keys, mac, transactionId } = msg.data;
627
+ if (!mac || !keys) {
628
+ logger.warn('Invalid SAS MAC message');
629
+ return;
630
+ }
631
+ if (!olmData.sasVerification) {
632
+ logger.warn(`SAS_MAC Participant ${pId} does not have valid sasVerification`);
633
+ return;
634
+ }
635
+ const sas = olmData.sasVerification.sas;
636
+ // Verify the received MACs.
637
+ const baseInfo = `${OLM_KEY_VERIFICATION_MAC_INFO}${pId}${this.myId}${transactionId}`;
638
+ const keysMac = sas.calculate_mac(Object.keys(mac).sort().join(','), // eslint-disable-line newline-per-chained-call
639
+ baseInfo + OLM_KEY_VERIFICATION_MAC_KEY_IDS);
640
+ if (keysMac !== keys) {
641
+ logger.error('SAS verification error: keys MAC mismatch');
642
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_KEYS_MAC_MISMATCH);
643
+ return;
644
+ }
645
+ if (!olmData.ed25519) {
646
+ logger.warn('SAS verification error: Missing ed25519 key');
647
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_MISSING_KEY);
648
+ return;
649
+ }
650
+ for (const [keyInfo, computedMac] of Object.entries(mac)) {
651
+ const ourComputedMac = sas.calculate_mac(olmData.ed25519, baseInfo + keyInfo);
652
+ if (computedMac !== ourComputedMac) {
653
+ logger.error('SAS verification error: MAC mismatch');
654
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, false, E2EEErrors.E2EE_SAS_MAC_MISMATCH);
655
+ return;
656
+ }
657
+ }
658
+ logger.info(`SAS MAC verified for participant ${pId}`);
659
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_VERIFICATION_COMPLETED, pId, true);
660
+ break;
661
+ }
662
+ }
663
+ }
664
+ /**
665
+ * Handles a participant leaving. When a participant leaves their olm session is destroyed.
666
+ *
667
+ * @private
668
+ */
669
+ _onParticipantLeft(id, participant) {
670
+ logger.debug(`Participant ${id} left`);
671
+ this.clearParticipantSession(participant);
672
+ }
673
+ /**
674
+ * Handles an update in a participant's presence property.
675
+ *
676
+ * @param {JitsiParticipant} participant - The participant.
677
+ * @param {string} name - The name of the property that changed.
678
+ * @param {*} oldValue - The property's previous value.
679
+ * @param {*} newValue - The property's new value.
680
+ * @private
681
+ */
682
+ async _onParticipantPropertyChanged(participant, name, oldValue, newValue) {
683
+ const participantId = participant.getId();
684
+ const olmData = this._getParticipantOlmData(participant);
685
+ switch (name) {
686
+ case 'e2ee.enabled':
687
+ if (newValue && this._conf.isE2EEEnabled()) {
688
+ const localParticipantId = this._conf.myUserId();
689
+ const participantFeatures = await participant.getFeatures();
690
+ if (participantFeatures.has(FEATURE_E2EE) && localParticipantId < participantId) {
691
+ if (this._sessionInitialization) {
692
+ await this._sessionInitialization;
693
+ }
694
+ await this._sendSessionInit(participant);
695
+ const uuid = uuidv4();
696
+ const d = new Deferred();
697
+ d.setRejectTimeout(REQ_TIMEOUT);
698
+ d.catch(() => {
699
+ this._reqs.delete(uuid);
700
+ olmData.pendingSessionUuid = undefined;
701
+ });
702
+ this._reqs.set(uuid, d);
703
+ const data = {
704
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
705
+ olm: {
706
+ data: {
707
+ ciphertext: this._encryptKeyInfo(olmData.session),
708
+ uuid
709
+ },
710
+ type: OLM_MESSAGE_TYPES.KEY_INFO
711
+ }
712
+ };
713
+ this._sendMessage(data, participantId);
714
+ }
715
+ }
716
+ break;
717
+ case 'e2ee.idKey.ed25519':
718
+ olmData.ed25519 = newValue;
719
+ this.eventEmitter.emit(OlmAdapterEvents.PARTICIPANT_SAS_AVAILABLE, participantId);
720
+ break;
721
+ }
722
+ }
723
+ /**
724
+ * Builds and sends an error message to the target participant.
725
+ *
726
+ * @param {JitsiParticipant} participant - The target participant.
727
+ * @param {string} error - The error message.
728
+ * @returns {void}
729
+ */
730
+ _sendError(participant, error) {
731
+ const pId = participant.getId();
732
+ const err = {
733
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
734
+ olm: {
735
+ data: {
736
+ error
737
+ },
738
+ type: OLM_MESSAGE_TYPES.ERROR
739
+ }
740
+ };
741
+ this._sendMessage(err, pId);
742
+ }
743
+ /**
744
+ * Internal helper to send the given object to the given participant ID.
745
+ * This function merely exists so the transport can be easily swapped.
746
+ * Currently messages are transmitted via XMPP MUC private messages.
747
+ *
748
+ * @param {object} data - The data that will be sent to the target participant.
749
+ * @param {string} participantId - ID of the target participant.
750
+ */
751
+ _sendMessage(data, participantId) {
752
+ this._conf.sendMessage(data, participantId);
753
+ }
754
+ /**
755
+ * Builds and sends the session-init request to the target participant.
756
+ *
757
+ * @param {JitsiParticipant} participant - Participant to whom we'll send the request.
758
+ * @returns {Promise} - The promise will be resolved when the session-ack is received.
759
+ * @private
760
+ */
761
+ _sendSessionInit(participant) {
762
+ const pId = participant.getId();
763
+ const olmData = this._getParticipantOlmData(participant);
764
+ if (olmData.session) {
765
+ logger.warn(`Tried to send session-init to ${pId} but we already have a session`);
766
+ return Promise.reject();
767
+ }
768
+ if (olmData.pendingSessionUuid !== undefined) {
769
+ logger.warn(`Tried to send session-init to ${pId} but we already have a pending session`);
770
+ return Promise.reject();
771
+ }
772
+ // Generate a One Time Key.
773
+ this._olmAccount.generate_one_time_keys(1);
774
+ const otKeys = _safeJsonParse(this._olmAccount.one_time_keys());
775
+ const otKey = Object.values(otKeys.curve25519)[0];
776
+ if (!otKey) {
777
+ return Promise.reject(new Error('No one-time-keys generated'));
778
+ }
779
+ // Mark the OT keys (one really) as published so they are not reused.
780
+ this._olmAccount.mark_keys_as_published();
781
+ const uuid = uuidv4();
782
+ const init = {
783
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
784
+ olm: {
785
+ data: {
786
+ idKey: this._idKeys.curve25519,
787
+ otKey,
788
+ uuid
789
+ },
790
+ type: OLM_MESSAGE_TYPES.SESSION_INIT
791
+ }
792
+ };
793
+ const d = new Deferred();
794
+ d.setRejectTimeout(REQ_TIMEOUT);
795
+ d.catch(() => {
796
+ this._reqs.delete(uuid);
797
+ olmData.pendingSessionUuid = undefined;
798
+ });
799
+ this._reqs.set(uuid, d);
800
+ this._sendMessage(init, pId);
801
+ // Store the UUID for matching with the ACK.
802
+ olmData.pendingSessionUuid = uuid;
803
+ return d;
804
+ }
805
+ /**
806
+ * Builds and sends the SAS MAC message to the given participant.
807
+ * The second phase of the verification process, the Key verification phase
808
+ https://spec.matrix.org/latest/client-server-api/#short-authentication-string-sas-verification
809
+ */
810
+ _sendSasMac(participant) {
811
+ const pId = participant.getId();
812
+ const olmData = this._getParticipantOlmData(participant);
813
+ const { sas, transactionId } = olmData.sasVerification;
814
+ // Calculate and send MAC with the keys to be verified.
815
+ const mac = {};
816
+ const keyList = [];
817
+ const baseInfo = `${OLM_KEY_VERIFICATION_MAC_INFO}${this.myId}${pId}${transactionId}`;
818
+ const deviceKeyId = `ed25519:${pId}`;
819
+ mac[deviceKeyId] = sas.calculate_mac(this._idKeys.ed25519, baseInfo + deviceKeyId);
820
+ keyList.push(deviceKeyId);
821
+ const keys = sas.calculate_mac(keyList.sort().join(','), baseInfo + OLM_KEY_VERIFICATION_MAC_KEY_IDS);
822
+ const macMessage = {
823
+ [JITSI_MEET_MUC_TYPE]: OLM_MESSAGE_TYPE,
824
+ olm: {
825
+ data: {
826
+ keys,
827
+ mac,
828
+ transactionId
829
+ },
830
+ type: OLM_MESSAGE_TYPES.SAS_MAC
831
+ }
832
+ };
833
+ this._sendMessage(macMessage, pId);
834
+ }
835
+ /**
836
+ * Computes the commitment.
837
+ */
838
+ _computeCommitment(pubKey, data) {
839
+ const olmUtil = new Olm.Utility();
840
+ const commitment = olmUtil.sha256(pubKey + JSON.stringify(data));
841
+ olmUtil.free();
842
+ return commitment;
843
+ }
844
+ }
845
+ /**
846
+ * Helper to ensure JSON parsing always returns an object.
847
+ *
848
+ * @param {string} data - The data that needs to be parsed.
849
+ * @returns {object} - Parsed data or empty object in case of failure.
850
+ */
851
+ function safeJsonParse(data) {
852
+ try {
853
+ return _safeJsonParse(data);
854
+ }
855
+ catch (e) {
856
+ return {};
857
+ }
858
+ }
859
+ OlmAdapter.events = OlmAdapterEvents;
860
+ //# sourceMappingURL=OlmAdapter.js.map