6ed69d2c2f
The data format used by plugin v6.3.0 was not well suited. Here comes a new data format, with S2S informations. The plugin can automatically upgrade old format. It also continues to provide the old format, so than remote instance that did not update the plugin will still work.
202 lines
6.3 KiB
TypeScript
202 lines
6.3 KiB
TypeScript
import type { RegisterServerOptions, VideoObject, SettingValue } from '@peertube/peertube-types'
|
|
import type {
|
|
LiveChatVideoObject,
|
|
VideoBuildResultContext,
|
|
LiveChatJSONLDLink,
|
|
LiveChatJSONLDAttribute,
|
|
PeertubeXMPPServerInfos
|
|
} from './types'
|
|
import { storeVideoLiveChatInfos } from './storage'
|
|
import { videoHasWebchat } from '../../../shared/lib/video'
|
|
import { getBoshUri, getWSUri, getWSS2SUri } from '../uri/webchat'
|
|
import { canonicalizePluginUri } from '../uri/canonicalize'
|
|
import { getProsodyDomain } from '../prosody/config/domain'
|
|
import { fillVideoCustomFields } from '../custom-fields'
|
|
|
|
/**
|
|
* This function adds LiveChat information on video ActivityPub data if relevant.
|
|
* @param options server options
|
|
* @param jsonld JSON-LD video data to fill
|
|
* @param context handler context
|
|
* @returns void
|
|
*/
|
|
async function videoBuildJSONLD (
|
|
options: RegisterServerOptions,
|
|
jsonld: VideoObject,
|
|
context: VideoBuildResultContext
|
|
): Promise<VideoObject | LiveChatVideoObject> {
|
|
const logger = options.peertubeHelpers.logger
|
|
const video = context.video
|
|
if (video.remote) { return jsonld } // should not happen, but... just in case...
|
|
|
|
const settings = await options.settingsManager.getSettings([
|
|
'chat-per-live-video',
|
|
'chat-all-lives',
|
|
'chat-all-non-lives',
|
|
'chat-videos-list',
|
|
'disable-websocket',
|
|
'prosody-room-type',
|
|
'federation-dont-publish-remotely',
|
|
'chat-no-anonymous',
|
|
'prosody-room-allow-s2s',
|
|
'prosody-s2s-port'
|
|
])
|
|
|
|
if (settings['federation-dont-publish-remotely']) {
|
|
// Note: we store also outgoing data. Could help for migration/cleanup scripts, for example.
|
|
await storeVideoLiveChatInfos(options, video, false)
|
|
return jsonld
|
|
}
|
|
|
|
await fillVideoCustomFields(options, video)
|
|
const hasChat = await videoHasWebchat({
|
|
'chat-per-live-video': !!settings['chat-per-live-video'],
|
|
'chat-all-lives': !!settings['chat-all-lives'],
|
|
'chat-all-non-lives': !!settings['chat-all-non-lives'],
|
|
'chat-videos-list': settings['chat-videos-list'] as string
|
|
}, video)
|
|
|
|
if (!hasChat) {
|
|
logger.debug(`Video uuid=${video.uuid} has not livechat, adding peertubeLiveChat=false.`)
|
|
// Note: we store also outgoing data. Could help for migration/cleanup scripts, for example.
|
|
await storeVideoLiveChatInfos(options, video, false)
|
|
Object.assign(jsonld, {
|
|
peertubeLiveChat: false
|
|
})
|
|
return jsonld
|
|
}
|
|
|
|
logger.debug(`Adding LiveChat data on video uuid=${video.uuid}...`)
|
|
|
|
const prosodyDomain = await getProsodyDomain(options)
|
|
let roomJID: string
|
|
if (settings['prosody-room-type'] === 'channel') {
|
|
roomJID = `channel.${video.channelId}@room.${prosodyDomain}`
|
|
} else {
|
|
roomJID = `${video.uuid}@room.${prosodyDomain}`
|
|
}
|
|
|
|
const serverInfos = await _serverBuildInfos(options, {
|
|
'federation-dont-publish-remotely': settings['federation-dont-publish-remotely'],
|
|
'prosody-s2s-port': settings['prosody-s2s-port'],
|
|
'prosody-room-allow-s2s': settings['prosody-room-allow-s2s'],
|
|
'disable-websocket': settings['disable-websocket'],
|
|
'chat-no-anonymous': settings['chat-no-anonymous']
|
|
})
|
|
|
|
// For backward compatibility with remote servers, using plugin <=6.3.0, we must provide links:
|
|
const links: LiveChatJSONLDLink[] = []
|
|
if (serverInfos.anonymous) {
|
|
if (serverInfos.anonymous.bosh) {
|
|
links.push({
|
|
type: 'xmpp-bosh-anonymous',
|
|
url: serverInfos.anonymous.bosh,
|
|
jid: serverInfos.anonymous.virtualhost
|
|
})
|
|
}
|
|
if (serverInfos.anonymous.websocket) {
|
|
links.push({
|
|
type: 'xmpp-websocket-anonymous',
|
|
url: serverInfos.anonymous.websocket,
|
|
jid: serverInfos.anonymous.virtualhost
|
|
})
|
|
}
|
|
}
|
|
|
|
const peertubeLiveChat: LiveChatJSONLDAttribute = {
|
|
type: 'xmpp',
|
|
jid: roomJID,
|
|
links,
|
|
xmppserver: serverInfos
|
|
}
|
|
Object.assign(jsonld, {
|
|
peertubeLiveChat
|
|
})
|
|
// Note: we store also outgoing data. Could help for migration/cleanup scripts, for example.
|
|
await storeVideoLiveChatInfos(options, video, peertubeLiveChat)
|
|
return jsonld
|
|
}
|
|
|
|
async function serverBuildInfos (options: RegisterServerOptions): Promise<PeertubeXMPPServerInfos> {
|
|
const settings = await options.settingsManager.getSettings([
|
|
'federation-dont-publish-remotely',
|
|
'prosody-s2s-port',
|
|
'prosody-room-allow-s2s',
|
|
'disable-websocket',
|
|
'chat-no-anonymous'
|
|
])
|
|
return _serverBuildInfos(options, {
|
|
'federation-dont-publish-remotely': settings['federation-dont-publish-remotely'],
|
|
'prosody-s2s-port': settings['prosody-s2s-port'],
|
|
'prosody-room-allow-s2s': settings['prosody-room-allow-s2s'],
|
|
'disable-websocket': settings['disable-websocket'],
|
|
'chat-no-anonymous': settings['chat-no-anonymous']
|
|
})
|
|
}
|
|
|
|
async function _serverBuildInfos (
|
|
options: RegisterServerOptions,
|
|
settings: {
|
|
'federation-dont-publish-remotely': SettingValue
|
|
'prosody-s2s-port': SettingValue
|
|
'prosody-room-allow-s2s': SettingValue
|
|
'disable-websocket': SettingValue
|
|
'chat-no-anonymous': SettingValue
|
|
}
|
|
): Promise<PeertubeXMPPServerInfos> {
|
|
const prosodyDomain = await getProsodyDomain(options)
|
|
const mucDomain = 'room.' + prosodyDomain
|
|
const anonDomain = 'anon.' + prosodyDomain
|
|
|
|
let directs2s
|
|
if (settings['prosody-room-allow-s2s'] && settings['prosody-s2s-port']) {
|
|
directs2s = {
|
|
port: (settings['prosody-s2s-port'] as string) ?? ''
|
|
}
|
|
}
|
|
|
|
let websockets2s
|
|
if (!settings['federation-dont-publish-remotely']) {
|
|
const wsS2SUri = getWSS2SUri(options)
|
|
if (wsS2SUri) { // can be undefined for old Peertube version that dont allow WS for plugins
|
|
websockets2s = {
|
|
url: canonicalizePluginUri(options, wsS2SUri, {
|
|
removePluginVersion: true,
|
|
protocol: 'ws'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
let anonymous: PeertubeXMPPServerInfos['anonymous'] | undefined
|
|
if (!settings['chat-no-anonymous']) {
|
|
anonymous = {
|
|
bosh: canonicalizePluginUri(options, getBoshUri(options), { removePluginVersion: true }),
|
|
virtualhost: anonDomain
|
|
}
|
|
|
|
if (!settings['disable-websocket']) {
|
|
const wsUri = getWSUri(options)
|
|
if (wsUri) {
|
|
anonymous.websocket = canonicalizePluginUri(options, wsUri, {
|
|
removePluginVersion: true,
|
|
protocol: 'ws'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
host: prosodyDomain,
|
|
muc: mucDomain,
|
|
directs2s,
|
|
websockets2s,
|
|
anonymous
|
|
}
|
|
}
|
|
|
|
export {
|
|
videoBuildJSONLD,
|
|
serverBuildInfos
|
|
}
|