Configure bot name + refactoring.

This commit is contained in:
John Livingston
2023-09-19 18:56:39 +02:00
parent 9e7d9c6069
commit 4fe972dc10
7 changed files with 78 additions and 38 deletions

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
}