@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.
- package/LICENSE +202 -0
- package/README.md +26 -0
- package/dist/esm/JitsiConference.js +3692 -0
- package/dist/esm/JitsiConference.js.map +1 -0
- package/dist/esm/JitsiConferenceErrors.js +126 -0
- package/dist/esm/JitsiConferenceErrors.js.map +1 -0
- package/dist/esm/JitsiConferenceEventManager.js +424 -0
- package/dist/esm/JitsiConferenceEventManager.js.map +1 -0
- package/dist/esm/JitsiConferenceEvents.js +431 -0
- package/dist/esm/JitsiConferenceEvents.js.map +1 -0
- package/dist/esm/JitsiConnection.js +187 -0
- package/dist/esm/JitsiConnection.js.map +1 -0
- package/dist/esm/JitsiConnectionErrors.js +52 -0
- package/dist/esm/JitsiConnectionErrors.js.map +1 -0
- package/dist/esm/JitsiConnectionEvents.js +57 -0
- package/dist/esm/JitsiConnectionEvents.js.map +1 -0
- package/dist/esm/JitsiMediaDevices.js +221 -0
- package/dist/esm/JitsiMediaDevices.js.map +1 -0
- package/dist/esm/JitsiMediaDevicesEvents.js +29 -0
- package/dist/esm/JitsiMediaDevicesEvents.js.map +1 -0
- package/dist/esm/JitsiMeetJS.js +499 -0
- package/dist/esm/JitsiMeetJS.js.map +1 -0
- package/dist/esm/JitsiParticipant.js +323 -0
- package/dist/esm/JitsiParticipant.js.map +1 -0
- package/dist/esm/JitsiTrackError.js +122 -0
- package/dist/esm/JitsiTrackError.js.map +1 -0
- package/dist/esm/JitsiTrackErrors.js +91 -0
- package/dist/esm/JitsiTrackErrors.js.map +1 -0
- package/dist/esm/JitsiTrackEvents.js +60 -0
- package/dist/esm/JitsiTrackEvents.js.map +1 -0
- package/dist/esm/JitsiTranscriptionStatus.js +15 -0
- package/dist/esm/JitsiTranscriptionStatus.js.map +1 -0
- package/dist/esm/modules/RTC/BridgeChannel.js +398 -0
- package/dist/esm/modules/RTC/BridgeChannel.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiLocalTrack.js +896 -0
- package/dist/esm/modules/RTC/JitsiLocalTrack.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiRemoteTrack.js +427 -0
- package/dist/esm/modules/RTC/JitsiRemoteTrack.js.map +1 -0
- package/dist/esm/modules/RTC/JitsiTrack.js +453 -0
- package/dist/esm/modules/RTC/JitsiTrack.js.map +1 -0
- package/dist/esm/modules/RTC/MockClasses.js +388 -0
- package/dist/esm/modules/RTC/MockClasses.js.map +1 -0
- package/dist/esm/modules/RTC/RTC.js +658 -0
- package/dist/esm/modules/RTC/RTC.js.map +1 -0
- package/dist/esm/modules/RTC/RTCUtils.js +762 -0
- package/dist/esm/modules/RTC/RTCUtils.js.map +1 -0
- package/dist/esm/modules/RTC/ScreenObtainer.js +380 -0
- package/dist/esm/modules/RTC/ScreenObtainer.js.map +1 -0
- package/dist/esm/modules/RTC/TPCUtils.js +803 -0
- package/dist/esm/modules/RTC/TPCUtils.js.map +1 -0
- package/dist/esm/modules/RTC/TraceablePeerConnection.js +2223 -0
- package/dist/esm/modules/RTC/TraceablePeerConnection.js.map +1 -0
- package/dist/esm/modules/RTCStats/DefaulLogStorage.js +35 -0
- package/dist/esm/modules/RTCStats/DefaulLogStorage.js.map +1 -0
- package/dist/esm/modules/RTCStats/RTCStats.js +219 -0
- package/dist/esm/modules/RTCStats/RTCStats.js.map +1 -0
- package/dist/esm/modules/RTCStats/RTCStatsEvents.js +92 -0
- package/dist/esm/modules/RTCStats/RTCStatsEvents.js.map +1 -0
- package/dist/esm/modules/RTCStats/interfaces.js +2 -0
- package/dist/esm/modules/RTCStats/interfaces.js.map +1 -0
- package/dist/esm/modules/browser/BrowserCapabilities.js +345 -0
- package/dist/esm/modules/browser/BrowserCapabilities.js.map +1 -0
- package/dist/esm/modules/browser/index.js +3 -0
- package/dist/esm/modules/browser/index.js.map +1 -0
- package/dist/esm/modules/connectivity/ConnectionQuality.js +389 -0
- package/dist/esm/modules/connectivity/ConnectionQuality.js.map +1 -0
- package/dist/esm/modules/connectivity/IceFailedHandling.js +84 -0
- package/dist/esm/modules/connectivity/IceFailedHandling.js.map +1 -0
- package/dist/esm/modules/connectivity/NetworkInfo.js +49 -0
- package/dist/esm/modules/connectivity/NetworkInfo.js.map +1 -0
- package/dist/esm/modules/connectivity/TrackStreamingStatus.js +453 -0
- package/dist/esm/modules/connectivity/TrackStreamingStatus.js.map +1 -0
- package/dist/esm/modules/detection/ActiveDeviceDetector.js +79 -0
- package/dist/esm/modules/detection/ActiveDeviceDetector.js.map +1 -0
- package/dist/esm/modules/detection/DetectionEvents.js +58 -0
- package/dist/esm/modules/detection/DetectionEvents.js.map +1 -0
- package/dist/esm/modules/detection/NoAudioSignalDetection.js +127 -0
- package/dist/esm/modules/detection/NoAudioSignalDetection.js.map +1 -0
- package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js +47 -0
- package/dist/esm/modules/detection/P2PDominantSpeakerDetection.js.map +1 -0
- package/dist/esm/modules/detection/TrackVADEmitter.js +190 -0
- package/dist/esm/modules/detection/TrackVADEmitter.js.map +1 -0
- package/dist/esm/modules/detection/VADAudioAnalyser.js +199 -0
- package/dist/esm/modules/detection/VADAudioAnalyser.js.map +1 -0
- package/dist/esm/modules/detection/VADNoiseDetection.js +168 -0
- package/dist/esm/modules/detection/VADNoiseDetection.js.map +1 -0
- package/dist/esm/modules/detection/VADReportingService.js +203 -0
- package/dist/esm/modules/detection/VADReportingService.js.map +1 -0
- package/dist/esm/modules/detection/VADTalkMutedDetection.js +131 -0
- package/dist/esm/modules/detection/VADTalkMutedDetection.js.map +1 -0
- package/dist/esm/modules/e2ee/Context.js +274 -0
- package/dist/esm/modules/e2ee/Context.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEContext.js +158 -0
- package/dist/esm/modules/e2ee/E2EEContext.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEErrors.js +10 -0
- package/dist/esm/modules/e2ee/E2EEErrors.js.map +1 -0
- package/dist/esm/modules/e2ee/E2EEncryption.js +87 -0
- package/dist/esm/modules/e2ee/E2EEncryption.js.map +1 -0
- package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js +24 -0
- package/dist/esm/modules/e2ee/ExternallyManagedKeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/KeyHandler.js +137 -0
- package/dist/esm/modules/e2ee/KeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/ManagedKeyHandler.js +182 -0
- package/dist/esm/modules/e2ee/ManagedKeyHandler.js.map +1 -0
- package/dist/esm/modules/e2ee/OlmAdapter.js +860 -0
- package/dist/esm/modules/e2ee/OlmAdapter.js.map +1 -0
- package/dist/esm/modules/e2ee/SAS.js +128 -0
- package/dist/esm/modules/e2ee/SAS.js.map +1 -0
- package/dist/esm/modules/e2ee/Worker.js +102 -0
- package/dist/esm/modules/e2ee/Worker.js.map +1 -0
- package/dist/esm/modules/e2ee/crypto-utils.js +53 -0
- package/dist/esm/modules/e2ee/crypto-utils.js.map +1 -0
- package/dist/esm/modules/e2ee/utils.js +15 -0
- package/dist/esm/modules/e2ee/utils.js.map +1 -0
- package/dist/esm/modules/e2eping/e2eping.js +314 -0
- package/dist/esm/modules/e2eping/e2eping.js.map +1 -0
- package/dist/esm/modules/flags/FeatureFlags.js +36 -0
- package/dist/esm/modules/flags/FeatureFlags.js.map +1 -0
- package/dist/esm/modules/litemode/LiteModeContext.js +50 -0
- package/dist/esm/modules/litemode/LiteModeContext.js.map +1 -0
- package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js +98 -0
- package/dist/esm/modules/proxyconnection/CustomSignalingLayer.js.map +1 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js +348 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionPC.js.map +1 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionService.js +279 -0
- package/dist/esm/modules/proxyconnection/ProxyConnectionService.js.map +1 -0
- package/dist/esm/modules/proxyconnection/constants.js +14 -0
- package/dist/esm/modules/proxyconnection/constants.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/CodecSelection.js +222 -0
- package/dist/esm/modules/qualitycontrol/CodecSelection.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/MockClasses.js +120 -0
- package/dist/esm/modules/qualitycontrol/MockClasses.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/QualityController.js +366 -0
- package/dist/esm/modules/qualitycontrol/QualityController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js +73 -0
- package/dist/esm/modules/qualitycontrol/ReceiveAudioController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js +216 -0
- package/dist/esm/modules/qualitycontrol/ReceiveVideoController.js.map +1 -0
- package/dist/esm/modules/qualitycontrol/SendVideoController.js +133 -0
- package/dist/esm/modules/qualitycontrol/SendVideoController.js.map +1 -0
- package/dist/esm/modules/recording/JibriSession.js +279 -0
- package/dist/esm/modules/recording/JibriSession.js.map +1 -0
- package/dist/esm/modules/recording/RecordingManager.js +257 -0
- package/dist/esm/modules/recording/RecordingManager.js.map +1 -0
- package/dist/esm/modules/recording/recordingConstants.js +21 -0
- package/dist/esm/modules/recording/recordingConstants.js.map +1 -0
- package/dist/esm/modules/recording/recordingXMLUtils.js +69 -0
- package/dist/esm/modules/recording/recordingXMLUtils.js.map +1 -0
- package/dist/esm/modules/red/red.js +108 -0
- package/dist/esm/modules/red/red.js.map +1 -0
- package/dist/esm/modules/sdp/LocalSdpMunger.js +143 -0
- package/dist/esm/modules/sdp/LocalSdpMunger.js.map +1 -0
- package/dist/esm/modules/sdp/RtxModifier.js +179 -0
- package/dist/esm/modules/sdp/RtxModifier.js.map +1 -0
- package/dist/esm/modules/sdp/SDP.js +848 -0
- package/dist/esm/modules/sdp/SDP.js.map +1 -0
- package/dist/esm/modules/sdp/SDPDiffer.js +96 -0
- package/dist/esm/modules/sdp/SDPDiffer.js.map +1 -0
- package/dist/esm/modules/sdp/SDPUtil.js +798 -0
- package/dist/esm/modules/sdp/SDPUtil.js.map +1 -0
- package/dist/esm/modules/sdp/SampleSdpStrings.js +589 -0
- package/dist/esm/modules/sdp/SampleSdpStrings.js.map +1 -0
- package/dist/esm/modules/sdp/SdpSimulcast.js +196 -0
- package/dist/esm/modules/sdp/SdpSimulcast.js.map +1 -0
- package/dist/esm/modules/sdp/SdpTransformUtil.js +337 -0
- package/dist/esm/modules/sdp/SdpTransformUtil.js.map +1 -0
- package/dist/esm/modules/sdp/constants.js +2 -0
- package/dist/esm/modules/sdp/constants.js.map +1 -0
- package/dist/esm/modules/settings/Settings.js +95 -0
- package/dist/esm/modules/settings/Settings.js.map +1 -0
- package/dist/esm/modules/statistics/AnalyticsAdapter.js +277 -0
- package/dist/esm/modules/statistics/AnalyticsAdapter.js.map +1 -0
- package/dist/esm/modules/statistics/AvgRTPStatsReporter.js +817 -0
- package/dist/esm/modules/statistics/AvgRTPStatsReporter.js.map +1 -0
- package/dist/esm/modules/statistics/LocalStatsCollector.js +149 -0
- package/dist/esm/modules/statistics/LocalStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/PreCallTest.js +15 -0
- package/dist/esm/modules/statistics/PreCallTest.js.map +1 -0
- package/dist/esm/modules/statistics/RTPStatsCollector.js +601 -0
- package/dist/esm/modules/statistics/RTPStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/SpeakerStats.js +163 -0
- package/dist/esm/modules/statistics/SpeakerStats.js.map +1 -0
- package/dist/esm/modules/statistics/SpeakerStatsCollector.js +161 -0
- package/dist/esm/modules/statistics/SpeakerStatsCollector.js.map +1 -0
- package/dist/esm/modules/statistics/constants.js +7 -0
- package/dist/esm/modules/statistics/constants.js.map +1 -0
- package/dist/esm/modules/statistics/statistics.js +362 -0
- package/dist/esm/modules/statistics/statistics.js.map +1 -0
- package/dist/esm/modules/util/AsyncQueue.js +102 -0
- package/dist/esm/modules/util/AsyncQueue.js.map +1 -0
- package/dist/esm/modules/util/Deferred.js +41 -0
- package/dist/esm/modules/util/Deferred.js.map +1 -0
- package/dist/esm/modules/util/EventEmitter.js +17 -0
- package/dist/esm/modules/util/EventEmitter.js.map +1 -0
- package/dist/esm/modules/util/EventEmitterForwarder.js +52 -0
- package/dist/esm/modules/util/EventEmitterForwarder.js.map +1 -0
- package/dist/esm/modules/util/Listenable.js +106 -0
- package/dist/esm/modules/util/Listenable.js.map +1 -0
- package/dist/esm/modules/util/MathUtil.js +103 -0
- package/dist/esm/modules/util/MathUtil.js.map +1 -0
- package/dist/esm/modules/util/RandomUtil.js +66 -0
- package/dist/esm/modules/util/RandomUtil.js.map +1 -0
- package/dist/esm/modules/util/Retry.js +15 -0
- package/dist/esm/modules/util/Retry.js.map +1 -0
- package/dist/esm/modules/util/ScriptUtil.js +58 -0
- package/dist/esm/modules/util/ScriptUtil.js.map +1 -0
- package/dist/esm/modules/util/StringUtils.js +21 -0
- package/dist/esm/modules/util/StringUtils.js.map +1 -0
- package/dist/esm/modules/util/TestUtils.js +14 -0
- package/dist/esm/modules/util/TestUtils.js.map +1 -0
- package/dist/esm/modules/util/UsernameGenerator.js +436 -0
- package/dist/esm/modules/util/UsernameGenerator.js.map +1 -0
- package/dist/esm/modules/util/XMLUtils.js +135 -0
- package/dist/esm/modules/util/XMLUtils.js.map +1 -0
- package/dist/esm/modules/version/ComponentsVersions.js +52 -0
- package/dist/esm/modules/version/ComponentsVersions.js.map +1 -0
- package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js +137 -0
- package/dist/esm/modules/videosipgw/JitsiVideoSIPGWSession.js.map +1 -0
- package/dist/esm/modules/videosipgw/VideoSIPGW.js +102 -0
- package/dist/esm/modules/videosipgw/VideoSIPGW.js.map +1 -0
- package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js +65 -0
- package/dist/esm/modules/videosipgw/VideoSIPGWConstants.js.map +1 -0
- package/dist/esm/modules/watchRTC/WatchRTC.js +69 -0
- package/dist/esm/modules/watchRTC/WatchRTC.js.map +1 -0
- package/dist/esm/modules/watchRTC/functions.js +31 -0
- package/dist/esm/modules/watchRTC/functions.js.map +1 -0
- package/dist/esm/modules/watchRTC/interfaces.js +2 -0
- package/dist/esm/modules/watchRTC/interfaces.js.map +1 -0
- package/dist/esm/modules/webaudio/AudioMixer.js +74 -0
- package/dist/esm/modules/webaudio/AudioMixer.js.map +1 -0
- package/dist/esm/modules/webaudio/WebAudioUtils.js +13 -0
- package/dist/esm/modules/webaudio/WebAudioUtils.js.map +1 -0
- package/dist/esm/modules/xmpp/AVModeration.js +156 -0
- package/dist/esm/modules/xmpp/AVModeration.js.map +1 -0
- package/dist/esm/modules/xmpp/BreakoutRooms.js +230 -0
- package/dist/esm/modules/xmpp/BreakoutRooms.js.map +1 -0
- package/dist/esm/modules/xmpp/Caps.js +223 -0
- package/dist/esm/modules/xmpp/Caps.js.map +1 -0
- package/dist/esm/modules/xmpp/ChatRoom.js +1877 -0
- package/dist/esm/modules/xmpp/ChatRoom.js.map +1 -0
- package/dist/esm/modules/xmpp/ConnectionPlugin.js +37 -0
- package/dist/esm/modules/xmpp/ConnectionPlugin.js.map +1 -0
- package/dist/esm/modules/xmpp/FileSharing.js +95 -0
- package/dist/esm/modules/xmpp/FileSharing.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleHelperFunctions.js +168 -0
- package/dist/esm/modules/xmpp/JingleHelperFunctions.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSession.js +166 -0
- package/dist/esm/modules/xmpp/JingleSession.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSessionPC.js +1969 -0
- package/dist/esm/modules/xmpp/JingleSessionPC.js.map +1 -0
- package/dist/esm/modules/xmpp/JingleSessionState.js +23 -0
- package/dist/esm/modules/xmpp/JingleSessionState.js.map +1 -0
- package/dist/esm/modules/xmpp/Lobby.js +384 -0
- package/dist/esm/modules/xmpp/Lobby.js.map +1 -0
- package/dist/esm/modules/xmpp/MediaSessionEvents.js +12 -0
- package/dist/esm/modules/xmpp/MediaSessionEvents.js.map +1 -0
- package/dist/esm/modules/xmpp/MockClasses.js +77 -0
- package/dist/esm/modules/xmpp/MockClasses.js.map +1 -0
- package/dist/esm/modules/xmpp/Polls.js +87 -0
- package/dist/esm/modules/xmpp/Polls.js.map +1 -0
- package/dist/esm/modules/xmpp/ResumeTask.js +149 -0
- package/dist/esm/modules/xmpp/ResumeTask.js.map +1 -0
- package/dist/esm/modules/xmpp/RoomMetadata.js +96 -0
- package/dist/esm/modules/xmpp/RoomMetadata.js.map +1 -0
- package/dist/esm/modules/xmpp/SignalingLayerImpl.js +313 -0
- package/dist/esm/modules/xmpp/SignalingLayerImpl.js.map +1 -0
- package/dist/esm/modules/xmpp/StropheErrorHandler.js +53 -0
- package/dist/esm/modules/xmpp/StropheErrorHandler.js.map +1 -0
- package/dist/esm/modules/xmpp/StropheLastSuccess.js +52 -0
- package/dist/esm/modules/xmpp/StropheLastSuccess.js.map +1 -0
- package/dist/esm/modules/xmpp/XmppConnection.js +579 -0
- package/dist/esm/modules/xmpp/XmppConnection.js.map +1 -0
- package/dist/esm/modules/xmpp/moderator.js +524 -0
- package/dist/esm/modules/xmpp/moderator.js.map +1 -0
- package/dist/esm/modules/xmpp/sha1.js +165 -0
- package/dist/esm/modules/xmpp/sha1.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.disco.js +222 -0
- package/dist/esm/modules/xmpp/strophe.disco.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.emuc.js +206 -0
- package/dist/esm/modules/xmpp/strophe.emuc.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.jingle.js +404 -0
- package/dist/esm/modules/xmpp/strophe.jingle.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.logger.js +44 -0
- package/dist/esm/modules/xmpp/strophe.logger.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.ping.js +170 -0
- package/dist/esm/modules/xmpp/strophe.ping.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.rayo.js +117 -0
- package/dist/esm/modules/xmpp/strophe.rayo.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.stream-management.js +365 -0
- package/dist/esm/modules/xmpp/strophe.stream-management.js.map +1 -0
- package/dist/esm/modules/xmpp/strophe.util.js +116 -0
- package/dist/esm/modules/xmpp/strophe.util.js.map +1 -0
- package/dist/esm/modules/xmpp/xmpp.js +973 -0
- package/dist/esm/modules/xmpp/xmpp.js.map +1 -0
- package/dist/esm/service/RTC/BridgeVideoType.js +24 -0
- package/dist/esm/service/RTC/BridgeVideoType.js.map +1 -0
- package/dist/esm/service/RTC/CameraFacingMode.js +21 -0
- package/dist/esm/service/RTC/CameraFacingMode.js.map +1 -0
- package/dist/esm/service/RTC/CodecMimeType.js +36 -0
- package/dist/esm/service/RTC/CodecMimeType.js.map +1 -0
- package/dist/esm/service/RTC/MediaDirection.js +23 -0
- package/dist/esm/service/RTC/MediaDirection.js.map +1 -0
- package/dist/esm/service/RTC/MediaType.js +20 -0
- package/dist/esm/service/RTC/MediaType.js.map +1 -0
- package/dist/esm/service/RTC/RTCEvents.js +111 -0
- package/dist/esm/service/RTC/RTCEvents.js.map +1 -0
- package/dist/esm/service/RTC/ReceiverAudioSubscription.js +27 -0
- package/dist/esm/service/RTC/ReceiverAudioSubscription.js.map +1 -0
- package/dist/esm/service/RTC/Resolutions.js +56 -0
- package/dist/esm/service/RTC/Resolutions.js.map +1 -0
- package/dist/esm/service/RTC/SignalingEvents.js +42 -0
- package/dist/esm/service/RTC/SignalingEvents.js.map +1 -0
- package/dist/esm/service/RTC/SignalingLayer.js +153 -0
- package/dist/esm/service/RTC/SignalingLayer.js.map +1 -0
- package/dist/esm/service/RTC/StandardVideoQualitySettings.js +180 -0
- package/dist/esm/service/RTC/StandardVideoQualitySettings.js.map +1 -0
- package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js +36 -0
- package/dist/esm/service/RTC/VideoEncoderScalabilityMode.js.map +1 -0
- package/dist/esm/service/RTC/VideoType.js +19 -0
- package/dist/esm/service/RTC/VideoType.js.map +1 -0
- package/dist/esm/service/authentication/AuthenticationEvents.js +13 -0
- package/dist/esm/service/authentication/AuthenticationEvents.js.map +1 -0
- package/dist/esm/service/connectivity/ConnectionQualityEvents.js +13 -0
- package/dist/esm/service/connectivity/ConnectionQualityEvents.js.map +1 -0
- package/dist/esm/service/connectivity/Constants.js +3 -0
- package/dist/esm/service/connectivity/Constants.js.map +1 -0
- package/dist/esm/service/e2eping/E2ePingEvents.js +8 -0
- package/dist/esm/service/e2eping/E2ePingEvents.js.map +1 -0
- package/dist/esm/service/statistics/AnalyticsEvents.js +521 -0
- package/dist/esm/service/statistics/AnalyticsEvents.js.map +1 -0
- package/dist/esm/service/statistics/Events.js +36 -0
- package/dist/esm/service/statistics/Events.js.map +1 -0
- package/dist/esm/service/statistics/constants.js +2 -0
- package/dist/esm/service/statistics/constants.js.map +1 -0
- package/dist/esm/service/xmpp/XMPPEvents.js +359 -0
- package/dist/esm/service/xmpp/XMPPEvents.js.map +1 -0
- package/dist/esm/service/xmpp/XMPPExtensioProtocols.js +64 -0
- package/dist/esm/service/xmpp/XMPPExtensioProtocols.js.map +1 -0
- package/dist/esm/test-setup-polyfill.js +34 -0
- package/dist/esm/test-setup-polyfill.js.map +1 -0
- package/dist/esm/tools/gen-version.js +15 -0
- package/dist/esm/tools/gen-version.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/umd/lib-jitsi-meet.e2ee-worker.js +484 -0
- package/dist/umd/lib-jitsi-meet.min.js +3 -0
- package/dist/umd/lib-jitsi-meet.min.js.LICENSE.txt +18 -0
- package/dist/umd/lib-jitsi-meet.min.map +1 -0
- package/package.json +93 -0
- 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
|