From 3efbfbc12b2d6672a139b8561eef5ce394235c91 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Thu, 18 Apr 2024 15:42:06 +0200 Subject: [PATCH] Possibility to configure an OpenID Connect provider on the instance level WIP (#128) Fix chat federation. --- CHANGELOG.md | 1 + server/lib/conversejs/params.ts | 40 +++++++++++++------ server/lib/federation/outgoing.ts | 2 + server/lib/federation/sanitize.ts | 6 +++ server/lib/federation/storage.ts | 3 +- server/lib/federation/types.ts | 1 + server/lib/prosody/config/content.ts | 1 + .../admin/advanced/xmpp_clients.md | 18 +++++++-- 8 files changed, 56 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 637b8c94..7390f254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ TODO: https://github.com/JohnXLivingston/peertube-plugin-livechat/issues/48 **Breaking changes**: * If you were adding custom CSS to livechat iframe, it could be broken, as the livechat is no more included in an iframe. Your custom styles are now added on a `div` element. +* If you enabled [XMPP Clients connections](https://livingston.frama.io/peertube-plugin-livechat/documentation/admin/advanced/xmpp_clients/), you must add a new DNS entry for `external.your_instance.example.com`. Check the documentation. ### New features diff --git a/server/lib/conversejs/params.ts b/server/lib/conversejs/params.ts index e89f15d3..9efd6f5b 100644 --- a/server/lib/conversejs/params.ts +++ b/server/lib/conversejs/params.ts @@ -79,20 +79,26 @@ async function getConverseJSParams ( let externalAuthOIDC if (userIsConnected !== true) { - try { - const oidc = ExternalAuthOIDC.singleton() - if (await oidc.isOk()) { - const authUrl = oidc.getConnectUrl() - const buttonLabel = oidc.getButtonLabel() - if (authUrl && buttonLabel) { - externalAuthOIDC = { - buttonLabel: buttonLabel, - url: authUrl + if (!remoteConnectionInfos?.externalAuthCompatible) { + options.peertubeHelpers.logger.debug( + 'The remote livechat plugin is not compatible with external authentication, not enabling the feature' + ) + } else { + try { + const oidc = ExternalAuthOIDC.singleton() + if (await oidc.isOk()) { + const authUrl = oidc.getConnectUrl() + const buttonLabel = oidc.getButtonLabel() + if (authUrl && buttonLabel) { + externalAuthOIDC = { + buttonLabel: buttonLabel, + url: authUrl + } } } + } catch (err) { + options.peertubeHelpers.logger.error(err) } - } catch (err) { - options.peertubeHelpers.logger.error(err) } } @@ -291,6 +297,7 @@ interface WCRemoteConnectionInfos { wsUri?: string } authenticated?: boolean + externalAuthCompatible: boolean } async function _remoteConnectionInfos ( @@ -301,7 +308,8 @@ async function _remoteConnectionInfos ( if (!remoteChatInfos) { throw new Error('Should have remote chat infos for remote videos') } if (remoteChatInfos.type !== 'xmpp') { throw new Error('Should have remote xmpp chat infos for remote videos') } const connectionInfos: WCRemoteConnectionInfos = { - roomJID: remoteChatInfos.jid + roomJID: remoteChatInfos.jid, + externalAuthCompatible: false } if (compatibleRemoteAuthenticatedConnectionEnabled(remoteChatInfos, canWebsocketS2S, canDirectS2S)) { connectionInfos.authenticated = true @@ -314,6 +322,14 @@ async function _remoteConnectionInfos ( wsUri: anonymousCI.wsUri } } + + if (remoteChatInfos.xmppserver.external) { + // To be able to connect to a remote livechat using an external account, + // The remote server MUST have livechat >= 9.0.0... + // So we flag the connection as compatible or not, and we will disable the feature if not compatible. + connectionInfos.externalAuthCompatible = true + } + return connectionInfos } diff --git a/server/lib/federation/outgoing.ts b/server/lib/federation/outgoing.ts index cbf14d1b..d83a877f 100644 --- a/server/lib/federation/outgoing.ts +++ b/server/lib/federation/outgoing.ts @@ -190,6 +190,7 @@ async function _serverBuildInfos ( const prosodyDomain = await getProsodyDomain(options) const mucDomain = 'room.' + prosodyDomain const anonDomain = 'anon.' + prosodyDomain + const externalDomain = 'external.' + prosodyDomain let directs2s if (settings['prosody-room-allow-s2s'] && settings['prosody-s2s-port']) { @@ -232,6 +233,7 @@ async function _serverBuildInfos ( return { host: prosodyDomain, muc: mucDomain, + external: externalDomain, // we will always add it, even if disabled. Can't cause trouble. directs2s, websockets2s, anonymous diff --git a/server/lib/federation/sanitize.ts b/server/lib/federation/sanitize.ts index 350385fe..568abb10 100644 --- a/server/lib/federation/sanitize.ts +++ b/server/lib/federation/sanitize.ts @@ -88,6 +88,12 @@ function sanitizePeertubeLiveChatServerInfos ( muc } + // This comes with livechat >= 9.0.0, can be absent. + const external = _validateHost(xmppserver.external, checkHost) + if (external) { + r.external = external + } + if (xmppserver.directs2s) { if ((typeof xmppserver.directs2s) === 'object') { const port = xmppserver.directs2s.port diff --git a/server/lib/federation/storage.ts b/server/lib/federation/storage.ts index 92f81a27..d0fce1a1 100644 --- a/server/lib/federation/storage.ts +++ b/server/lib/federation/storage.ts @@ -122,7 +122,8 @@ async function storeRemoteServerInfos ( const mainHost = xmppserver.host const hosts = [ xmppserver.host, - xmppserver.muc + xmppserver.muc, + xmppserver.external ] for (const host of hosts) { diff --git a/server/lib/federation/types.ts b/server/lib/federation/types.ts index 69458959..8a93eafc 100644 --- a/server/lib/federation/types.ts +++ b/server/lib/federation/types.ts @@ -7,6 +7,7 @@ interface VideoBuildResultContext { interface PeertubeXMPPServerInfos { host: string // main host (should be the peertube url) muc: string // muc component url + external?: string // external users virtualhost (livechat version >=9.0.0) directs2s?: { // if direct S2S is enabled port: string } diff --git a/server/lib/prosody/config/content.ts b/server/lib/prosody/config/content.ts index 2dd71342..d6b5814c 100644 --- a/server/lib/prosody/config/content.ts +++ b/server/lib/prosody/config/content.ts @@ -375,6 +375,7 @@ class ProsodyConfigContent { this.muc.add('modules_enabled', 'dialback') // This allows s2s connections without certicicates! this.authenticated?.add('modules_enabled', 'dialback') // This allows s2s connections without certicicates! + this.external?.add('modules_enabled', 'dialback') // same. } useExternalComponents ( diff --git a/support/documentation/content/en/documentation/admin/advanced/xmpp_clients.md b/support/documentation/content/en/documentation/admin/advanced/xmpp_clients.md index 18a80a5d..b087f27f 100644 --- a/support/documentation/content/en/documentation/admin/advanced/xmpp_clients.md +++ b/support/documentation/content/en/documentation/admin/advanced/xmpp_clients.md @@ -57,9 +57,9 @@ so that the outer world can connect to it. ### DNS -You need to add a [DNS record](https://prosody.im/doc/dns) allowing remote servers to find the "room.your_instance.tld" component. +You need to add [DNS records](https://prosody.im/doc/dns) allowing remote servers to find "room.your_instance.tld" and "external.your_instance.tld" components. -The easiest way to do this is to add an SRV record for the "room" [subdomain](https://prosody.im/doc/dns#subdomains): +The easiest way to do this is to add SRV records for the "room" and "external" [subdomain](https://prosody.im/doc/dns#subdomains): * record name: _xmpp-server._tcp.room.your_instance.tld. (replace «your_instance.tld» by your instance uri) * TTL: 3600 @@ -70,13 +70,25 @@ The easiest way to do this is to add an SRV record for the "room" [subdomain](ht * port: 5269 (adapt if your changed the default port) * target: your_instance.tld. (replace by your instance uri) +* record name: _xmpp-server._tcp.external.your_instance.tld. (replace «your_instance.tld» by your instance uri) +* TTL: 3600 +* class: IN +* SRV: 0 +* priority: 0 +* weight: 5 +* port: 5269 (adapt if your changed the default port) +* target: your_instance.tld. (replace by your instance uri) + Be careful to keep the dot after "your_instance.tld". -Using the `dig` command to check your record, you should get a result similar to this: +Using the `dig` command to check your records, you should get a result similar to this: ```bash $ dig +short _xmpp-server._tcp.room.videos.john-livingston.fr. SRV 0 5 5269 videos.john-livingston.fr. + +$ dig +short _xmpp-server._tcp.external.videos.john-livingston.fr. SRV +0 5 5269 videos.john-livingston.fr. ``` If you are **not using the standard `5269` port**, you must also add a SRV record for `_xmpp-server._tcp.your_instance.tld.` (same as above, just without the `room.` prefix).