Channel Configuration UI WIP
This commit is contained in:
parent
cc673bd3cb
commit
aa71a302f6
@ -47,9 +47,9 @@ async function renderConfigurationChannel (
|
|||||||
name="bot"
|
name="bot"
|
||||||
id="peertube-livechat-bot"
|
id="peertube-livechat-bot"
|
||||||
value="1"
|
value="1"
|
||||||
{{#channelConfiguration.configuration.bot}}
|
{{#channelConfiguration.configuration.bot.enabled}}
|
||||||
checked="checked"
|
checked="checked"
|
||||||
{{/channelConfiguration.configuration.bot}}
|
{{/channelConfiguration.configuration.bot.enabled}}
|
||||||
/>
|
/>
|
||||||
{{enableBot}}
|
{{enableBot}}
|
||||||
</label>
|
</label>
|
||||||
@ -61,7 +61,7 @@ async function renderConfigurationChannel (
|
|||||||
name="bot_nickname"
|
name="bot_nickname"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="peertube-livechat-bot-nickname"
|
id="peertube-livechat-bot-nickname"
|
||||||
value="{{channelConfiguration.configuration.botNickname}}"
|
value="{{channelConfiguration.configuration.bot.nickname}}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,11 +84,7 @@ async function renderConfigurationChannel (
|
|||||||
name="forbidden_words_{{fieldNumber}}"
|
name="forbidden_words_{{fieldNumber}}"
|
||||||
id="peertube-livechat-forbidden-words-{{fieldNumber}}"
|
id="peertube-livechat-forbidden-words-{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>{{
|
>{{entries}}</textarea>
|
||||||
#channelConfiguration.configuration.forbiddenWords
|
|
||||||
}}{{.}}\n{{
|
|
||||||
/channelConfiguration.configuration.forbiddenWords
|
|
||||||
}}</textarea>
|
|
||||||
<p class="form-group-description">{{forbiddenWordsDesc2}}</p>
|
<p class="form-group-description">{{forbiddenWordsDesc2}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -97,6 +93,9 @@ async function renderConfigurationChannel (
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="forbidden_words_regexp_{{fieldNumber}}"
|
name="forbidden_words_regexp_{{fieldNumber}}"
|
||||||
value="1"
|
value="1"
|
||||||
|
{{#regexp}}
|
||||||
|
checked="checked"
|
||||||
|
{{/regexp}}
|
||||||
/>
|
/>
|
||||||
{{forbiddenWordsRegexp}}
|
{{forbiddenWordsRegexp}}
|
||||||
</label>
|
</label>
|
||||||
@ -108,6 +107,9 @@ async function renderConfigurationChannel (
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="forbidden_words_applytomoderators_{{fieldNumber}}"
|
name="forbidden_words_applytomoderators_{{fieldNumber}}"
|
||||||
value="1"
|
value="1"
|
||||||
|
{{#applyToModerators}}
|
||||||
|
checked="checked"
|
||||||
|
{{/applyToModerators}}
|
||||||
/>
|
/>
|
||||||
{{forbiddenWordsApplyToModerators}}
|
{{forbiddenWordsApplyToModerators}}
|
||||||
</label>
|
</label>
|
||||||
@ -120,7 +122,7 @@ async function renderConfigurationChannel (
|
|||||||
name="forbidden_words_reason_{{fieldNumber}}"
|
name="forbidden_words_reason_{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="peertube-livechat-forbidden-words-reason-{{fieldNumber}}"
|
id="peertube-livechat-forbidden-words-reason-{{fieldNumber}}"
|
||||||
value=""
|
value="{{reason}}"
|
||||||
/>
|
/>
|
||||||
<p class="form-group-description">{{forbiddenWordsReasonDesc}}</p>
|
<p class="form-group-description">{{forbiddenWordsReasonDesc}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,15 +33,23 @@ async function getConfigurationChannelViewData (
|
|||||||
throw new Error('Invalid channel configuration options.')
|
throw new Error('Invalid channel configuration options.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const forbiddenWordsArray = []
|
||||||
|
for (let i = 0; i < channelConfiguration.configuration.bot.forbiddenWords.length; i++) {
|
||||||
|
const fw = channelConfiguration.configuration.bot.forbiddenWords[i]
|
||||||
|
forbiddenWordsArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
entries: fw.entries.join('\n'),
|
||||||
|
regexp: !!fw.regexp,
|
||||||
|
applyToModerators: fw.applyToModerators,
|
||||||
|
reason: fw.reason
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
channelConfiguration,
|
channelConfiguration,
|
||||||
forbiddenWordsArray: [0, 1, 2].map(count => {
|
forbiddenWordsArray,
|
||||||
return {
|
|
||||||
displayNumber: count + 1,
|
|
||||||
fieldNumber: count,
|
|
||||||
displayHelp: count === 0
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
quotesArray: [0].map(count => {
|
quotesArray: [0].map(count => {
|
||||||
return {
|
return {
|
||||||
displayNumber: count + 1,
|
displayNumber: count + 1,
|
||||||
@ -89,11 +97,35 @@ async function vivifyConfigurationChannel (
|
|||||||
const submitForm: Function = async () => {
|
const submitForm: Function = async () => {
|
||||||
const data = new FormData(form)
|
const data = new FormData(form)
|
||||||
const channelConfigurationOptions: ChannelConfigurationOptions = {
|
const channelConfigurationOptions: ChannelConfigurationOptions = {
|
||||||
bot: data.get('bot') === '1',
|
bot: {
|
||||||
botNickname: data.get('bot_nickname')?.toString() ?? '',
|
enabled: data.get('bot') === '1',
|
||||||
// bannedJIDs: (data.get('banned_jids')?.toString() ?? '').split(/\r?\n|\r|\n/g),
|
nickname: data.get('bot_nickname')?.toString() ?? '',
|
||||||
forbiddenWords: (data.get('forbidden_words')?.toString() ?? '').split(/\r?\n|\r|\n/g)
|
// TODO bannedJIDs
|
||||||
|
forbiddenWords: [],
|
||||||
|
quotes: [],
|
||||||
|
commands: []
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle form errors.
|
||||||
|
|
||||||
|
for (let i = 0; data.has('forbidden_words_' + i.toString()); i++) {
|
||||||
|
const entries = (data.get('forbidden_words_' + i.toString())?.toString() ?? '').split(/\r?\n|\r|\n/g)
|
||||||
|
const regexp = data.get('forbidden_words_regexp_' + i.toString())
|
||||||
|
const applyToModerators = data.get('forbidden_words_applytomoderators_' + i.toString())
|
||||||
|
const reason = data.get('forbidden_words_reason_' + i.toString())?.toString()
|
||||||
|
const fw: ChannelConfigurationOptions['bot']['forbiddenWords'][0] = {
|
||||||
|
entries,
|
||||||
|
applyToModerators: !!applyToModerators,
|
||||||
|
regexp: !!regexp
|
||||||
|
}
|
||||||
|
if (reason) {
|
||||||
|
fw.reason = reason
|
||||||
|
}
|
||||||
|
channelConfigurationOptions.bot.forbiddenWords.push(fw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: quotes and commands.
|
||||||
|
|
||||||
const headers: any = clientOptions.peertubeHelpers.getAuthHeader() ?? {}
|
const headers: any = clientOptions.peertubeHelpers.getAuthHeader() ?? {}
|
||||||
headers['content-type'] = 'application/json;charset=UTF-8'
|
headers['content-type'] = 'application/json;charset=UTF-8'
|
||||||
|
@ -18,11 +18,20 @@ async function sanitizeChannelConfigurationOptions (
|
|||||||
throw new Error('Invalid data type')
|
throw new Error('Invalid data type')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const botData = data.bot
|
||||||
|
if (typeof botData !== 'object') {
|
||||||
|
throw new Error('Invalid data.bot data type')
|
||||||
|
}
|
||||||
|
|
||||||
const result: ChannelConfigurationOptions = {
|
const result: ChannelConfigurationOptions = {
|
||||||
bot: _readBoolean(data, 'bot'),
|
bot: {
|
||||||
botNickname: _readSimpleInput(data, 'botNickname'),
|
enabled: _readBoolean(botData, 'enabled'),
|
||||||
// bannedJIDs: await _readRegExpArray(data, 'bannedJIDs'),
|
nickname: _readSimpleInput(botData, 'nickname', true),
|
||||||
forbiddenWords: await _readRegExpArray(data, 'forbiddenWords')
|
forbiddenWords: await _readForbiddenWords(botData),
|
||||||
|
quotes: _readQuotes(botData),
|
||||||
|
commands: _readCommands(botData)
|
||||||
|
// TODO: bannedJIDs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -38,15 +47,59 @@ function _readBoolean (data: any, f: string): boolean {
|
|||||||
return data[f]
|
return data[f]
|
||||||
}
|
}
|
||||||
|
|
||||||
function _readSimpleInput (data: any, f: string): string {
|
function _readInteger (data: any, f: string, min: number, max: number): number {
|
||||||
|
if (!(f in data)) {
|
||||||
|
throw new Error('Missing integer value for field ' + f)
|
||||||
|
}
|
||||||
|
const v = parseInt(data[f])
|
||||||
|
if (isNaN(v)) {
|
||||||
|
throw new Error('Invalid value type for field ' + f)
|
||||||
|
}
|
||||||
|
if (v < min) {
|
||||||
|
throw new Error('Invalid value type (<min) for field ' + f)
|
||||||
|
}
|
||||||
|
if (v > max) {
|
||||||
|
throw new Error('Invalid value type (>max) for field ' + f)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readSimpleInput (data: any, f: string, strict?: boolean): string {
|
||||||
if (!(f in data)) {
|
if (!(f in data)) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
if (typeof data[f] !== 'string') {
|
if (typeof data[f] !== 'string') {
|
||||||
throw new Error('Invalid data type for field ' + f)
|
throw new Error('Invalid data type for field ' + f)
|
||||||
}
|
}
|
||||||
|
// Removing control characters.
|
||||||
|
// eslint-disable-next-line no-control-regex
|
||||||
|
let s = (data[f] as string).replace(/[\u0000-\u001F\u007F-\u009F]/g, '')
|
||||||
|
if (strict) {
|
||||||
// Replacing all invalid characters, no need to throw an error..
|
// Replacing all invalid characters, no need to throw an error..
|
||||||
return (data[f] as string).replace(/[^\p{L}\p{N}\p{Z}_-]$/gu, '')
|
s = s.replace(/[^\p{L}\p{N}\p{Z}_-]$/gu, '')
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readStringArray (data: any, f: string): string[] {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
result.push(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _readRegExpArray (data: any, f: string): Promise<string[]> {
|
async function _readRegExpArray (data: any, f: string): Promise<string[]> {
|
||||||
@ -82,6 +135,66 @@ async function _readRegExpArray (data: any, f: string): Promise<string[]> {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function _readForbiddenWords (botData: any): Promise<ChannelConfigurationOptions['bot']['forbiddenWords']> {
|
||||||
|
if (!Array.isArray(botData.forbiddenWords)) {
|
||||||
|
throw new Error('Invalid forbiddenWords data')
|
||||||
|
}
|
||||||
|
const result: ChannelConfigurationOptions['bot']['forbiddenWords'] = []
|
||||||
|
for (const fw of botData.forbiddenWords) {
|
||||||
|
const regexp = !!fw.regexp
|
||||||
|
let entries
|
||||||
|
if (regexp) {
|
||||||
|
entries = await _readRegExpArray(fw, 'entries')
|
||||||
|
} else {
|
||||||
|
entries = _readStringArray(fw, 'entries')
|
||||||
|
}
|
||||||
|
const applyToModerators = _readBoolean(fw, 'applyToModerators')
|
||||||
|
const reason = fw.reason ? _readSimpleInput(fw, 'reason') : undefined
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
regexp,
|
||||||
|
entries,
|
||||||
|
applyToModerators,
|
||||||
|
reason
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readQuotes (botData: any): ChannelConfigurationOptions['bot']['quotes'] {
|
||||||
|
if (!Array.isArray(botData.quotes)) {
|
||||||
|
throw new Error('Invalid quotes data')
|
||||||
|
}
|
||||||
|
const result: ChannelConfigurationOptions['bot']['quotes'] = []
|
||||||
|
for (const fw of botData.quotes) {
|
||||||
|
const messages = _readStringArray(fw, 'message')
|
||||||
|
const delay = _readInteger(fw, 'delay', 1, 6000)
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
messages,
|
||||||
|
delay
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function _readCommands (botData: any): ChannelConfigurationOptions['bot']['commands'] {
|
||||||
|
if (!Array.isArray(botData.commands)) {
|
||||||
|
throw new Error('Invalid commands data')
|
||||||
|
}
|
||||||
|
const result: ChannelConfigurationOptions['bot']['commands'] = []
|
||||||
|
for (const fw of botData.commands) {
|
||||||
|
const message = _readSimpleInput(fw, 'message')
|
||||||
|
const command = _readSimpleInput(fw, 'command')
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
message,
|
||||||
|
command
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
sanitizeChannelConfigurationOptions
|
sanitizeChannelConfigurationOptions
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,43 @@ async function getChannelConfigurationOptions (
|
|||||||
|
|
||||||
function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions): ChannelConfigurationOptions {
|
function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions): ChannelConfigurationOptions {
|
||||||
return {
|
return {
|
||||||
bot: false,
|
bot: {
|
||||||
botNickname: 'Sepia',
|
enabled: false,
|
||||||
// bannedJIDs: [],
|
nickname: 'Sepia',
|
||||||
forbiddenWords: []
|
// Note: we are instanciating several data for forbiddenWords, quotes and commands.
|
||||||
|
// This will be used by the frontend to instanciates requires fields
|
||||||
|
forbiddenWords: [
|
||||||
|
{
|
||||||
|
entries: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entries: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entries: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
quotes: [
|
||||||
|
{
|
||||||
|
messages: [],
|
||||||
|
delay: 5 * 60 // seconds to minutes
|
||||||
|
}
|
||||||
|
],
|
||||||
|
commands: [
|
||||||
|
{
|
||||||
|
command: '',
|
||||||
|
message: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: '',
|
||||||
|
message: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
command: '',
|
||||||
|
message: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,25 +119,26 @@ function channelConfigurationOptionsToBotRoomConf (
|
|||||||
// If we want the bot to correctly enable/disable the handlers,
|
// If we want the bot to correctly enable/disable the handlers,
|
||||||
// we must always define all handlers, even if not used.
|
// we must always define all handlers, even if not used.
|
||||||
const handlers: ConfigHandlers = []
|
const handlers: ConfigHandlers = []
|
||||||
|
channelConfigurationOptions.bot.forbiddenWords.forEach((v, i) => {
|
||||||
handlers.push(_getForbiddenWordsHandler(
|
handlers.push(_getForbiddenWordsHandler(
|
||||||
'forbidden_words_0',
|
'forbidden_words_' + i.toString(),
|
||||||
channelConfigurationOptions.forbiddenWords
|
channelConfigurationOptions.bot.forbiddenWords[i]
|
||||||
))
|
))
|
||||||
|
})
|
||||||
|
|
||||||
const roomConf: ChannelCommonRoomConf = {
|
const roomConf: ChannelCommonRoomConf = {
|
||||||
enabled: channelConfigurationOptions.bot,
|
enabled: channelConfigurationOptions.bot.enabled,
|
||||||
handlers
|
handlers
|
||||||
}
|
}
|
||||||
if (channelConfigurationOptions.botNickname && channelConfigurationOptions.botNickname !== '') {
|
if (channelConfigurationOptions.bot.nickname && channelConfigurationOptions.bot.nickname !== '') {
|
||||||
roomConf.nick = channelConfigurationOptions.botNickname
|
roomConf.nick = channelConfigurationOptions.bot.nickname
|
||||||
}
|
}
|
||||||
return roomConf
|
return roomConf
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getForbiddenWordsHandler (
|
function _getForbiddenWordsHandler (
|
||||||
id: string,
|
id: string,
|
||||||
forbiddenWords: string[],
|
forbiddenWords: ChannelConfigurationOptions['bot']['forbiddenWords'][0]
|
||||||
reason?: string
|
|
||||||
): ConfigHandler {
|
): ConfigHandler {
|
||||||
const handler: ConfigHandler = {
|
const handler: ConfigHandler = {
|
||||||
type: 'moderate',
|
type: 'moderate',
|
||||||
@ -114,26 +148,63 @@ function _getForbiddenWordsHandler (
|
|||||||
rules: []
|
rules: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (forbiddenWords.length === 0) {
|
if (forbiddenWords.entries.length === 0) {
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.enabled = true
|
handler.enabled = true
|
||||||
|
const rule: any = {
|
||||||
|
name: id
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forbiddenWords.regexp) {
|
||||||
// Note: on the Peertube frontend, channelConfigurationOptions.forbiddenWords
|
// Note: on the Peertube frontend, channelConfigurationOptions.forbiddenWords
|
||||||
// is an array of RegExp definition (strings).
|
// is an array of RegExp definition (strings).
|
||||||
// They are validated one by bone.
|
// They are validated one by bone.
|
||||||
// To increase the bot performance, we will join them all (hopping the bot will optimize them).
|
// To increase the bot performance, we will join them all (hopping the bot will optimize them).
|
||||||
const rule: any = {
|
rule.regexp = '(?:' + forbiddenWords.entries.join(')|(?:') + ')'
|
||||||
name: id,
|
} else {
|
||||||
regexp: '(?:' + forbiddenWords.join(')|(?:') + ')'
|
// Here we must add word-breaks and escape entries.
|
||||||
|
// We join all entries in one Regexp (for the same reason as above).
|
||||||
|
rule.regexp = '(?:' +
|
||||||
|
forbiddenWords.entries.map(s => {
|
||||||
|
s = _stringToWordRegexp(s)
|
||||||
|
// Must add the \b...
|
||||||
|
// ... but... won't work if the first (or last) char is an emoji.
|
||||||
|
// So, doing this trick:
|
||||||
|
if (/^\w/.test(s)) {
|
||||||
|
s = '\\b' + s
|
||||||
}
|
}
|
||||||
if (reason) {
|
if (/\w$/.test(s)) {
|
||||||
rule.reason = reason
|
s = s + '\\b'
|
||||||
|
}
|
||||||
|
// FIXME: this solution wont work for non-latin charsets.
|
||||||
|
return s
|
||||||
|
}).join(')|(?:') + ')'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forbiddenWords.reason) {
|
||||||
|
rule.reason = forbiddenWords.reason
|
||||||
}
|
}
|
||||||
handler.options.rules.push(rule)
|
handler.options.rules.push(rule)
|
||||||
|
|
||||||
|
handler.options.applyToModerators = !!forbiddenWords.applyToModerators
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stringToWordRegexpSpecials = [
|
||||||
|
// order matters for these
|
||||||
|
'-', '[', ']',
|
||||||
|
// order doesn't matter for any of these
|
||||||
|
'/', '{', '}', '(', ')', '*', '+', '?', '.', '\\', '^', '$', '|'
|
||||||
|
]
|
||||||
|
// I choose to escape every character with '\'
|
||||||
|
// even though only some strictly require it when inside of []
|
||||||
|
const stringToWordRegexp = RegExp('[' + stringToWordRegexpSpecials.join('\\') + ']', 'g')
|
||||||
|
function _stringToWordRegexp (s: string): string {
|
||||||
|
return s.replace(stringToWordRegexp, '\\$&')
|
||||||
|
}
|
||||||
|
|
||||||
function _getFilePath (
|
function _getFilePath (
|
||||||
options: RegisterServerOptions,
|
options: RegisterServerOptions,
|
||||||
channelId: number | string
|
channelId: number | string
|
||||||
|
@ -55,6 +55,16 @@ async function initConfigurationApiRouter (options: RegisterServerOptions, route
|
|||||||
// Note: the front-end should do some input validation.
|
// Note: the front-end should do some input validation.
|
||||||
// If there is any invalid value, we just return a 400 error.
|
// If there is any invalid value, we just return a 400 error.
|
||||||
// The frontend should have prevented to post invalid data.
|
// The frontend should have prevented to post invalid data.
|
||||||
|
|
||||||
|
// Note: if !bot.enabled, we wont try to save hidden fields values, to minimize the risk of error
|
||||||
|
if (req.body.bot?.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 = channelOptions.bot
|
||||||
|
req.body.bot.enable = false
|
||||||
|
}
|
||||||
channelOptions = await sanitizeChannelConfigurationOptions(options, channelInfos.id, req.body)
|
channelOptions = await sanitizeChannelConfigurationOptions(options, channelInfos.id, req.body)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn(err)
|
logger.warn(err)
|
||||||
|
@ -53,10 +53,25 @@ interface ChannelInfos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ChannelConfigurationOptions {
|
interface ChannelConfigurationOptions {
|
||||||
bot: boolean
|
bot: {
|
||||||
botNickname?: string
|
enabled: boolean
|
||||||
forbiddenWords: string[]
|
nickname?: string
|
||||||
|
forbiddenWords: Array<{
|
||||||
|
entries: string[]
|
||||||
|
regexp?: boolean
|
||||||
|
applyToModerators?: boolean
|
||||||
|
reason?: string
|
||||||
|
}>
|
||||||
|
quotes: Array<{
|
||||||
|
messages: string[]
|
||||||
|
delay: number
|
||||||
|
}>
|
||||||
|
commands: Array<{
|
||||||
|
command: string
|
||||||
|
message: string
|
||||||
|
}>
|
||||||
// TODO: bannedJIDs: string[]
|
// TODO: bannedJIDs: string[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChannelConfiguration {
|
interface ChannelConfiguration {
|
||||||
|
Loading…
Reference in New Issue
Block a user