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
delete permList._id ;
delete permList.channelOverrides._id ;
delete permList.__v;
//Render out the page

View file

@ -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,10 +41,12 @@ 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;
//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)
@ -56,6 +58,21 @@ module.exports.post = async function(req, res){
//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);
}
}

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/>.*/
//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;

View file

@ -27,7 +27,7 @@ module.exports.isRank = function(value){
}
module.exports.permissionsValidator = {
permissionsMap: () => checkExact(checkSchema({
permissionsMap: () => checkSchema({
'permissionsMap.adminPanel': {
optional: true,
custom: {
@ -58,10 +58,11 @@ module.exports.permissionsValidator = {
options: module.exports.isRank
},
}
}))
})
}
module.exports.channelPermissionValidatorSchema = {
module.exports.channelPermissionValidator = {
channelPermissionsMap: () => checkSchema({
'channelPermissionsMap.manageChannel': {
optional: true,
custom: {
@ -74,8 +75,5 @@ module.exports.channelPermissionValidatorSchema = {
options: module.exports.isRank
},
}
}
module.exports.channelPermissionValidator = {
channelPermissionsMap: () => checkExact(checkSchema(module.exports.channelPermissionValidatorSchema))
})
}

View file

@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.-->
<h3>Permissions:</h3>
<field id="admin-perm-list-field" class="admin-list-field">
<% Object.keys(permList).forEach((key)=>{ %>
<% if(key != "channelOverrides"){ %>
<span class="admin-list-field-container">
<label id="admin-perm-list-label-<%- key %>" class="admin-list-label admin-perm-list" for="admin-perm-list-rank-select-<%- key %>"><%- key %>: </label>
<select id="admin-perm-list-rank-select-<%- key %>" name="admin-perm-list-rank-select-<%- key %>" class="admin-list-select admin-perm-list-rank-select">
@ -25,6 +26,20 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.-->
<% }); %>
</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>
</div>

View file

@ -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;
}

View file

@ -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();