Settings validation

This commit is contained in:
Isaac 2021-05-17 20:24:00 +01:00
parent 2e679b5693
commit 6a978aa025
No known key found for this signature in database
GPG Key ID: F6812DBC6719B4E3
6 changed files with 126 additions and 2 deletions

5
jsconfig.json Normal file
View File

@ -0,0 +1,5 @@
{
"include": [
"src/**/*.js"
]
}

View File

@ -34,6 +34,7 @@
"cryptr": "^6.0.2", "cryptr": "^6.0.2",
"discord.js": "^12.5.1", "discord.js": "^12.5.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"jsonschema": "^1.4.0",
"keyv": "^4.0.3", "keyv": "^4.0.3",
"leeks.js": "^0.2.2", "leeks.js": "^0.2.2",
"leekslazylogger-fastify": "^0.1.1", "leekslazylogger-fastify": "^0.1.1",

View File

@ -8,6 +8,7 @@ specifiers:
discord.js: ^12.5.1 discord.js: ^12.5.1
dotenv: ^8.2.0 dotenv: ^8.2.0
eslint: ^7.21.0 eslint: ^7.21.0
jsonschema: ^1.4.0
keyv: ^4.0.3 keyv: ^4.0.3
leeks.js: ^0.2.2 leeks.js: ^0.2.2
leekslazylogger-fastify: ^0.1.1 leekslazylogger-fastify: ^0.1.1
@ -33,6 +34,7 @@ dependencies:
cryptr: 6.0.2 cryptr: 6.0.2
discord.js: 12.5.1 discord.js: 12.5.1
dotenv: 8.2.0 dotenv: 8.2.0
jsonschema: 1.4.0
keyv: 4.0.3 keyv: 4.0.3
leeks.js: 0.2.2 leeks.js: 0.2.2
leekslazylogger-fastify: 0.1.1 leekslazylogger-fastify: 0.1.1
@ -1422,6 +1424,10 @@ packages:
/json-stringify-safe/5.0.1: /json-stringify-safe/5.0.1:
resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
/jsonschema/1.4.0:
resolution: {integrity: sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==}
dev: false
/jsprim/1.4.1: /jsprim/1.4.1:
resolution: {integrity: sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=} resolution: {integrity: sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=}
engines: {'0': node >=0.6.0} engines: {'0': node >=0.6.0}

View File

@ -1,6 +1,7 @@
const Command = require('../modules/commands/command'); const Command = require('../modules/commands/command');
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const { MessageAttachment } = require('discord.js'); const { MessageAttachment } = require('discord.js');
const { Validator } = require('jsonschema');
module.exports = class SettingsCommand extends Command { module.exports = class SettingsCommand extends Command {
constructor(client) { constructor(client) {
@ -16,6 +17,108 @@ module.exports = class SettingsCommand extends Command {
args: [], args: [],
permissions: ['MANAGE_GUILD'] permissions: ['MANAGE_GUILD']
}); });
this.schema = {
type: 'object',
properties: {
categories: {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'string'
},
claiming: {
type: 'boolean'
},
image: {
type: ['string', 'null']
},
max_per_member: {
type: 'number'
},
name: {
type: 'string'
},
name_format: {
type: 'string'
},
opening_message: {
type: 'string'
},
opening_questions: {
type: ['array', 'null'],
items: {
type: 'string'
}
},
ping: {
type: ['array', 'null'],
items: {
type: 'string'
}
},
require_topic: {
type: 'boolean'
},
roles: {
type: 'array',
items: {
type: 'string'
}
},
survey: {
type: ['string', 'null']
}
},
required: [
'name',
'name_format',
'opening_message',
'roles'
]
}
},
colour: {
type: 'string'
},
command_prefix: {
type: 'string'
},
error_colour: {
type: 'string'
},
footer: {
type: 'string'
},
locale: {
type: 'string'
},
log_messages: {
type: 'boolean'
},
success_colour: {
type: 'string'
},
surveys: {
type: 'object'
}
},
required: [
'categories',
'colour',
'command_prefix',
'error_colour',
'footer',
'locale',
'log_messages',
'success_colour',
'surveys'
]
};
this.v = new Validator();
} }
async execute(message) { async execute(message) {
@ -29,6 +132,14 @@ module.exports = class SettingsCommand extends Command {
// load settings from json // load settings from json
this.client.log.info(`Downloading settings for "${message.guild.name}"`); this.client.log.info(`Downloading settings for "${message.guild.name}"`);
let data = await (await fetch(attachments[0].url)).json(); let data = await (await fetch(attachments[0].url)).json();
const { valid, errors } = this.v.validate(data, this.schema);
if (!valid) {
this.client.log.warn('Settings validation error');
return await message.channel.send(i18n('commands.settings.response.invalid', errors.map(error => `\`${error.stack}\``).join(',\n')));
}
settings.colour = data.colour; settings.colour = data.colour;
settings.command_prefix = data.command_prefix; settings.command_prefix = data.command_prefix;
settings.error_colour = data.error_colour; settings.error_colour = data.error_colour;
@ -137,7 +248,7 @@ module.exports = class SettingsCommand extends Command {
} }
this.client.log.success(`Updated guild settings for "${message.guild.name}"`); this.client.log.success(`Updated guild settings for "${message.guild.name}"`);
message.channel.send(i18n('commands.settings.response.updated')); return await message.channel.send(i18n('commands.settings.response.updated'));
} else { } else {

View File

@ -323,6 +323,7 @@
"description": "Configure Discord Tickets", "description": "Configure Discord Tickets",
"name": "settings", "name": "settings",
"response": { "response": {
"invalid": "❌ Settings data is invalid; please refer to the documentation.\n%s",
"updated": "✅ Settings have been updated." "updated": "✅ Settings have been updated."
} }
}, },

View File

@ -1,5 +1,5 @@
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const { Collection, Client } = require('discord.js'); const { Collection } = require('discord.js');
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const Plugin = require('./plugin'); const Plugin = require('./plugin');