Created channel perms schema and api routes.
This commit is contained in:
parent
9dbbc4e924
commit
8384e732f3
|
|
@ -15,7 +15,7 @@ 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/>.*/
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
const channelModel = require('../../schemas/channelSchema');
|
const channelModel = require('../../schemas/channel/channelSchema');
|
||||||
const flairModel = require('../../schemas/flairSchema');
|
const flairModel = require('../../schemas/flairSchema');
|
||||||
const userModel = require('../../schemas/userSchema');
|
const userModel = require('../../schemas/userSchema');
|
||||||
const loggerUtils = require('../../utils/loggerUtils');
|
const loggerUtils = require('../../utils/loggerUtils');
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
const config = require('../../config.json');
|
const config = require('../../config.json');
|
||||||
const userModel = require('../schemas/userSchema');
|
const userModel = require('../schemas/userSchema');
|
||||||
const permissionModel = require('../schemas/permissionSchema');
|
const permissionModel = require('../schemas/permissionSchema');
|
||||||
const channelModel = require('../schemas/channelSchema');
|
const channelModel = require('../schemas/channel/channelSchema');
|
||||||
const {exceptionHandler} = require("../utils/loggerUtils");
|
const {exceptionHandler} = require("../utils/loggerUtils");
|
||||||
|
|
||||||
//register page functions
|
//register page functions
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
||||||
const channelModel = require('../../../schemas/channelSchema.js');
|
const channelModel = require('../../../schemas/channel/channelSchema.js');
|
||||||
|
|
||||||
//api list channel functions
|
//api list channel functions
|
||||||
module.exports.get = async function(req, res){
|
module.exports.get = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const {validationResult, matchedData} = require('express-validator');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
||||||
const channelModel = require('../../../schemas/channelSchema');
|
const channelModel = require('../../../schemas/channel/channelSchema');
|
||||||
|
|
||||||
//api account functions
|
//api account functions
|
||||||
module.exports.post = async function(req, res){
|
module.exports.post = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ 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/>.*/
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const channelModel = require('../../../schemas/channelSchema');
|
const channelModel = require('../../../schemas/channel/channelSchema');
|
||||||
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
||||||
|
|
||||||
//api account functions
|
//api account functions
|
||||||
|
|
|
||||||
73
src/controllers/api/channel/permissionsController.js
Normal file
73
src/controllers/api/channel/permissionsController.js
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*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} = require('../../../utils/loggerUtils.js');
|
||||||
|
const channelModel = require('../../../schemas/channel/channelSchema.js');
|
||||||
|
|
||||||
|
//api account functions
|
||||||
|
module.exports.get = async function(req, res){
|
||||||
|
try{
|
||||||
|
const validResult = validationResult(req);
|
||||||
|
|
||||||
|
if(validResult.isEmpty()){
|
||||||
|
const data = matchedData(req);
|
||||||
|
const channel = await channelModel.findOne({name: data.chanName});
|
||||||
|
|
||||||
|
|
||||||
|
if(channel == null){
|
||||||
|
throw new Error("Channel not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200);
|
||||||
|
return res.send(channel.permissions);
|
||||||
|
}else{
|
||||||
|
res.status(400);
|
||||||
|
res.send({errors: validResult.array()})
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
exceptionHandler(res, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.post = async function(req, res){
|
||||||
|
try{
|
||||||
|
const validResult = validationResult(req);
|
||||||
|
|
||||||
|
if(validResult.isEmpty()){
|
||||||
|
const data = matchedData(req);
|
||||||
|
const channel = await channelModel.findOne({name: data.chanName});
|
||||||
|
const permissionsMap = new Map(Object.entries(data.channelPermissionsMap));
|
||||||
|
|
||||||
|
if(channel == null){
|
||||||
|
throw new Error("Channel not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200);
|
||||||
|
return res.send(await channel.updateChannelPerms(permissionsMap));
|
||||||
|
}else{
|
||||||
|
res.status(400);
|
||||||
|
res.send({errors: validResult.array()})
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
exceptionHandler(res, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ const {validationResult, matchedData} = require('express-validator');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
||||||
const channelModel = require('../../../schemas/channelSchema');
|
const channelModel = require('../../../schemas/channel/channelSchema');
|
||||||
|
|
||||||
//api account functions
|
//api account functions
|
||||||
module.exports.post = async function(req, res){
|
module.exports.post = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const {validationResult, matchedData} = require('express-validator');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../../../utils/loggerUtils.js');
|
||||||
const channelModel = require('../../../schemas/channelSchema');
|
const channelModel = require('../../../schemas/channel/channelSchema');
|
||||||
|
|
||||||
//api account functions
|
//api account functions
|
||||||
module.exports.get = async function(req, res){
|
module.exports.get = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const config = require('../../config.json');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../utils/loggerUtils.js');
|
||||||
const channelModel = require('../schemas/channelSchema');
|
const channelModel = require('../schemas/channel/channelSchema');
|
||||||
|
|
||||||
//root index functions
|
//root index functions
|
||||||
module.exports.get = async function(req, res){
|
module.exports.get = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const config = require('../../config.json');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const {exceptionHandler} = require('../utils/loggerUtils.js');
|
const {exceptionHandler} = require('../utils/loggerUtils.js');
|
||||||
const channelModel = require('../schemas/channelSchema');
|
const channelModel = require('../schemas/channel/channelSchema');
|
||||||
|
|
||||||
//root index functions
|
//root index functions
|
||||||
module.exports.get = async function(req, res){
|
module.exports.get = async function(req, res){
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ 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} = 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");
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,12 @@ const { Router } = require('express');
|
||||||
|
|
||||||
//local imports
|
//local imports
|
||||||
const permissionSchema = require("../../schemas/permissionSchema");
|
const permissionSchema = require("../../schemas/permissionSchema");
|
||||||
const channelValidator = require("../../validators/channelValidator");
|
const {channelValidator} = require("../../validators/channelValidator");
|
||||||
|
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");
|
||||||
const settingsController = require("../../controllers/api/channel/settingsController");
|
const settingsController = require("../../controllers/api/channel/settingsController");
|
||||||
|
const permissionsController = require("../../controllers/api/channel/permissionsController")
|
||||||
const deleteController = require("../../controllers/api/channel/deleteController");
|
const deleteController = require("../../controllers/api/channel/deleteController");
|
||||||
|
|
||||||
//globals
|
//globals
|
||||||
|
|
@ -38,6 +40,8 @@ router.post('/register', channelValidator.name(), channelValidator.description()
|
||||||
router.get('/list', listController.get);
|
router.get('/list', listController.get);
|
||||||
router.get('/settings', channelValidator.name('chanName'), settingsController.get);
|
router.get('/settings', channelValidator.name('chanName'), settingsController.get);
|
||||||
router.post('/settings', channelValidator.name('chanName'), channelValidator.settingsMap(), settingsController.post);
|
router.post('/settings', channelValidator.name('chanName'), channelValidator.settingsMap(), settingsController.post);
|
||||||
|
router.get('/permissions', channelValidator.name('chanName'), permissionsController.get);
|
||||||
|
router.post('/permissions', channelValidator.name('chanName'), channelPermissionValidator.channelPermissionsMap(), permissionsController.post);
|
||||||
router.post('/delete', channelValidator.name('chanName'), channelValidator.name('confirm'),deleteController.post);
|
router.post('/delete', channelValidator.name('chanName'), channelValidator.name('confirm'),deleteController.post);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
43
src/schemas/channel/channelPermissionSchema.js
Normal file
43
src/schemas/channel/channelPermissionSchema.js
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*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 {mongoose} = require('mongoose');
|
||||||
|
|
||||||
|
//This originally belonged to the permissionSchema, but this avoids circular dependencies.
|
||||||
|
const rankEnum = ["anon", "user", "gold", "bot", "mod", "admin"];
|
||||||
|
|
||||||
|
//Since this is intended to be used as a child schema for multiple parent schemas, we won't export it as a model
|
||||||
|
const channelPermissionSchema = new mongoose.Schema({
|
||||||
|
manageChannel: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
deleteChannel: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Only putting the rank enum out, all other logic should be handled by channelSchema methods to avoid circular dependencies
|
||||||
|
//Alternatively if things get to big we can make it it's own util.
|
||||||
|
channelPermissionSchema.statics.rankEnum = rankEnum;
|
||||||
|
|
||||||
|
module.exports = channelPermissionSchema;
|
||||||
|
|
@ -18,7 +18,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
const {mongoose} = require('mongoose');
|
const {mongoose} = require('mongoose');
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
const statSchema = require('./statSchema.js');
|
const statModel = require('../statSchema.js');
|
||||||
|
const permissionModel = require('../permissionSchema.js');
|
||||||
|
const channelPermissionSchema = require('./channelPermissionSchema.js');
|
||||||
|
|
||||||
const channelSchema = new mongoose.Schema({
|
const channelSchema = new mongoose.Schema({
|
||||||
id: {
|
id: {
|
||||||
|
|
@ -45,10 +47,27 @@ const channelSchema = new mongoose.Schema({
|
||||||
type: mongoose.SchemaTypes.Boolean,
|
type: mongoose.SchemaTypes.Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
permissions: {
|
||||||
|
type: channelPermissionSchema,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
rankList: [{
|
||||||
|
user: {
|
||||||
|
type: mongoose.SchemaTypes.ObjectID,
|
||||||
|
required: true,
|
||||||
|
ref: "user"
|
||||||
|
},
|
||||||
|
rank: {
|
||||||
|
type: mongoose.SchemaTypes.Boolean,
|
||||||
|
required: true,
|
||||||
|
enum: permissionModel.rankEnum
|
||||||
}
|
}
|
||||||
}
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
channelSchema.pre('save', async function (next){
|
channelSchema.pre('save', async function (next){
|
||||||
if(this.isModified("name")){
|
if(this.isModified("name")){
|
||||||
if(this.name.match(/^[a-z0-9_\-.]+$/i) == null){
|
if(this.name.match(/^[a-z0-9_\-.]+$/i) == null){
|
||||||
|
|
@ -68,7 +87,7 @@ channelSchema.statics.register = async function(channelObj){
|
||||||
if(chanDB){
|
if(chanDB){
|
||||||
throw new Error("Channel name already taken!");
|
throw new Error("Channel name already taken!");
|
||||||
}else{
|
}else{
|
||||||
const id = await statSchema.incrementChannelCount();
|
const id = await statModel.incrementChannelCount();
|
||||||
const newChannel = await this.create((thumbnail ? {id, name, description, thumbnail} : {id, name, description}));
|
const newChannel = await this.create((thumbnail ? {id, name, description, thumbnail} : {id, name, description}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +128,46 @@ channelSchema.methods.updateSettings = async function(settingsMap){
|
||||||
return this.settings;
|
return this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channelSchema.methods.updateChannelPerms = async function(permissionsMap){
|
||||||
|
permissionsMap.forEach((value, key) => {
|
||||||
|
if(this.permissions[key] == null){
|
||||||
|
throw new Error("Invalid channel permission.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.permissions[key] = value;
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.save();
|
||||||
|
|
||||||
|
return this.permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelSchema.methods.channelPermCheck = async function(user, perm){
|
||||||
|
const perms = await permissionSchema.getPerms();
|
||||||
|
|
||||||
|
//Set user to anon rank if no rank was found for the given user
|
||||||
|
if(user == null || user.rank == null){
|
||||||
|
user ={
|
||||||
|
rank: "anon"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if this permission exists
|
||||||
|
if(this.permissions[perm] != null){
|
||||||
|
//if so get required rank as a number
|
||||||
|
requiredRank = permissionModel.rankToNum(this[perm]);
|
||||||
|
//get the required site-wide rank to override channel perms
|
||||||
|
requiredOverrideRank = permissionModel.rankToNum(perms.channeOverrides[perm]);
|
||||||
|
|
||||||
|
//get user site rank as a number
|
||||||
|
userRank = user ? permissionModel.rankToNum(user.rank) : 0;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
//if not scream and shout
|
||||||
|
throw new Error(`Permission check '${perm}' not found!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
channelSchema.methods.nuke = async function(confirm){
|
channelSchema.methods.nuke = async function(confirm){
|
||||||
if(confirm == "" || confirm == null){
|
if(confirm == "" || confirm == null){
|
||||||
throw new Error("Empty Confirmation String!");
|
throw new Error("Empty Confirmation String!");
|
||||||
|
|
@ -17,7 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
const {mongoose} = require('mongoose');
|
const {mongoose} = require('mongoose');
|
||||||
|
|
||||||
const rankEnum = ["anon","user", "gold", "bot", "mod", "admin"];
|
//Local Imports
|
||||||
|
const channelPermissionSchema = require('./channel/channelPermissionSchema');
|
||||||
|
|
||||||
|
//This originally belonged to the permissionSchema, but this avoids circular dependencies.
|
||||||
|
//We could update all references but quite honestly I that would be uglier, this should have a copy too...
|
||||||
|
const rankEnum = channelPermissionSchema.statics.rankEnum;
|
||||||
|
|
||||||
const permissionSchema = new mongoose.Schema({
|
const permissionSchema = new mongoose.Schema({
|
||||||
adminPanel: {
|
adminPanel: {
|
||||||
|
|
@ -50,6 +55,10 @@ const permissionSchema = new mongoose.Schema({
|
||||||
default: "admin",
|
default: "admin",
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
channelOverrides: {
|
||||||
|
type: channelPermissionSchema,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Statics
|
//Statics
|
||||||
|
|
@ -108,6 +117,7 @@ permissionSchema.statics.permCheck = async function(user, perm){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Middleware for rank checks
|
||||||
permissionSchema.statics.reqPermCheck = function(perm){
|
permissionSchema.statics.reqPermCheck = function(perm){
|
||||||
return async (req, res, next)=>{
|
return async (req, res, next)=>{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
module.exports.accountValidator = {
|
||||||
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.pass(field).isStrongPassword({minLength: 8, minLowercase: 1, minUppercase: 1, minNumbers: 1, minSymbols: 1}),
|
securePass: (field) => module.exports.accountValidator.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 = {
|
module.exports.channelValidator = {
|
||||||
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}),
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,22 @@ module.exports.permissionsValidator = {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
@ -157,6 +157,8 @@ p.panel-head-element{
|
||||||
|
|
||||||
#chat-panel-flair-select{
|
#chat-panel-flair-select{
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
|
text-align: center;
|
||||||
|
appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input#chat-panel-prompt{
|
input#chat-panel-prompt{
|
||||||
|
|
@ -176,6 +178,7 @@ input#chat-panel-prompt{
|
||||||
|
|
||||||
.chat-entry-username{
|
.chat-entry-username{
|
||||||
margin: 0.2em;
|
margin: 0.2em;
|
||||||
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-entry-body{
|
.chat-entry-body{
|
||||||
|
|
@ -184,6 +187,7 @@ input#chat-panel-prompt{
|
||||||
|
|
||||||
.chat-entry-high-level{
|
.chat-entry-high-level{
|
||||||
margin: 0.2em;
|
margin: 0.2em;
|
||||||
|
margin-right: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background-image: url("/img/sweet_leaf_simple.png");
|
background-image: url("/img/sweet_leaf_simple.png");
|
||||||
background-size: 1.3em;
|
background-size: 1.3em;
|
||||||
|
|
@ -192,6 +196,7 @@ input#chat-panel-prompt{
|
||||||
background-position-y: top;
|
background-position-y: top;
|
||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-entry-high-level-img{
|
.chat-entry-high-level-img{
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,23 @@ class canopyAjaxUtils{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setChannelPermissions(chanName, permissionsMap){
|
||||||
|
var response = await fetch(`/api/channel/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({chanName, channelPermissionsMap: Object.fromEntries(permissionsMap)})
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.status == 200){
|
||||||
|
return await response.json();
|
||||||
|
}else{
|
||||||
|
utils.ux.displayResponseError(await response.json());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async deleteChannel(chanName, confirm){
|
async deleteChannel(chanName, confirm){
|
||||||
var response = await fetch(`/api/channel/delete`,{
|
var response = await fetch(`/api/channel/delete`,{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue