Added channel overrides section to admin panel

This commit is contained in:
rainbownapkin 2024-11-23 17:45:19 -05:00
parent 68f9d5af06
commit 33026a1265
7 changed files with 113 additions and 42 deletions

View file

@ -31,6 +31,7 @@ module.exports.get = async function(req, res){
//Clean up perm list :P //Clean up perm list :P
delete permList._id ; delete permList._id ;
delete permList.channelOverrides._id ;
delete permList.__v; delete permList.__v;
//Render out the page //Render out the page

View file

@ -24,7 +24,7 @@ const permissionModel = require('../../../schemas/permissionSchema.js');
//api permissions functions //api permissions functions
module.exports.get = async function(req, res){ module.exports.get = async function(req, res){
try{ try{
const perms = await permissionModel.getPerms(); var perms = await permissionModel.getPerms();
res.status(200); res.status(200);
return res.send(perms); return res.send(perms);
@ -41,21 +41,38 @@ module.exports.post = async function(req, res){
//if none //if none
if(validResult.isEmpty()){ if(validResult.isEmpty()){
//grab validated/sanatized data //grab validated/sanatized data
const {permissionsMap} = matchedData(req); const {permissionsMap, channelPermissionsMap} = matchedData(req);
const perms = await permissionModel.getPerms(); const perms = await permissionModel.getPerms();
var permError = false; var permError = false;
//For each permission submitted //If we're updating normal perms
Object.keys(permissionsMap).forEach((perm) => { if(permissionsMap){
//Check to make sure no one is jumping perms (this should be admins only, but just in-case) //For each permission submitted
//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 Object.keys(permissionsMap).forEach((perm) => {
if(permissionModel.rankToNum(perms[perm]) > permissionModel.rankToNum(req.session.user.rank) || permissionModel.rankToNum(permissionsMap[perm]) > permissionModel.rankToNum(req.session.user.rank)){ //Check to make sure no one is jumping perms (this should be admins only, but just in-case)
permError = true; //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 //Set permissions in the permissions model
perms[perm] = permissionsMap[perm]; 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. //Flip our shit if something's wrong.
if(permError){ if(permError){
@ -69,6 +86,7 @@ module.exports.post = async function(req, res){
var returnObj = perms.toObject(); var returnObj = perms.toObject();
delete returnObj._id delete returnObj._id
delete returnObj.channelOverrides._id
delete returnObj.__v delete returnObj.__v
//send successful response //send successful response
@ -80,6 +98,7 @@ module.exports.post = async function(req, res){
res.send({errors: validResult.array()}) res.send({errors: validResult.array()})
} }
}catch(err){ }catch(err){
console.log(err);
return exceptionHandler(res, err); return exceptionHandler(res, err);
} }
} }

View file

@ -15,12 +15,13 @@ 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/>.*/
//npm imports //npm imports
const { checkExact } = require('express-validator');
const { Router } = require('express'); const { Router } = require('express');
//local imports //local imports
const {accountValidator} = require("../../validators/accountValidator"); const {accountValidator} = require("../../validators/accountValidator");
const {permissionsValidator} = require("../../validators/permissionsValidator"); const {permissionsValidator, channelPermissionValidator} = require("../../validators/permissionsValidator");
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");
@ -37,7 +38,7 @@ router.use(permissionSchema.reqPermCheck("adminAPI"));
router.get('/listUsers', listUsersController.get); router.get('/listUsers', listUsersController.get);
router.get('/listChannels', listChannelsController.get); router.get('/listChannels', listChannelsController.get);
router.get('/permissions', permissionsController.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); router.post('/changeRank', accountValidator.user(), accountValidator.rank(), changeRankController.post);
module.exports = router; module.exports = router;

View file

@ -27,7 +27,7 @@ module.exports.isRank = function(value){
} }
module.exports.permissionsValidator = { module.exports.permissionsValidator = {
permissionsMap: () => checkExact(checkSchema({ permissionsMap: () => checkSchema({
'permissionsMap.adminPanel': { 'permissionsMap.adminPanel': {
optional: true, optional: true,
custom: { custom: {
@ -58,24 +58,22 @@ module.exports.permissionsValidator = {
options: module.exports.isRank 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 = { 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
},
}
})
} }

View file

@ -17,14 +17,29 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.-->
<h3>Permissions:</h3> <h3>Permissions:</h3>
<field id="admin-perm-list-field" class="admin-list-field"> <field id="admin-perm-list-field" class="admin-list-field">
<% Object.keys(permList).forEach((key)=>{ %> <% Object.keys(permList).forEach((key)=>{ %>
<span class="admin-list-field-container"> <% if(key != "channelOverrides"){ %>
<label id="admin-perm-list-label-<%- key %>" class="admin-list-label admin-perm-list" for="admin-perm-list-rank-select-<%- key %>"><%- key %>: </label> <span class="admin-list-field-container">
<select id="admin-perm-list-rank-select-<%- key %>" name="admin-perm-list-rank-select-<%- key %>" class="admin-list-select admin-perm-list-rank-select"> <label id="admin-perm-list-label-<%- key %>" class="admin-list-label admin-perm-list" for="admin-perm-list-rank-select-<%- key %>"><%- key %>: </label>
<%rankEnum.slice().reverse().forEach((rank)=>{ %> <select id="admin-perm-list-rank-select-<%- key %>" name="admin-perm-list-rank-select-<%- key %>" class="admin-list-select admin-perm-list-rank-select">
<option <%if(permList[key] == rank){%> selected <%}%> value="<%- rank %>"><%- rank %></option> <%rankEnum.slice().reverse().forEach((rank)=>{ %>
<% }); %> <option <%if(permList[key] == rank){%> selected <%}%> value="<%- rank %>"><%- rank %></option>
</select> <% }); %>
</span> </select>
</span>
<% } %>
<% }); %>
<h4 class="admin-list-field-container">Channel Overrides:</h4>
<% Object.keys(permList.channelOverrides).forEach((key)=>{ %>
<% if(key != "channelOverrides"){ %>
<span class="admin-list-field-container">
<label id="admin-chan-perm-list-label-<%- key %>" class="admin-list-label admin-chan-perm-list" for="admin-chan-perm-list-rank-select-<%- key %>"><%- key %>: </label>
<select id="admin-chan-perm-list-rank-select-<%- key %>" name="admin-chan-perm-list-rank-select-<%- key %>" class="admin-list-select admin-chan-perm-list-rank-select">
<%rankEnum.slice().reverse().forEach((rank)=>{ %>
<option <%if(permList.channelOverrides[key] == rank){%> selected <%}%> value="<%- rank %>"><%- rank %></option>
<% }); %>
</select>
</span>
<% } %>
<% }); %> <% }); %>
</field> </field>
</div> </div>

View file

@ -68,7 +68,7 @@ img.admin-list-entry-item{
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
.admin-perm-list-rank-select{ .admin-perm-list-rank-select, .admin-chan-perm-list-rank-select{
width: 5em; width: 5em;
margin-left: 1em; margin-left: 1em;
} }

View file

@ -52,6 +52,23 @@ class canopyAdminUtils{
utils.ux.displayResponseError(await response.json()); 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{ class adminUserList{
@ -85,6 +102,7 @@ class adminUserList{
class adminPermissionList{ class adminPermissionList{
constructor(){ constructor(){
this.permissionSelectors = document.querySelectorAll(".admin-perm-list-rank-select"); this.permissionSelectors = document.querySelectorAll(".admin-perm-list-rank-select");
this.channelPermissionSelectors = document.querySelectorAll(".admin-chan-perm-list-rank-select");
this.setupInput(); this.setupInput();
} }
@ -93,6 +111,10 @@ class adminPermissionList{
this.permissionSelectors.forEach((permissionSelector)=>{ this.permissionSelectors.forEach((permissionSelector)=>{
permissionSelector.addEventListener("change", this.setPerm.bind(this)) permissionSelector.addEventListener("change", this.setPerm.bind(this))
}); });
this.channelPermissionSelectors.forEach((permissionSelector)=>{
permissionSelector.addEventListener("change", this.setChanPerm.bind(this))
});
} }
async setPerm(event){ async setPerm(event){
@ -101,12 +123,27 @@ class adminPermissionList{
this.updateSelect(await adminUtil.setPermission(permMap), event.target); 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){ updateSelect(update, select){
if(update != null){ 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]; 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(); const adminUtil = new canopyAdminUtils();