From 2ec7f2290c07e5152c5d1da7f8326813143773c3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Apr 2020 16:04:41 -0600 Subject: [PATCH] Support Jitsi information from client .well-known It can be useful for the homeserver to support a dedicated Jitsi instance instead of requiring that all their users change/update their configs manually. --- src/CallHandler.js | 3 +- src/Lifecycle.js | 4 +++ src/widgets/Jitsi.ts | 73 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/widgets/Jitsi.ts diff --git a/src/CallHandler.js b/src/CallHandler.js index 8284e788b4..fdd0d5ae45 100644 --- a/src/CallHandler.js +++ b/src/CallHandler.js @@ -66,6 +66,7 @@ import WidgetUtils from './utils/WidgetUtils'; import WidgetEchoStore from './stores/WidgetEchoStore'; import SettingsStore, { SettingLevel } from './settings/SettingsStore'; import {generateHumanReadableId} from "./utils/NamingUtils"; +import {Jitsi} from "./widgets/Jitsi"; global.mxCalls = { //room_id: MatrixCall @@ -431,7 +432,7 @@ async function _startCallApp(roomId, type) { } const confId = `JitsiConference${generateHumanReadableId()}`; - const jitsiDomain = SdkConfig.get()['jitsi']['preferredDomain']; + const jitsiDomain = Jitsi.getInstance().preferredDomain; let widgetUrl = WidgetUtils.getLocalJitsiWrapperUrl(); diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 305a73fbad..b3d777240b 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -40,6 +40,7 @@ import ToastStore from "./stores/ToastStore"; import {IntegrationManagers} from "./integrations/IntegrationManagers"; import {Mjolnir} from "./mjolnir/Mjolnir"; import DeviceListener from "./DeviceListener"; +import {Jitsi} from "./widgets/Jitsi"; /** * Called at startup, to attempt to build a logged-in Matrix session. It tries @@ -604,6 +605,9 @@ async function startMatrixClient(startSyncing=true) { // This needs to be started after crypto is set up DeviceListener.sharedInstance().start(); + // Now that we have a MatrixClientPeg, update the Jitsi info + await Jitsi.getInstance().update(); + // dispatch that we finished starting up to wire up any other bits // of the matrix client that cannot be set prior to starting up. dis.dispatch({action: 'client_started'}); diff --git a/src/widgets/Jitsi.ts b/src/widgets/Jitsi.ts new file mode 100644 index 0000000000..988131e045 --- /dev/null +++ b/src/widgets/Jitsi.ts @@ -0,0 +1,73 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import SdkConfig from "../SdkConfig"; +import {MatrixClientPeg} from "../MatrixClientPeg"; +import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery"; + +const JITSI_WK_PROPERTY = "im.vector.riot.jitsi"; +const JITSI_WK_CHECK_INTERVAL = 2 * 60 * 60 * 1000; // 2 hours, arbitrarily selected + +export class Jitsi { + private static instance: Jitsi; + + private domain: string; + + public get preferredDomain(): string { + return this.domain || 'jitsi.riot.im'; + } + + constructor() { + // We rely on the first call to be an .update() instead of doing one here. Doing one + // here could result in duplicate calls to the homeserver. + + // Start a timer to update the server info regularly + setInterval(() => this.update(), JITSI_WK_CHECK_INTERVAL); + } + + public async update(): Promise { + // Start with a default of the config's domain + let domain = (SdkConfig.get()['jitsi'] || {})['preferredDomain'] || 'jitsi.riot.im'; + + // Now request the .well-known config to see if it changed + if (MatrixClientPeg.get()) { + try { + console.log("Attempting to get Jitsi conference information from homeserver"); + + const homeserverDomain = MatrixClientPeg.getHomeserverName(); + const discoveryResponse = await AutoDiscovery.getRawClientConfig(homeserverDomain); + if (discoveryResponse && discoveryResponse[JITSI_WK_PROPERTY]) { + const wkPreferredDomain = discoveryResponse[JITSI_WK_PROPERTY]['preferredDomain']; + if (wkPreferredDomain) domain = wkPreferredDomain; + } + } catch (e) { + // These are non-fatal errors + console.error(e); + } + } + + // Put the result into memory for us to use later + this.domain = domain; + console.log("Jitsi conference domain:", this.preferredDomain); + } + + public static getInstance(): Jitsi { + if (!Jitsi.instance) { + Jitsi.instance = new Jitsi(); + } + return Jitsi.instance; + } +}