From 5e988605ce8b7b1072d1f1816d952697731f6303 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Wed, 1 Dec 2021 12:57:15 +0100 Subject: [PATCH] Builtin Prosody: new settings to choose how long the room's content is archived, and if it should be archived by default. --- CHANGELOG.md | 1 + client/admin-plugin-client-plugin.ts | 2 + server/lib/diagnostic/prosody.ts | 14 ++++++ server/lib/prosody/config.ts | 66 ++++++++++++++++++++++++++-- server/lib/prosody/config/content.ts | 43 +++++++++++++++--- server/lib/settings.ts | 32 ++++++++++++++ 6 files changed, 147 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87021408..2ff41716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * UI/UX improvements. Now using a custom ConverseJS build. * Auto color detection: when using ConverseJS, the plugin tries to guess colors to apply to its theme. +* Builtin Prosody: new settings to choose how long the room's content is archived, and if it should be archived by default. ### Breaking changes diff --git a/client/admin-plugin-client-plugin.ts b/client/admin-plugin-client-plugin.ts index 343f02be..0576420c 100644 --- a/client/admin-plugin-client-plugin.ts +++ b/client/admin-plugin-client-plugin.ts @@ -208,6 +208,8 @@ function register ({ registerHook, registerSettingsScript, peertubeHelpers }: Re case 'chat-type-help-builtin-prosody': case 'prosody-list-rooms': case 'prosody-advanced': + case 'prosody-muc-log-by-default': + case 'prosody-muc-expiration': case 'prosody-c2s': return options.formValues['chat-type'] !== ('builtin-prosody' as ChatType) case 'prosody-c2s-port': diff --git a/server/lib/diagnostic/prosody.ts b/server/lib/diagnostic/prosody.ts index 5e05bbdb..6488e07f 100644 --- a/server/lib/diagnostic/prosody.ts +++ b/server/lib/diagnostic/prosody.ts @@ -36,6 +36,20 @@ export async function diagProsody (test: string, options: RegisterServerOptions) result.messages.push(`Prosody rooms will be grouped by '${wantedConfig.roomType}'.`) + if (wantedConfig.logByDefault) { + result.messages.push('By default, room content will be archived.') + } else { + result.messages.push('By default, room content will not be archived.') + } + + if ('error' in wantedConfig.logExpiration) { + result.messages.push({ + level: 'error', + message: 'Errors: Room logs expiration value is not valid. Using the default value.' + }) + } + result.messages.push(`Room content will be saved for '${wantedConfig.logExpiration.value}'`) + 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, { diff --git a/server/lib/prosody/config.ts b/server/lib/prosody/config.ts index dd7e9b15..577b0c7f 100644 --- a/server/lib/prosody/config.ts +++ b/server/lib/prosody/config.ts @@ -2,7 +2,7 @@ import * as fs from 'fs' import * as path from 'path' import { getBaseRouterRoute } from '../helpers' import { ProsodyFilePaths } from './config/paths' -import { ProsodyConfigContent } from './config/content' +import { ConfigLogExpiration, ProsodyConfigContent } from './config/content' import { getProsodyDomain } from './config/domain' import { getAPIKey } from '../apikey' import type { ProsodyLogLevel } from './config/content' @@ -70,6 +70,8 @@ interface ProsodyConfig { port: string baseApiUrl: string roomType: 'video' | 'channel' + logByDefault: boolean + logExpiration: ConfigLogExpiration } async function getProsodyConfig (options: RegisterServerOptions): Promise { const logger = options.peertubeHelpers.logger @@ -79,6 +81,9 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise +interface ConfigLogExpirationNever { + value: 'never' + type: 'never' +} +interface ConfigLogExpirationSeconds { + value: string + seconds: number + type: 'seconds' +} +interface ConfigLogExpirationPeriod { + value: string + type: 'period' +} +interface ConfigLogExpirationError { + value: string + error: string + type: 'period' +} +type ConfigLogExpiration = + ConfigLogExpirationNever | ConfigLogExpirationPeriod | ConfigLogExpirationSeconds | ConfigLogExpirationError + function writeValue (value: ConfigEntryValue): string { if (typeof value === 'boolean') { return value.toString() + ';\n' @@ -218,16 +239,23 @@ class ProsodyConfigContent { /** * Calling this method makes Prosody use mod_muc_mam to store rooms history. - * @param duration: how long the server must store messages. See https://prosody.im/doc/modules/mod_muc_mam + * @param logByDefault: if the room content should be archived by default. + * @param logExpiration: how long the server must store messages. See https://prosody.im/doc/modules/mod_muc_mam */ - useMam (duration: string): void { + useMam (logByDefault: boolean, logExpiration: ConfigLogExpiration): void { this.muc.add('modules_enabled', 'muc_mam') - this.muc.set('muc_log_by_default', true) + this.muc.set('muc_log_by_default', !!logByDefault) this.muc.set('muc_log_presences', true) - this.muc.set('log_all_rooms', true) - this.muc.set('muc_log_expires_after', duration) - this.muc.set('muc_log_cleanup_interval', 4 * 60 * 60) + this.muc.set('log_all_rooms', false) + this.muc.set('muc_log_expires_after', logExpiration.value) + const defaultCleanupInterval = 4 * 60 * 60 + if (logExpiration.type === 'seconds' && logExpiration.seconds && logExpiration.seconds < defaultCleanupInterval) { + // if the log expiration is less than the default cleanup interval, we have to decrease it. + this.muc.set('muc_log_cleanup_interval', logExpiration.seconds) + } else { + this.muc.set('muc_log_cleanup_interval', defaultCleanupInterval) + } // We can also use mod_muc_moderation // NB: for now Prosody has a partial support of this feature with «internal» storage. @@ -287,5 +315,6 @@ class ProsodyConfigContent { export { ProsodyLogLevel, - ProsodyConfigContent + ProsodyConfigContent, + ConfigLogExpiration } diff --git a/server/lib/settings.ts b/server/lib/settings.ts index caf7ed65..703fc7e3 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -327,6 +327,38 @@ In some rare case, Prosody can't call Peertube's API from its public URI. You can use this field to customise Peertube's URI for Prosody modules (for example with «http://localhost:9000»).` }) + registerSetting({ + name: 'prosody-muc-log-by-default', + label: 'Log rooms content by default', + type: 'input-checkbox', + default: true, + private: true, + descriptionHTML: +`If checked, room contents will be saved by default. +Any user that join a room will we what was written before he joins.
+Please note that it is always possible to enable/disable the content +archiving for a specific room, by editing its properties. +` + }) + + registerSetting({ + name: 'prosody-muc-expiration', + label: 'Room logs expiration', + type: 'input', + default: '1w', + private: true, + descriptionHTML: +`You can choose here how long the chatting room's content is kept by the server. The value can be: +
    +
  • 60: the content will be saved for 60 seconds. You can replace 60 by any integer value.
  • +
  • 1d: the content will be saved for 1 day. You can replace 1 by any integer value.
  • +
  • 1w: the content will be saved for 1 week. You can replace 1 by any integer value.
  • +
  • 1m: the content will be saved for 1 month. You can replace 1 by any integer value.
  • +
  • 1y: the content will be saved for 1 year. You can replace 1 by any integer value.
  • +
  • never: the content will never expire, and will be kept forever.
  • +
` + }) + registerSetting({ name: 'prosody-c2s', label: 'Enable client to server connections',