Configure bot name + refactoring.

This commit is contained in:
John Livingston 2023-09-19 18:56:39 +02:00
parent 9e7d9c6069
commit 4fe972dc10
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
7 changed files with 78 additions and 38 deletions

View File

@ -44,3 +44,4 @@ declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_ENABLE_BOT_LABEL: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_OPTIONS_TITLE: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_BANNED_JIDS_LABEL: string
declare const LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_NICKNAME: string

View File

@ -27,6 +27,7 @@ async function vivifyConfigurationChannel (
const data = new FormData(form)
const channelConfigurationOptions: ChannelConfigurationOptions = {
bot: data.get('bot') === '1',
botNickname: data.get('bot_nickname')?.toString() ?? '',
bannedJIDs: (data.get('banned_jids')?.toString() ?? '').split(/\r?\n|\r|\n/g),
forbiddenWords: (data.get('forbidden_words')?.toString() ?? '').split(/\r?\n|\r|\n/g)
}

View File

@ -47,6 +47,7 @@ async function renderConfigurationChannel (
bannedJIDs: await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_CHANNEL_BANNED_JIDS_LABEL),
save: await peertubeHelpers.translate(LOC_SAVE),
cancel: await peertubeHelpers.translate(LOC_CANCEL),
botNickname: await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_NICKNAME),
channelConfiguration
}
@ -69,6 +70,14 @@ async function renderConfigurationChannel (
</fieldset>
<fieldset livechat-configuration-channel-options-bot-enabled>
<legend>{{botOptions}}</legend>
<label>
{{botNickname}}
<input
type="text"
name="bot_nickname"
value="{{channelConfiguration.configuration.botNickname}}"
/>
</label>
<label>
{{forbiddenWords}}
<textarea name="forbidden_words">

View File

@ -317,4 +317,4 @@ livechat_configuration_channel_enable_bot_label: "Enable moderation bot"
livechat_configuration_channel_bot_options_title: "Moderation bot options"
livechat_configuration_channel_forbidden_words_label: "Forbidden words or expressions"
livechat_configuration_channel_banned_jids_label: "Banned users and patterns"
livechat_configuration_channel_bot_nickname: "Bot nickname"

View File

@ -14,49 +14,74 @@ async function sanitizeChannelConfigurationOptions (
_channelId: number | string,
data: any
): Promise<ChannelConfigurationOptions> {
const result = {
bot: false,
bannedJIDs: [],
forbiddenWords: []
}
if (typeof data !== 'object') {
throw new Error('Invalid data type')
}
// boolean fields
for (const f of ['bot']) {
if (!(f in data) || (typeof data[f] !== 'boolean')) {
throw new Error('Invalid data type for field ' + f)
}
result[f as keyof ChannelConfigurationOptions] = data[f]
}
// value/regexp array fields
for (const f of ['bannedJIDs', 'forbiddenWords']) {
if (!(f in data) || !Array.isArray(data[f])) {
throw new Error('Invalid data type for field ' + f)
}
for (const v of data[f]) {
if (typeof v !== 'string') {
throw new Error('Invalid data type in a value of field ' + f)
}
if (v === '' || /^\s+$/.test(v)) {
// ignore empty values
continue
}
// value must be a valid regexp
try {
// eslint-disable-next-line no-new
new RegExp(v)
} catch (_err) {
throw new Error('Invalid value in field ' + f)
}
(result[f as keyof ChannelConfigurationOptions] as string[]).push(v)
}
const result: ChannelConfigurationOptions = {
bot: _readBoolean(data, 'bot'),
botNickname: _readSimpleInput(data, 'botNickname'),
bannedJIDs: await _readRegExpArray(data, 'bannedJIDs'),
forbiddenWords: await _readRegExpArray(data, 'forbiddenWords')
}
return result
}
function _readBoolean (data: any, f: string): boolean {
if (!(f in data)) {
return false
}
if (typeof data[f] !== 'boolean') {
throw new Error('Invalid data type for field ' + f)
}
return data[f]
}
function _readSimpleInput (data: any, f: string): string {
if (!(f in data)) {
return ''
}
if (typeof data[f] !== 'string') {
throw new Error('Invalid data type for field ' + f)
}
// Replacing all invalid characters, no need to throw an error..
return (data[f] as string).replace(/[^\p{L}\p{N}\p{Z}_-]$/gu, '')
}
async function _readRegExpArray (data: any, f: string): Promise<string[]> {
// Note: this function can instanciate a lot of RegExp.
// To avoid freezing the server, we make it async, and will validate each regexp in a separate tick.
if (!(f in data)) {
return []
}
if (!Array.isArray(data[f])) {
throw new Error('Invalid data type for field ' + f)
}
const result: string[] = []
for (const v of data[f]) {
if (typeof v !== 'string') {
throw new Error('Invalid data type in a value of field ' + f)
}
if (v === '' || /^\s+$/.test(v)) {
// ignore empty values
continue
}
// value must be a valid regexp
try {
async function _validate (): Promise<void> {
// eslint-disable-next-line no-new
new RegExp(v)
}
await _validate()
} catch (_err) {
throw new Error('Invalid value in field ' + f)
}
result.push(v)
}
return result
}
export {
sanitizeChannelConfigurationOptions
}

View File

@ -33,6 +33,7 @@ async function getChannelConfigurationOptions (
function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions): ChannelConfigurationOptions {
return {
bot: false,
botNickname: 'Sepia',
bannedJIDs: [],
forbiddenWords: []
}
@ -77,11 +78,13 @@ function channelConfigurationOptionsToBotRoomConf (
options: RegisterServerOptions,
channelConfigurationOptions: ChannelConfigurationOptions
): ChannelCommonRoomConf {
const roomConf = {
const roomConf: ChannelCommonRoomConf = {
enabled: channelConfigurationOptions.bot,
// TODO: nick
handlers: []
}
if (channelConfigurationOptions.botNickname && channelConfigurationOptions.botNickname !== '') {
roomConf.nick = channelConfigurationOptions.botNickname
}
return roomConf
}

View File

@ -54,6 +54,7 @@ interface ChannelInfos {
interface ChannelConfigurationOptions {
bot: boolean
botNickname?: string
forbiddenWords: string[]
bannedJIDs: string[]
}