Builtin Prosody: adding the prosody-room-type settings to allow rooms to be per channel or per video. WIP.

This commit is contained in:
John Livingston
2021-08-05 15:41:49 +02:00
parent 5237c20332
commit 5c0b274f39
9 changed files with 203 additions and 70 deletions

View File

@ -4,10 +4,11 @@ import { asyncMiddleware } from '../middlewares/async'
import { getCheckAPIKeyMiddleware } from '../middlewares/apikey'
import { prosodyCheckUserPassword, prosodyRegisterUser, prosodyUserRegistered } from '../prosody/auth'
import { getUserNickname } from '../helpers'
import { Affiliations, getVideoAffiliations } from '../prosody/config/affiliations'
import { Affiliations, getVideoAffiliations, getChannelAffiliations } from '../prosody/config/affiliations'
import { getProsodyDomain } from '../prosody/config/domain'
import type { ChatType } from '../../../shared/lib/types'
import { fillVideoCustomFields } from '../custom-fields'
import { getChannelInfosById } from '../database/channel'
// See here for description: https://modules.prosody.im/mod_muc_http_defaults.html
interface RoomDefaults {
@ -48,61 +49,106 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
const jid: string = req.query.jid as string || ''
logger.info(`Requesting room information for room '${jid}'.`)
const video = await peertubeHelpers.videos.loadByIdOrUUID(jid)
if (!video) {
logger.warn(`Video ${jid} not found`)
res.sendStatus(403)
return
}
// Adding the custom fields:
await fillVideoCustomFields(options, video)
// check settings (chat enabled for this video?)
const settings = await options.settingsManager.getSettings([
'chat-type',
'chat-only-locals',
'chat-per-live-video',
'chat-all-lives',
'chat-all-non-lives',
'chat-videos-list'
'prosody-room-type'
])
if (settings['chat-type'] !== ('builtin-prosody' as ChatType)) {
logger.warn('Prosody chat is not active')
res.sendStatus(403)
return
}
if (!videoHasWebchat({
'chat-only-locals': !!settings['chat-only-locals'],
'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)) {
logger.warn(`Video ${jid} has not chat activated`)
res.sendStatus(403)
return
}
// Now, we have two different room type: per video or per channel.
if (settings['prosody-room-type'] === 'channel') {
const matches = jid.match(/^channel\.(\d+)$/)
if (!matches || !matches[1]) {
logger.warn(`Invalid channel room jid '${jid}'.`)
res.sendStatus(403)
return
}
const channelId = parseInt(matches[1])
const channelInfos = await getChannelInfosById(options, channelId)
if (!channelInfos) {
logger.warn(`Channel ${channelId} not found`)
res.sendStatus(403)
return
}
let affiliations: Affiliations
try {
affiliations = await getVideoAffiliations(options, video)
} catch (error) {
logger.error(`Failed to get video affiliations for ${video.uuid}:`, error)
// affiliations: should at least be {}, so that the first user will not be moderator/admin
affiliations = {}
}
let affiliations: Affiliations
try {
affiliations = await getChannelAffiliations(options, channelId)
} catch (error) {
logger.error(`Failed to get channel affiliations for ${channelId}:`, error)
// affiliations: should at least be {}, so that the first user will not be moderator/admin
affiliations = {}
}
const roomDefaults: RoomDefaults = {
config: {
name: video.name,
description: '',
language: video.language,
subject: video.name
},
affiliations: affiliations
const roomDefaults: RoomDefaults = {
config: {
name: channelInfos.displayName,
description: '',
subject: channelInfos.displayName
},
affiliations: affiliations
}
res.json(roomDefaults)
} else {
const video = await peertubeHelpers.videos.loadByIdOrUUID(jid)
if (!video) {
logger.warn(`Video ${jid} not found`)
res.sendStatus(403)
return
}
// Adding the custom fields:
await fillVideoCustomFields(options, video)
// check settings (chat enabled for this video?)
const settings = await options.settingsManager.getSettings([
'chat-type',
'chat-only-locals',
'chat-per-live-video',
'chat-all-lives',
'chat-all-non-lives',
'chat-videos-list'
])
if (settings['chat-type'] !== ('builtin-prosody' as ChatType)) {
logger.warn('Prosody chat is not active')
res.sendStatus(403)
return
}
if (!videoHasWebchat({
'chat-only-locals': !!settings['chat-only-locals'],
'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)) {
logger.warn(`Video ${jid} has not chat activated`)
res.sendStatus(403)
return
}
let affiliations: Affiliations
try {
affiliations = await getVideoAffiliations(options, video)
} catch (error) {
logger.error(`Failed to get video affiliations for ${video.uuid}:`, error)
// affiliations: should at least be {}, so that the first user will not be moderator/admin
affiliations = {}
}
const roomDefaults: RoomDefaults = {
config: {
name: video.name,
description: '',
language: video.language,
subject: video.name
},
affiliations: affiliations
}
res.json(roomDefaults)
}
res.json(roomDefaults)
}
]))

View File

@ -37,11 +37,12 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
const settings = await settingsManager.getSettings([
'chat-type', 'chat-room', 'chat-server',
'chat-bosh-uri', 'chat-ws-uri'
'chat-bosh-uri', 'chat-ws-uri',
'prosody-room-type'
])
const chatType: ChatType = (settings['chat-type'] ?? 'disabled') as ChatType
let server: string
let jid: string
let room: string
let boshUri: string
let wsUri: string
@ -49,8 +50,12 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
let advancedControls: boolean = false
if (chatType === 'builtin-prosody') {
const prosodyDomain = await getProsodyDomain(options)
server = 'anon.' + prosodyDomain
room = '{{VIDEO_UUID}}@room.' + prosodyDomain
jid = 'anon.' + prosodyDomain
if (settings['prosody-room-type'] === 'channel') {
room = 'channel.{{CHANNEL_ID}}@room.' + prosodyDomain
} else {
room = '{{VIDEO_UUID}}@room.' + prosodyDomain
}
boshUri = getBaseRouterRoute(options) + 'webchat/http-bind'
wsUri = ''
authenticationUrl = options.peertubeHelpers.config.getWebserverUrl() +
@ -67,7 +72,7 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
if (!settings['chat-bosh-uri'] && !settings['chat-ws-uri']) {
throw new Error('Missing BOSH or Websocket uri.')
}
server = settings['chat-server'] as string
jid = settings['chat-server'] as string
room = settings['chat-room'] as string
boshUri = settings['chat-bosh-uri'] as string
wsUri = settings['chat-ws-uri'] as string
@ -84,7 +89,7 @@ async function initWebchatRouter (options: RegisterServerOptions): Promise<Route
let page = '' + (converseJSIndex as string)
const baseStaticUrl = getBaseStaticRoute(options)
page = page.replace(/{{BASE_STATIC_URL}}/g, baseStaticUrl)
page = page.replace(/{{JID}}/g, server)
page = page.replace(/{{JID}}/g, jid)
// Computing the room name...
room = room.replace(/{{VIDEO_UUID}}/g, video.uuid)
room = room.replace(/{{CHANNEL_ID}}/g, `${video.channelId}`)