diff --git a/src/app/channel/channelManager.js b/src/app/channel/channelManager.js
index 894cc4c..8e03b87 100644
--- a/src/app/channel/channelManager.js
+++ b/src/app/channel/channelManager.js
@@ -46,6 +46,19 @@ module.exports = class{
//Get the active channel based on the socket
var {activeChan, chanDB} = await this.getActiveChan(socket);
+ //Check for ban
+ const ban = await chanDB.checkBanByUserDoc(userDB);
+ if(ban != null){
+ //Toss out banned user's
+ if(ban.expirationDays < 0){
+ socket.emit("kick", {type: "Unauthorized", reason: "You have been permanently banned from this channel!"});
+ }else{
+ socket.emit("kick", {type: "Unauthorized", reason: `You have been temporarily banned from this channel, and will be unbanned in ${ban.getDaysUntilExpiration()} day(s)!`});
+ }
+ socket.disconnect();
+ return;
+ }
+
//Define listeners
this.defineListeners(socket);
this.chatHandler.defineListeners(socket);
diff --git a/src/controllers/popup/channelUserBanController.js b/src/controllers/popup/channelUserBanController.js
new file mode 100644
index 0000000..20b7ae1
--- /dev/null
+++ b/src/controllers/popup/channelUserBanController.js
@@ -0,0 +1,20 @@
+/*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 .*/
+
+//root index functions
+module.exports.get = async function(req, res){
+ res.render('partial/popup/channelUserBan');
+}
\ No newline at end of file
diff --git a/src/routers/popupRouter.js b/src/routers/popupRouter.js
index 5d92616..a0efa78 100644
--- a/src/routers/popupRouter.js
+++ b/src/routers/popupRouter.js
@@ -21,6 +21,7 @@ const { Router } = require('express');
//local imports
const placeholderController = require("../controllers/popup/placeholderController");
const userBanController = require("../controllers/popup/userBanController");
+const channelUserBanController = require("../controllers/popup/channelUserBanController");
//globals
const router = Router();
@@ -28,5 +29,6 @@ const router = Router();
//routing functions
router.get('/placeholder', placeholderController.get);
router.get('/userBan', userBanController.get);
+router.get('/channelUserBan', channelUserBanController.get);
module.exports = router;
diff --git a/src/schemas/channel/channelBanSchema.js b/src/schemas/channel/channelBanSchema.js
new file mode 100644
index 0000000..bb5ab70
--- /dev/null
+++ b/src/schemas/channel/channelBanSchema.js
@@ -0,0 +1,53 @@
+/*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 .*/
+
+//NPM Imports
+const {mongoose} = require('mongoose');
+
+const channelBanSchema = new mongoose.Schema({
+ user: {
+ type: mongoose.SchemaTypes.ObjectID,
+ required: true,
+ ref: "user"
+ },
+ banDate: {
+ type: mongoose.SchemaTypes.Date,
+ required: true,
+ default: new Date()
+ },
+ expirationDays: {
+ type: mongoose.SchemaTypes.Number,
+ required: true,
+ default: 14
+ },
+ banAlts: {
+ type: mongoose.SchemaTypes.Boolean,
+ required: true,
+ default: false
+ }
+});
+
+//methods
+channelBanSchema.methods.getDaysUntilExpiration = function(){
+ //Get ban date
+ const expirationDate = new Date(this.banDate);
+ //Get expiration days and calculate expiration date
+ expirationDate.setDate(expirationDate.getDate() + this.expirationDays);
+ //Calculate and return days until ban expiration
+ return ((expirationDate - new Date()) / (1000 * 60 * 60 * 24)).toFixed(1);
+}
+
+module.exports = channelBanSchema;
\ No newline at end of file
diff --git a/src/schemas/channel/channelSchema.js b/src/schemas/channel/channelSchema.js
index 2d35ac0..7b2f281 100644
--- a/src/schemas/channel/channelSchema.js
+++ b/src/schemas/channel/channelSchema.js
@@ -19,11 +19,12 @@ const {mongoose} = require('mongoose');
const {validationResult, matchedData} = require('express-validator');
//Local Imports
-const statModel = require('../statSchema.js');
-const {userModel} = require('../userSchema.js');
-const permissionModel = require('../permissionSchema.js');
-const channelPermissionSchema = require('./channelPermissionSchema.js');
-const { exceptionHandler } = require('../../utils/loggerUtils.js');
+const statModel = require('../statSchema');
+const {userModel} = require('../userSchema');
+const permissionModel = require('../permissionSchema');
+const channelPermissionSchema = require('./channelPermissionSchema');
+const channelBanSchema = require('./channelBanSchema');
+const { exceptionHandler } = require('../../utils/loggerUtils');
const channelSchema = new mongoose.Schema({
id: {
@@ -69,28 +70,7 @@ const channelSchema = new mongoose.Schema({
}
}],
//Thankfully we don't have to keep track of alts, ips, or deleted users so this should be a little easier :P
- banList: [{
- user: {
- type: mongoose.SchemaTypes.ObjectID,
- required: true,
- ref: "user"
- },
- banDate: {
- type: mongoose.SchemaTypes.Date,
- required: true,
- default: new Date()
- },
- expirationDays: {
- type: mongoose.SchemaTypes.Number,
- required: true,
- default: 14
- },
- banAlts: {
- type: mongoose.SchemaTypes.Boolean,
- required: true,
- default: false
- }
- }]
+ banList: [channelBanSchema]
});
@@ -194,6 +174,21 @@ channelSchema.statics.reqPermCheck = function(perm, chanField = "chanName"){
}
}
+channelSchema.statics.processExpiredBans = async function(){
+ const chanDB = await this.find({});
+
+ chanDB.forEach((channel) => {
+ channel.banList.forEach(async (ban, i) => {
+ //ignore permanent and non-expired bans
+ if(ban.expirationDays >= 0 && ban.getDaysUntilExpiration() <= 0){
+ //Get the index of the ban
+ channel.banList.splice(i,1);
+ return await channel.save();
+ }
+ })
+ });
+}
+
//methods
channelSchema.methods.updateSettings = async function(settingsMap){
settingsMap.forEach((value, key) => {
@@ -372,6 +367,7 @@ channelSchema.methods.getChanBans = async function(){
var banObj = {
banDate: ban.banDate,
expirationDays: ban.expirationDays,
+ banAlts: ban.banAlts,
}
//Check if the ban was permanent (expiration set before ban date)
@@ -382,6 +378,7 @@ channelSchema.methods.getChanBans = async function(){
//Set calculated expiration date
banObj.expirationDate = expirationDate;
+ banObj.daysUntilExpiration = ban.getDaysUntilExpiration();
}
//Setup user object (Do this last to keep it at bottom for human-readibility of json :P)
diff --git a/src/schemas/userBanSchema.js b/src/schemas/userBanSchema.js
index df0fb04..5e8ea80 100644
--- a/src/schemas/userBanSchema.js
+++ b/src/schemas/userBanSchema.js
@@ -196,6 +196,7 @@ userBanSchema.statics.getBans = async function(){
banDate: ban.banDate,
expirationDays: ban.expirationDays,
expirationDate: expirationDate,
+ daysUntilExpiration: ban.getDaysUntilExpiration(),
user: userObj,
ips: ban.ips,
alts: ban.alts,
@@ -247,7 +248,7 @@ userBanSchema.methods.getDaysUntilExpiration = function(){
//Get expiration days and calculate expiration date
expirationDate.setDate(expirationDate.getDate() + this.expirationDays);
//Calculate and return days until ban expiration
- return daysUntilExpiraiton = ((expirationDate - new Date()) / (1000 * 60 * 60 * 24)).toFixed(1);
+ return ((expirationDate - new Date()) / (1000 * 60 * 60 * 24)).toFixed(1);
}
module.exports = mongoose.model("userBan", userBanSchema);
\ No newline at end of file
diff --git a/src/utils/scheduler.js b/src/utils/scheduler.js
index 8a5d881..840ee14 100644
--- a/src/utils/scheduler.js
+++ b/src/utils/scheduler.js
@@ -18,9 +18,20 @@ along with this program. If not, see .*/
const cron = require('node-cron');
//Local Imports
-const userBanSchema = require('../schemas/userBanSchema');
+const userBanModel = require('../schemas/userBanSchema');
+const channelModel = require('../schemas/channel/channelSchema');
+
+module.exports.schedule = function(){
+ //Process expired global bans every night at midnight
+ cron.schedule('0 0 * * *', ()=>{userBanModel.processExpiredBans()},{scheduled: true, timezone: "UTC"});
+}
module.exports.kickoff = function(){
- //Process expired bans every night at midnight
- cron.schedule('0 0 * * *', ()=>{userBanSchema.processExpiredBans()},{scheduled: true, timezone: "UTC"});
+ //Process expired global bans that may have expired since last restart
+ userBanModel.processExpiredBans()
+ //Process expired channel bans that may haven ot expired since last restart
+ channelModel.processExpiredBans();
+
+ //Schedule jobs
+ module.exports.schedule();
}
\ No newline at end of file
diff --git a/src/views/adminPanel.ejs b/src/views/adminPanel.ejs
index 7c4aa62..f338d09 100644
--- a/src/views/adminPanel.ejs
+++ b/src/views/adminPanel.ejs
@@ -23,10 +23,12 @@ along with this program. If not, see .-->