diff --git a/src/controllers/adminPanelController.js b/src/controllers/adminPanelController.js index f4287b6..098f62f 100644 --- a/src/controllers/adminPanelController.js +++ b/src/controllers/adminPanelController.js @@ -31,6 +31,7 @@ module.exports.get = async function(req, res){ //Clean up perm list :P delete permList._id ; + delete permList.channelOverrides._id ; delete permList.__v; //Render out the page diff --git a/src/controllers/api/admin/permissionsController.js b/src/controllers/api/admin/permissionsController.js index d1c8399..86a60f5 100644 --- a/src/controllers/api/admin/permissionsController.js +++ b/src/controllers/api/admin/permissionsController.js @@ -24,7 +24,7 @@ const permissionModel = require('../../../schemas/permissionSchema.js'); //api permissions functions module.exports.get = async function(req, res){ try{ - const perms = await permissionModel.getPerms(); + var perms = await permissionModel.getPerms(); res.status(200); return res.send(perms); @@ -41,21 +41,38 @@ module.exports.post = async function(req, res){ //if none if(validResult.isEmpty()){ //grab validated/sanatized data - const {permissionsMap} = matchedData(req); + const {permissionsMap, channelPermissionsMap} = matchedData(req); const perms = await permissionModel.getPerms(); var permError = false; - //For each permission submitted - Object.keys(permissionsMap).forEach((perm) => { - //Check to make sure no one is jumping perms (this should be admins only, but just in-case) - //Setting a boolean inside of an if statement seems fucked, until you realize it won't set it back false on the next loop :P - if(permissionModel.rankToNum(perms[perm]) > permissionModel.rankToNum(req.session.user.rank) || permissionModel.rankToNum(permissionsMap[perm]) > permissionModel.rankToNum(req.session.user.rank)){ - permError = true; - } + //If we're updating normal perms + if(permissionsMap){ + //For each permission submitted + Object.keys(permissionsMap).forEach((perm) => { + //Check to make sure no one is jumping perms (this should be admins only, but just in-case) + //Setting a boolean inside of an if statement seems fucked, until you realize it won't set it back false on the next loop :P + if(permissionModel.rankToNum(perms[perm]) > permissionModel.rankToNum(req.session.user.rank) || permissionModel.rankToNum(permissionsMap[perm]) > permissionModel.rankToNum(req.session.user.rank)){ + permError = true; + } - //Set permissions in the permissions model - perms[perm] = permissionsMap[perm]; - }); + //Set permissions in the permissions model + perms[perm] = permissionsMap[perm]; + }); + } + + if(channelPermissionsMap){ + //For each permission submitted + Object.keys(channelPermissionsMap).forEach((perm) => { + //Check to make sure no one is jumping perms (this should be admins only, but just in-case) + //Setting a boolean inside of an if statement seems fucked, until you realize it won't set it back false on the next loop :P + if(permissionModel.rankToNum(perms.channelOverrides[perm]) > permissionModel.rankToNum(req.session.user.rank) || permissionModel.rankToNum(channelPermissionsMap[perm]) > permissionModel.rankToNum(req.session.user.rank)){ + permError = true; + } + + //Set permissions in the permissions model + perms.channelOverrides[perm] = channelPermissionsMap[perm]; + }); + } //Flip our shit if something's wrong. if(permError){ @@ -69,6 +86,7 @@ module.exports.post = async function(req, res){ var returnObj = perms.toObject(); delete returnObj._id + delete returnObj.channelOverrides._id delete returnObj.__v //send successful response @@ -80,6 +98,7 @@ module.exports.post = async function(req, res){ res.send({errors: validResult.array()}) } }catch(err){ + console.log(err); return exceptionHandler(res, err); } } \ No newline at end of file diff --git a/src/routers/api/adminRouter.js b/src/routers/api/adminRouter.js index fa848d3..771c582 100644 --- a/src/routers/api/adminRouter.js +++ b/src/routers/api/adminRouter.js @@ -15,12 +15,13 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see .*/ //npm imports +const { checkExact } = require('express-validator'); const { Router } = require('express'); //local imports const {accountValidator} = require("../../validators/accountValidator"); -const {permissionsValidator} = require("../../validators/permissionsValidator"); +const {permissionsValidator, channelPermissionValidator} = require("../../validators/permissionsValidator"); const permissionSchema = require("../../schemas/permissionSchema"); const listUsersController = require("../../controllers/api/admin/listUsersController"); const listChannelsController = require("../../controllers/api/admin/listChannelsController"); @@ -37,7 +38,7 @@ router.use(permissionSchema.reqPermCheck("adminAPI")); router.get('/listUsers', listUsersController.get); router.get('/listChannels', listChannelsController.get); router.get('/permissions', permissionsController.get); -router.post('/permissions', permissionsValidator.permissionsMap(), permissionsController.post); +router.post('/permissions', checkExact([permissionsValidator.permissionsMap(), channelPermissionValidator.channelPermissionsMap()]), permissionsController.post); router.post('/changeRank', accountValidator.user(), accountValidator.rank(), changeRankController.post); module.exports = router; diff --git a/src/validators/permissionsValidator.js b/src/validators/permissionsValidator.js index 3ffa3b6..af8108d 100644 --- a/src/validators/permissionsValidator.js +++ b/src/validators/permissionsValidator.js @@ -27,7 +27,7 @@ module.exports.isRank = function(value){ } module.exports.permissionsValidator = { - permissionsMap: () => checkExact(checkSchema({ + permissionsMap: () => checkSchema({ 'permissionsMap.adminPanel': { optional: true, custom: { @@ -58,24 +58,22 @@ module.exports.permissionsValidator = { options: module.exports.isRank }, } - })) -} - -module.exports.channelPermissionValidatorSchema = { - 'channelPermissionsMap.manageChannel': { - optional: true, - custom: { - options: module.exports.isRank - }, - }, - 'channelPermissionsMap.deleteChannel': { - optional: true, - custom: { - options: module.exports.isRank - }, - } + }) } module.exports.channelPermissionValidator = { - channelPermissionsMap: () => checkExact(checkSchema(module.exports.channelPermissionValidatorSchema)) + channelPermissionsMap: () => checkSchema({ + 'channelPermissionsMap.manageChannel': { + optional: true, + custom: { + options: module.exports.isRank + }, + }, + 'channelPermissionsMap.deleteChannel': { + optional: true, + custom: { + options: module.exports.isRank + }, + } + }) } \ No newline at end of file diff --git a/src/views/partial/adminPanel/permList.ejs b/src/views/partial/adminPanel/permList.ejs index f7f0d8c..e2654a7 100644 --- a/src/views/partial/adminPanel/permList.ejs +++ b/src/views/partial/adminPanel/permList.ejs @@ -17,14 +17,29 @@ along with this program. If not, see .-->

Permissions:

<% Object.keys(permList).forEach((key)=>{ %> - - - - + <% if(key != "channelOverrides"){ %> + + + + + <% } %> + <% }); %> +

Channel Overrides:

+ <% Object.keys(permList.channelOverrides).forEach((key)=>{ %> + <% if(key != "channelOverrides"){ %> + + + + + <% } %> <% }); %>
\ No newline at end of file diff --git a/www/css/adminPanel.css b/www/css/adminPanel.css index 5f51e4c..cc77166 100644 --- a/www/css/adminPanel.css +++ b/www/css/adminPanel.css @@ -68,7 +68,7 @@ img.admin-list-entry-item{ margin-bottom: 0.5em; } -.admin-perm-list-rank-select{ +.admin-perm-list-rank-select, .admin-chan-perm-list-rank-select{ width: 5em; margin-left: 1em; } diff --git a/www/js/adminPanel.js b/www/js/adminPanel.js index 3d0f9e2..da8a4a3 100644 --- a/www/js/adminPanel.js +++ b/www/js/adminPanel.js @@ -52,6 +52,23 @@ class canopyAdminUtils{ utils.ux.displayResponseError(await response.json()); } } + + async setChannelOverride(permMap){ + var response = await fetch(`/api/admin/permissions`,{ + 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({channelPermissionsMap: Object.fromEntries(permMap)}) + }); + + if(response.status == 200){ + return await response.json(); + }else{ + utils.ux.displayResponseError(await response.json()); + } + } } class adminUserList{ @@ -85,6 +102,7 @@ class adminUserList{ class adminPermissionList{ constructor(){ this.permissionSelectors = document.querySelectorAll(".admin-perm-list-rank-select"); + this.channelPermissionSelectors = document.querySelectorAll(".admin-chan-perm-list-rank-select"); this.setupInput(); } @@ -93,6 +111,10 @@ class adminPermissionList{ this.permissionSelectors.forEach((permissionSelector)=>{ permissionSelector.addEventListener("change", this.setPerm.bind(this)) }); + + this.channelPermissionSelectors.forEach((permissionSelector)=>{ + permissionSelector.addEventListener("change", this.setChanPerm.bind(this)) + }); } async setPerm(event){ @@ -101,12 +123,27 @@ class adminPermissionList{ this.updateSelect(await adminUtil.setPermission(permMap), event.target); } + async setChanPerm(event){ + const permMap = new Map([[event.target.id.replace("admin-chan-perm-list-rank-select-",""), event.target.value]]); + + this.updateChanSelect(await adminUtil.setChannelOverride(permMap), event.target); + } + updateSelect(update, select){ if(update != null){ - const perm = select.id.replace("admin-perm-list-rank-select-",""); + var perm = select.id.replace("admin-perm-list-rank-select-",""); + select.value = update[perm]; } } + + updateChanSelect(update, select){ + if(update != null){ + var perm = select.id.replace("admin-chan-perm-list-rank-select-",""); + + select.value = update.channelOverrides[perm]; + } + } } const adminUtil = new canopyAdminUtils();