Bots settings (WIP).
This commit is contained in:
parent
7bb444af2c
commit
62456aead1
@ -211,6 +211,7 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re
|
||||
case 'prosody-muc-log-by-default':
|
||||
case 'prosody-muc-expiration':
|
||||
case 'prosody-c2s':
|
||||
case 'prosody-component-port':
|
||||
return options.formValues['chat-type'] !== ('builtin-prosody' as ChatType)
|
||||
case 'prosody-c2s-port':
|
||||
return !(
|
||||
|
@ -3,15 +3,28 @@ For internal API, we will generate an api Key that must be provided as
|
||||
GET parameter for every API call.
|
||||
*/
|
||||
|
||||
async function getAPIKey ({ storageManager }: RegisterServerOptions): Promise<string> {
|
||||
let value: string = await storageManager.getData('APIKEY')
|
||||
async function _getKey ({ storageManager }: RegisterServerOptions, key: string): Promise<string> {
|
||||
let value: string = await storageManager.getData(key)
|
||||
if (!value) {
|
||||
value = Math.random().toString(36).slice(2, 12)
|
||||
await storageManager.storeData('APIKEY', value)
|
||||
await storageManager.storeData(key, value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export {
|
||||
getAPIKey
|
||||
async function getAPIKey (options: RegisterServerOptions): Promise<string> {
|
||||
return _getKey(options, 'APIKEY')
|
||||
}
|
||||
|
||||
async function getExternalComponentKey (options: RegisterServerOptions, componentName: string): Promise<string> {
|
||||
if (!/^[A-Z]+$/.test(componentName)) {
|
||||
throw new Error('Invalid component name: ' + componentName)
|
||||
}
|
||||
const key = 'EXTERNALCOMPONENTKEY_' + componentName
|
||||
return _getKey(options, key)
|
||||
}
|
||||
|
||||
export {
|
||||
getAPIKey,
|
||||
getExternalComponentKey
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
|
||||
}
|
||||
result.messages.push(`Room content will be saved for '${wantedConfig.logExpiration.value}'`)
|
||||
|
||||
if (wantedConfig.bots.demo) {
|
||||
result.messages.push(`The Demo bot is active for videos: ${wantedConfig.bots.demo.join(', ')}`)
|
||||
}
|
||||
|
||||
await fs.promises.access(filePath, fs.constants.R_OK) // throw an error if file does not exist.
|
||||
result.messages.push(`The prosody configuration file (${filePath}) exists`)
|
||||
const actualContent = await fs.promises.readFile(filePath, {
|
||||
|
@ -4,8 +4,9 @@ import { getBaseRouterRoute } from '../helpers'
|
||||
import { ProsodyFilePaths } from './config/paths'
|
||||
import { ConfigLogExpiration, ProsodyConfigContent } from './config/content'
|
||||
import { getProsodyDomain } from './config/domain'
|
||||
import { getAPIKey } from '../apikey'
|
||||
import { getAPIKey, getExternalComponentKey } from '../apikey'
|
||||
import type { ProsodyLogLevel } from './config/content'
|
||||
import { parseConfigDemoBotUUIDs } from './config/bots'
|
||||
|
||||
async function getWorkingDir (options: RegisterServerOptions): Promise<string> {
|
||||
const peertubeHelpers = options.peertubeHelpers
|
||||
@ -63,6 +64,9 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
|
||||
}
|
||||
}
|
||||
|
||||
interface ProsodyConfigBots {
|
||||
demo?: string[] // if the demo bot is activated, here are the video UUIDS where it will be.
|
||||
}
|
||||
interface ProsodyConfig {
|
||||
content: string
|
||||
paths: ProsodyFilePaths
|
||||
@ -72,25 +76,40 @@ interface ProsodyConfig {
|
||||
roomType: 'video' | 'channel'
|
||||
logByDefault: boolean
|
||||
logExpiration: ConfigLogExpiration
|
||||
bots: ProsodyConfigBots
|
||||
}
|
||||
async function getProsodyConfig (options: RegisterServerOptions): Promise<ProsodyConfig> {
|
||||
const logger = options.peertubeHelpers.logger
|
||||
logger.debug('Calling getProsodyConfig')
|
||||
|
||||
const port = (await options.settingsManager.getSetting('prosody-port') as string) || '52800'
|
||||
let useExternalComponents = false
|
||||
const bots: ProsodyConfigBots = {}
|
||||
|
||||
const settings = await options.settingsManager.getSettings([
|
||||
'prosody-port',
|
||||
'prosody-muc-log-by-default',
|
||||
'prosody-muc-expiration',
|
||||
'prosody-c2s',
|
||||
'prosody-room-type',
|
||||
'prosody-peertube-uri',
|
||||
'prosody-c2s-port',
|
||||
'prosody-component-port',
|
||||
'chat-videos-list'
|
||||
])
|
||||
|
||||
const port = (settings['prosody-port'] as string) || '52800'
|
||||
if (!/^\d+$/.test(port)) {
|
||||
throw new Error('Invalid port')
|
||||
}
|
||||
const logByDefault = (await options.settingsManager.getSetting('prosody-muc-log-by-default') as boolean) ?? true
|
||||
const logExpirationSetting =
|
||||
(await options.settingsManager.getSetting('prosody-muc-expiration') as string) ?? DEFAULTLOGEXPIRATION
|
||||
const enableC2s = (await options.settingsManager.getSetting('prosody-c2s') as boolean) || false
|
||||
const logByDefault = (settings['prosody-muc-log-by-default'] as boolean) ?? true
|
||||
const logExpirationSetting = (settings['prosody-muc-expiration'] as string) ?? DEFAULTLOGEXPIRATION
|
||||
const enableC2s = (settings['prosody-c2s'] as boolean) || false
|
||||
const prosodyDomain = await getProsodyDomain(options)
|
||||
const paths = await getProsodyFilePaths(options)
|
||||
const roomType = (await options.settingsManager.getSetting('prosody-room-type')) === 'channel' ? 'channel' : 'video'
|
||||
const roomType = (settings['prosody-room-type']) === 'channel' ? 'channel' : 'video'
|
||||
|
||||
const apikey = await getAPIKey(options)
|
||||
let baseApiUrl = await options.settingsManager.getSetting('prosody-peertube-uri') as string
|
||||
let baseApiUrl = settings['prosody-peertube-uri'] as string
|
||||
if (baseApiUrl && !/^https?:\/\/[a-z0-9.-_]+(?::\d+)?$/.test(baseApiUrl)) {
|
||||
throw new Error('Invalid prosody-peertube-uri')
|
||||
}
|
||||
@ -109,7 +128,7 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
config.useMucHttpDefault(roomApiUrl)
|
||||
|
||||
if (enableC2s) {
|
||||
const c2sPort = (await options.settingsManager.getSetting('prosody-c2s-port') as string) || '52822'
|
||||
const c2sPort = (settings['prosody-c2s-port'] as string) || '52822'
|
||||
if (!/^\d+$/.test(c2sPort)) {
|
||||
throw new Error('Invalid c2s port')
|
||||
}
|
||||
@ -139,6 +158,22 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
logLevel = 'info'
|
||||
}
|
||||
config.setLog(logLevel)
|
||||
|
||||
const demoBotUUIDs = parseConfigDemoBotUUIDs((settings['chat-videos-list'] as string) || '')
|
||||
if (demoBotUUIDs?.length > 0) {
|
||||
useExternalComponents = true
|
||||
config.useDemoBot(await getExternalComponentKey(options, 'DEMOBOT'))
|
||||
bots.demo = demoBotUUIDs
|
||||
}
|
||||
|
||||
if (useExternalComponents) {
|
||||
const externalComponentsPort = (settings['prosody-component-port'] as string) || '53470'
|
||||
if (!/^\d+$/.test(externalComponentsPort)) {
|
||||
throw new Error('Invalid external components port')
|
||||
}
|
||||
config.useExternalComponents(externalComponentsPort)
|
||||
}
|
||||
|
||||
const content = config.write()
|
||||
|
||||
return {
|
||||
@ -149,7 +184,8 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
|
||||
host: prosodyDomain,
|
||||
roomType,
|
||||
logByDefault,
|
||||
logExpiration
|
||||
logExpiration,
|
||||
bots
|
||||
}
|
||||
}
|
||||
|
||||
|
19
server/lib/prosody/config/bots.ts
Normal file
19
server/lib/prosody/config/bots.ts
Normal file
@ -0,0 +1,19 @@
|
||||
function parseConfigDemoBotUUIDs (s: string): string[] {
|
||||
if (!s) {
|
||||
return []
|
||||
}
|
||||
let a = s.split('\n')
|
||||
// find lines that are like:
|
||||
// 6432f147-83c7-4fa3-b3b5-e49c2590e825 #!demobot
|
||||
a = a.filter(line => /#!demobot\b/.test(line))
|
||||
a = a.map(line => {
|
||||
return line.replace(/#.*$/, '')
|
||||
.replace(/^\s+/, '')
|
||||
.replace(/\s+$/, '')
|
||||
})
|
||||
return a.filter(line => line !== '')
|
||||
}
|
||||
|
||||
export {
|
||||
parseConfigDemoBotUUIDs
|
||||
}
|
@ -102,16 +102,19 @@ class ProsodyConfigVirtualHost extends ProsodyConfigBlock {
|
||||
|
||||
class ProsodyConfigComponent extends ProsodyConfigBlock {
|
||||
name: string
|
||||
type: string
|
||||
type?: string
|
||||
|
||||
constructor (type: string, name: string) {
|
||||
constructor (name: string, type?: string) {
|
||||
super(' ')
|
||||
this.type = type
|
||||
this.name = name
|
||||
}
|
||||
|
||||
write (): string {
|
||||
return `Component "${this.name}" "${this.type}"\n` + super.write()
|
||||
if (this.type !== undefined) {
|
||||
return `Component "${this.name}" "${this.type}"\n` + super.write()
|
||||
}
|
||||
return `Component "${this.name}"\n` + super.write()
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,6 +126,7 @@ class ProsodyConfigContent {
|
||||
authenticated?: ProsodyConfigVirtualHost
|
||||
anon: ProsodyConfigVirtualHost
|
||||
muc: ProsodyConfigComponent
|
||||
externalComponents: ProsodyConfigComponent[] = []
|
||||
log: string
|
||||
prosodyDomain: string
|
||||
|
||||
@ -132,7 +136,7 @@ class ProsodyConfigContent {
|
||||
this.log = ''
|
||||
this.prosodyDomain = prosodyDomain
|
||||
this.anon = new ProsodyConfigVirtualHost('anon.' + prosodyDomain)
|
||||
this.muc = new ProsodyConfigComponent('muc', 'room.' + prosodyDomain)
|
||||
this.muc = new ProsodyConfigComponent('room.' + prosodyDomain, 'muc')
|
||||
|
||||
this.global.set('daemonize', false)
|
||||
this.global.set('allow_registration', false)
|
||||
@ -281,6 +285,21 @@ class ProsodyConfigContent {
|
||||
this.muc.set('peertubelivechat_test_peertube_api_url', apiurl)
|
||||
}
|
||||
|
||||
useExternalComponents (componentsPort: string): void {
|
||||
this.global.set('component_ports', [componentsPort])
|
||||
this.global.set('component_interfaces', ['127.0.0.1', '::1'])
|
||||
}
|
||||
|
||||
useDemoBot (componentSecret: string): void {
|
||||
const demoBot = new ProsodyConfigComponent('demobot.' + this.prosodyDomain)
|
||||
demoBot.set('component_secret', componentSecret)
|
||||
|
||||
// If we want the bot to be moderator, should do the trick:
|
||||
// this.global.add('admins', 'demobot.' + this.prosodyDomain)
|
||||
|
||||
this.externalComponents.push(demoBot)
|
||||
}
|
||||
|
||||
setLog (level: ProsodyLogLevel, syslog?: ProsodyLogLevel[]): void {
|
||||
let log = ''
|
||||
log += 'log = {\n'
|
||||
@ -309,6 +328,11 @@ class ProsodyConfigContent {
|
||||
content += '\n\n'
|
||||
content += this.muc.write()
|
||||
content += '\n\n'
|
||||
this.externalComponents.forEach((externalComponent) => {
|
||||
content += '\n\n'
|
||||
content += externalComponent.write()
|
||||
content += '\n\n'
|
||||
})
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
@ -359,6 +359,22 @@ archiving for a specific room, by editing its properties.
|
||||
</ul>`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-component-port',
|
||||
label: 'The port to be use for external components',
|
||||
type: 'input',
|
||||
default: '53470',
|
||||
private: true,
|
||||
descriptionHTML:
|
||||
`The port that will be used for extra components used by the builtin Prosody server.<br>
|
||||
This is only used when one of these special features is used:<br>
|
||||
<ul>
|
||||
<li>Demo bot: this is a hidden feature, for demonstration purposes. See the documentation for more information.</li>
|
||||
</ul><br>
|
||||
Change it if this port is already in use on your server.
|
||||
`
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'prosody-c2s',
|
||||
label: 'Enable client to server connections',
|
||||
|
Loading…
x
Reference in New Issue
Block a user