Started work on site-wide toke command management & errorHandler
This commit is contained in:
parent
d516fed309
commit
af7f4219a5
|
|
@ -35,8 +35,7 @@ module.exports.post = async function(req, res){
|
||||||
//if we found any related nuked bans
|
//if we found any related nuked bans
|
||||||
if(nukedBans != null){
|
if(nukedBans != null){
|
||||||
//Shit our pants!
|
//Shit our pants!
|
||||||
res.status(401);
|
return errorHandler(res, 'Cannon re-create banned account!', 'unauthorized');
|
||||||
return res.send({errors:[{msg:"Cannot re-create banned account!",type:"unauthorized"}]});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await userModel.register(user)
|
await userModel.register(user)
|
||||||
|
|
|
||||||
64
src/controllers/api/admin/tokeCommandController.js
Normal file
64
src/controllers/api/admin/tokeCommandController.js
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*Canopy - The next generation of stoner streaming software
|
||||||
|
Copyright (C) 2024 Rainbownapkin and the TTN Community
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
|
//npm imports
|
||||||
|
const {validationResult, matchedData} = require('express-validator');
|
||||||
|
|
||||||
|
//local imports
|
||||||
|
const {exceptionHandler, errorHandler} = require('../../../utils/loggerUtils.js');
|
||||||
|
const tokeCommandModel = require('../../../schemas/tokebot/tokeCommandSchema.js');
|
||||||
|
|
||||||
|
module.exports.get = async function(req, res){
|
||||||
|
try{
|
||||||
|
const tokeList = await tokeCommandModel.getCommandStrings();
|
||||||
|
|
||||||
|
res.status(200);
|
||||||
|
return res.send(tokeList);
|
||||||
|
}catch(err){
|
||||||
|
return exceptionHandler(res, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.post = async function(req, res){
|
||||||
|
try{
|
||||||
|
//get validation error results
|
||||||
|
const validResult = validationResult(req);
|
||||||
|
|
||||||
|
//if they're empty
|
||||||
|
if(validResult.isEmpty()){
|
||||||
|
const {command} = matchedData(req);
|
||||||
|
const foundToke = await tokeCommandModel.findOne({command});
|
||||||
|
|
||||||
|
if(foundToke != null){
|
||||||
|
return errorHandler(res, `Toke command '!${command}' already exists!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the toke
|
||||||
|
const tokeDB = await tokeCommandModel.create({command});
|
||||||
|
|
||||||
|
//Return the updated command list
|
||||||
|
res.status(200);
|
||||||
|
return res.send(await tokeCommandModel.getCommandStrings());
|
||||||
|
}else{
|
||||||
|
//otherwise scream
|
||||||
|
res.status(400);
|
||||||
|
return res.send({errors: validResult.array()})
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch(err){
|
||||||
|
return exceptionHandler(res, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
const { Router } = require('express');
|
const { Router } = require('express');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {accountValidator} = require("../../validators/accountValidator");
|
const accountValidator = require("../../validators/accountValidator");
|
||||||
const loginController = require("../../controllers/api/account/loginController");
|
const loginController = require("../../controllers/api/account/loginController");
|
||||||
const logoutController = require("../../controllers/api/account/logoutController");
|
const logoutController = require("../../controllers/api/account/logoutController");
|
||||||
const registerController = require("../../controllers/api/account/registerController");
|
const registerController = require("../../controllers/api/account/registerController");
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,16 @@ const { Router } = require('express');
|
||||||
|
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {accountValidator} = require("../../validators/accountValidator");
|
const accountValidator = require("../../validators/accountValidator");
|
||||||
const {permissionsValidator, channelPermissionValidator} = require("../../validators/permissionsValidator");
|
const {permissionsValidator, channelPermissionValidator} = require("../../validators/permissionsValidator");
|
||||||
|
const tokebotValidator = require("../../validators/tokebotValidator");
|
||||||
const permissionSchema = require("../../schemas/permissionSchema");
|
const permissionSchema = require("../../schemas/permissionSchema");
|
||||||
const listUsersController = require("../../controllers/api/admin/listUsersController");
|
const listUsersController = require("../../controllers/api/admin/listUsersController");
|
||||||
const listChannelsController = require("../../controllers/api/admin/listChannelsController");
|
const listChannelsController = require("../../controllers/api/admin/listChannelsController");
|
||||||
const changeRankController = require("../../controllers/api/admin/changeRankController");
|
const changeRankController = require("../../controllers/api/admin/changeRankController");
|
||||||
const permissionsController = require("../../controllers/api/admin/permissionsController");
|
const permissionsController = require("../../controllers/api/admin/permissionsController");
|
||||||
const banController = require("../../controllers/api/admin/banController");
|
const banController = require("../../controllers/api/admin/banController");
|
||||||
|
const tokeCommandController = require('../../controllers/api/admin/tokeCommandController');
|
||||||
|
|
||||||
//globals
|
//globals
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
@ -42,5 +44,7 @@ router.get('/ban', permissionSchema.reqPermCheck("adminPanel"), banController.g
|
||||||
//Sometimes they're so simple you don't need to put your validators in their own special place :P
|
//Sometimes they're so simple you don't need to put your validators in their own special place :P
|
||||||
router.post('/ban', permissionSchema.reqPermCheck("banUser"), accountValidator.user(), body("permanent").isBoolean(), body("expirationDays").isInt(), banController.post);
|
router.post('/ban', permissionSchema.reqPermCheck("banUser"), accountValidator.user(), body("permanent").isBoolean(), body("expirationDays").isInt(), banController.post);
|
||||||
router.delete('/ban', permissionSchema.reqPermCheck("banUser"), accountValidator.user(), banController.delete);
|
router.delete('/ban', permissionSchema.reqPermCheck("banUser"), accountValidator.user(), banController.delete);
|
||||||
|
router.get('/tokeCommands', permissionSchema.reqPermCheck("adminPanel"), tokeCommandController.get);
|
||||||
|
router.post('/tokeCommands', permissionSchema.reqPermCheck("editTokeCommands"), tokebotValidator.command(), tokeCommandController.post);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ const { Router } = require('express');
|
||||||
//local imports
|
//local imports
|
||||||
const permissionSchema = require("../../schemas/permissionSchema");
|
const permissionSchema = require("../../schemas/permissionSchema");
|
||||||
const channelModel = require("../../schemas/channel/channelSchema");
|
const channelModel = require("../../schemas/channel/channelSchema");
|
||||||
const {channelValidator} = require("../../validators/channelValidator");
|
const channelValidator = require("../../validators/channelValidator");
|
||||||
const {accountValidator} = require("../../validators/accountValidator");
|
const accountValidator = require("../../validators/accountValidator");
|
||||||
const {channelPermissionValidator} = require("../../validators/permissionsValidator");
|
const {channelPermissionValidator} = require("../../validators/permissionsValidator");
|
||||||
const registerController = require("../../controllers/api/channel/registerController");
|
const registerController = require("../../controllers/api/channel/registerController");
|
||||||
const listController = require("../../controllers/api/channel/listController");
|
const listController = require("../../controllers/api/channel/listController");
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,12 @@ const permissionSchema = new mongoose.Schema({
|
||||||
default: "admin",
|
default: "admin",
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
editTokeCommands: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
banUser: {
|
banUser: {
|
||||||
type: mongoose.SchemaTypes.String,
|
type: mongoose.SchemaTypes.String,
|
||||||
enum: rankEnum,
|
enum: rankEnum,
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,15 @@ You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//At some point this will be a bit more advanced, right now it's just a placeholder :P
|
//At some point this will be a bit more advanced, right now it's just a placeholder :P
|
||||||
|
module.exports.errorHandler = function(res, msg, type = "Generic"){
|
||||||
|
res.status(400);
|
||||||
|
return res.send({errors: [{type, msg, date: new Date()}]});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.exceptionHandler = function(res, err){
|
module.exports.exceptionHandler = function(res, err){
|
||||||
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
||||||
res.status(400);
|
res.status(400);
|
||||||
return res.send({errors: [{type: "Caught Exception", msg: err.message, date: new Date()}]});
|
module.exports.errorHandler(res, err.message, "Caught Exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.socketExceptionHandler = function(socket, err){
|
module.exports.socketExceptionHandler = function(socket, err){
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ const { check, body, checkSchema, checkExact} = require('express-validator');
|
||||||
//local imports
|
//local imports
|
||||||
const {isRank} = require('./permissionsValidator');
|
const {isRank} = require('./permissionsValidator');
|
||||||
|
|
||||||
module.exports.accountValidator = {
|
module.exports = {
|
||||||
user: (field = 'user') => body(field).escape().trim().isLength({min: 1, max: 22}),
|
user: (field = 'user') => body(field).escape().trim().isLength({min: 1, max: 22}),
|
||||||
|
|
||||||
//Password security requirements may change over time, therefore we should only validate against strongPassword() when creating new accounts
|
//Password security requirements may change over time, therefore we should only validate against strongPassword() when creating new accounts
|
||||||
//that way we don't break old ones upon change
|
//that way we don't break old ones upon change
|
||||||
pass: (field = 'pass') => body(field).notEmpty().escape().trim(),
|
pass: (field = 'pass') => body(field).notEmpty().escape().trim(),
|
||||||
securePass: (field) => module.exports.accountValidator.pass(field).isStrongPassword({minLength: 8, minLowercase: 1, minUppercase: 1, minNumbers: 1, minSymbols: 1}),
|
securePass: (field) => module.exports.pass(field).isStrongPassword({minLength: 8, minLowercase: 1, minUppercase: 1, minNumbers: 1, minSymbols: 1}),
|
||||||
|
|
||||||
email: (field = 'email') => body(field).optional().isEmail().normalizeEmail(),
|
email: (field = 'email') => body(field).optional().isEmail().normalizeEmail(),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
const { check, body, checkSchema, checkExact} = require('express-validator');
|
const { check, body, checkSchema, checkExact} = require('express-validator');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {accountValidator} = require('./accountValidator');
|
const accountValidator = require('./accountValidator');
|
||||||
|
|
||||||
module.exports.channelValidator = {
|
module.exports = {
|
||||||
name: (field = 'name') => check(field).escape().trim().isLength({min: 1, max: 50}),
|
name: (field = 'name') => check(field).escape().trim().isLength({min: 1, max: 50}),
|
||||||
|
|
||||||
description: (field = 'description') => body(field).escape().trim().isLength({min: 1, max: 1000}),
|
description: (field = 'description') => body(field).escape().trim().isLength({min: 1, max: 1000}),
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ module.exports.permissionsValidator = {
|
||||||
options: module.exports.isRank
|
options: module.exports.isRank
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'permissionsMap.editTokeCommands': {
|
||||||
|
optional: true,
|
||||||
|
custom: {
|
||||||
|
options: module.exports.isRank
|
||||||
|
}
|
||||||
|
},
|
||||||
'permissionsMap.banUser': {
|
'permissionsMap.banUser': {
|
||||||
optional: true,
|
optional: true,
|
||||||
custom: {
|
custom: {
|
||||||
|
|
|
||||||
22
src/validators/tokebotValidator.js
Normal file
22
src/validators/tokebotValidator.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*Canopy - The next generation of stoner streaming software
|
||||||
|
Copyright (C) 2024 Rainbownapkin and the TTN Community
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
|
//NPM Imports
|
||||||
|
const { check } = require('express-validator');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
command: (field = 'command') => check(field).escape().trim().isAlphanumeric().isLength({min: 1, max: 30}),
|
||||||
|
}
|
||||||
|
|
@ -169,6 +169,35 @@ class canopyAdminUtils{
|
||||||
utils.ux.displayResponseError(await response.json());
|
utils.ux.displayResponseError(await response.json());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getTokeCommands(){
|
||||||
|
var response = await fetch(`/api/admin/tokeCommands`,{
|
||||||
|
method: "GET"
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status == 200){
|
||||||
|
return await response.json();
|
||||||
|
}else{
|
||||||
|
utils.ux.displayResponseError(await response.json());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addTokeCommand(command){
|
||||||
|
var response = await fetch(`/api/admin/tokeCommands`,{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
//Unfortunately JSON doesn't natively handle ES6 maps, and god forbid someone update the standard in a way that's backwards compatible...
|
||||||
|
body: JSON.stringify({command})
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status == 200){
|
||||||
|
return await response.json();
|
||||||
|
}else{
|
||||||
|
utils.ux.displayResponseError(await response.json());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class adminUserList{
|
class adminUserList{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue