New option for the moderation bot:

* forbid messages with too many special characters (#517).
* update moderation bot to v0.4.0.
* refactoring localization segments to reuse existing one in multiple
  context.
* npm run doc:translate
This commit is contained in:
John Livingston
2024-09-07 00:46:23 +02:00
parent b6028ef740
commit f15d3ed542
61 changed files with 1471 additions and 529 deletions

View File

@ -44,6 +44,14 @@ async function sanitizeChannelConfigurationOptions (
const mute = data.mute ?? {}
mute.anonymous ??= false
// forbidSpecialChars comes with livechat 11.1.0
botData.forbidSpecialChars ??= {
enabled: false,
reason: '',
tolerance: 0,
applyToModerators: false
}
if (typeof mute !== 'object') {
throw new Error('Invalid data.mute data type')
}
@ -63,6 +71,7 @@ async function sanitizeChannelConfigurationOptions (
enabled: _readBoolean(botData, 'enabled'),
nickname: _readSimpleInput(botData, 'nickname', true),
forbiddenWords: await _readForbiddenWords(botData),
forbidSpecialChars: await _readForbidSpecialChars(botData),
quotes: _readQuotes(botData),
commands: _readCommands(botData)
// TODO: bannedJIDs
@ -229,6 +238,21 @@ async function _readForbiddenWords (botData: any): Promise<ChannelConfigurationO
return result
}
async function _readForbidSpecialChars (
botData: any
): Promise<ChannelConfigurationOptions['bot']['forbidSpecialChars']> {
if (typeof botData.forbidSpecialChars !== 'object') {
throw new Error('Invalid forbidSpecialChars data')
}
const result: ChannelConfigurationOptions['bot']['forbidSpecialChars'] = {
enabled: _readBoolean(botData.forbidSpecialChars, 'enabled'),
reason: _readSimpleInput(botData.forbidSpecialChars, 'reason'),
tolerance: _readInteger(botData.forbidSpecialChars, 'tolerance', 0, 10),
applyToModerators: _readBoolean(botData.forbidSpecialChars, 'applyToModerators')
}
return result
}
function _readQuotes (botData: any): ChannelConfigurationOptions['bot']['quotes'] {
if (!Array.isArray(botData.quotes)) {
throw new Error('Invalid quotes data')

View File

@ -44,6 +44,12 @@ function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions)
enabled: false,
nickname: 'Sepia',
forbiddenWords: [],
forbidSpecialChars: {
enabled: false,
reason: '',
tolerance: 0,
applyToModerators: false
},
quotes: [],
commands: []
},
@ -113,6 +119,11 @@ function channelConfigurationOptionsToBotRoomConf (
handlersIds.set(id, true)
handlers.push(_getForbiddenWordsHandler(id, v))
})
if (channelConfigurationOptions.bot.forbidSpecialChars.enabled) {
const id = 'forbid_special_chars'
handlersIds.set(id, true)
handlers.push(_getForbidSpecialCharsHandler(id, channelConfigurationOptions.bot.forbidSpecialChars))
}
channelConfigurationOptions.bot.quotes.forEach((v, i) => {
const id = 'quote_' + i.toString()
handlersIds.set(id, true)
@ -202,6 +213,46 @@ function _getForbiddenWordsHandler (
return handler
}
function _getForbidSpecialCharsHandler (
id: string,
forbidSpecialChars: ChannelConfigurationOptions['bot']['forbidSpecialChars']
): ConfigHandler {
const handler: ConfigHandler = {
type: 'moderate',
id,
enabled: true,
options: {
rules: []
}
}
// The regexp to find one invalid character:
// (Note: Emoji_Modifier and Emoji_Component should not be matched alones, but seems a reasonnable compromise to avoid
// complex regex).
let regexp = '[^' +
'\\s\\p{Letter}\\p{Number}\\p{Punctuation}\\p{Currency_Symbol}\\p{Emoji}\\p{Emoji_Component}\\p{Emoji_Modifier}' +
']'
if (forbidSpecialChars.tolerance > 0) {
// we must repeat !
const a = []
for (let i = 0; i <= forbidSpecialChars.tolerance; i++) { // N+1 values
a.push(regexp)
}
regexp = a.join('.*')
}
const rule: any = {
name: id,
regexp,
modifiers: 'us',
reason: forbidSpecialChars.reason
}
handler.options.rules.push(rule)
handler.options.applyToModerators = !!forbidSpecialChars.applyToModerators
return handler
}
function _getQuotesHandler (
id: string,
quotes: ChannelConfigurationOptions['bot']['quotes'][0]

View File

@ -96,6 +96,19 @@ async function initConfigurationApiRouter (options: RegisterServerOptions, route
req.body.bot = channelOptions.bot
req.body.bot.enabled = false
}
// TODO: Same for forbidSpecialChars: if disabled, don't save reason and tolerance
// (disabling for now, because it is not acceptable to load twice the channel configuration.
// Must find better way)
// if (req.body.bot?.enabled === true && req.body.bot.forbidSpecialChars?.enabled === false) {
// logger.debug('Bot disabled, loading the previous bot conf to not override hidden fields')
// const channelOptions =
// await getChannelConfigurationOptions(options, channelInfos.id) ??
// getDefaultChannelConfigurationOptions(options)
// req.body.bot.forbidSpecialChars.reason = channelOptions.bot.forbidSpecialChars.reason
// req.body.bot.forbidSpecialChars.tolerance = channelOptions.bot.forbidSpecialChars.tolerance
// req.body.bot.forbidSpecialChars.applyToModerators = channelOptions.bot.forbidSpecialChars.applyToModerators
// req.body.bot.forbidSpecialChars.enabled = false
// }
channelOptions = await sanitizeChannelConfigurationOptions(options, channelInfos.id, req.body)
} catch (err) {
logger.warn(err)