/*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'); //Local Imports const {userSchema} = require('./userSchema'); const userBanSchema = new mongoose.Schema({ user: { type: mongoose.SchemaTypes.ObjectID, required: true, ref: "user" }, //To be used in future when ip-hashing/better session tracking is implemented ips: { type: [mongoose.SchemaTypes.String], required: false }, //To be used in future when alt-detection has been implemented alts: { type: [userSchema], required: false }, banDate: { type: mongoose.SchemaTypes.Date, required: true, default: new Date() }, expirationDays: { type: mongoose.SchemaTypes.Number, required: true, default: 30 }, //If true, then expiration date deletes associated accounts instead of deleting the ban record permanent: { type: mongoose.SchemaTypes.Boolean, required: true, default: false } }); userBanSchema.statics.checkBanByUserDoc = async function(userDB){ const banDB = await this.find({}); var foundBan = null; banDB.forEach((ban) => { if(ban.user.toString() == userDB._id.toString()){ foundBan = ban; } }); return foundBan; } userBanSchema.statics.checkBan = async function(user){ const userDB = await userModel.findOne({user: user.user}); return this.checkBanByUserDoc(userDB); } userBanSchema.statics.banByUserDoc = async function(userDB, permanent, expirationDays){ //Prevent missing users if(userDB == null){ throw new Error("User not found") } //Ensure the user isn't already banned if(await this.checkBanByUserDoc(userDB) != null){ throw new Error("User already banned"); } if(expirationDays < 0){ throw new Error("Expiration Days must be a positive integer!"); }else if(expirationDays < 30 && permanent){ throw new Error("Permanent bans must be given at least 30 days before automatic account deletion!"); }else if(expirationDays > 185){ throw new Error("Expiration/Deletion date cannot be longer than half a year out from the original ban date."); } //Log the user out await userDB.killAllSessions(); //Add the ban to the database return await this.create({user: userDB._id, permanent, expirationDays}); } userBanSchema.statics.ban = async function(user, permanent, expirationDays){ const userDB = await userModel.findOne({user: user.user}); return this.banByUserDoc(userDB, permanent, expirationDays); } userBanSchema.statics.unbanByUserDoc = async function(userDB){ //Prevent missing users if(userDB == null){ throw new Error("User not found") } const ban = await this.checkBanByUserDoc(userDB); if(!ban){ throw new Error("User already un-banned"); } //Use _id in-case mongoose wants to be a cunt var oldBan = await this.deleteOne({_id: ban._id}); return oldBan; } userBanSchema.statics.unban = async function(user){ const userDB = await userModel.findOne({user: user.user}); return this.unbanByUserDoc(userDB); } userBanSchema.statics.getBans = async function(){ const banDB = await this.find({}).populate('user'); var bans = []; banDB.forEach((ban) => { //Calcualte expiration date var expirationDate = new Date(ban.banDate); expirationDate.setDate(expirationDate.getDate() + ban.expirationDays); const userObj = { id: ban.user.id, user: ban.user.user, img: ban.user.img, date: ban.user.date } const banObj = { banDate: ban.banDate, expirationDays: ban.expirationDays, expirationDate: expirationDate, user: userObj, ips: ban.ips, alts: ban.alts, permanent: ban.permanent } bans.push(banObj); }); return bans; } //methods userBanSchema.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 = mongoose.model("userBan", userBanSchema);