Improved exception handling, started work on improving error messages for IP bans
This commit is contained in:
parent
7d3c31f0aa
commit
853f67fe15
|
|
@ -122,7 +122,7 @@ module.exports = class{
|
||||||
const userDB = await userModel.findOne({user: socket.request.session.user.user});
|
const userDB = await userModel.findOne({user: socket.request.session.user.user});
|
||||||
|
|
||||||
if(userDB == null){
|
if(userDB == null){
|
||||||
throw new Error("User not found!");
|
throw loggerUtils.exceptionSmith("User not found!", "unauthorized");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set socket user and channel values
|
//Set socket user and channel values
|
||||||
|
|
@ -140,7 +140,7 @@ module.exports = class{
|
||||||
|
|
||||||
//Check if channel exists
|
//Check if channel exists
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
throw new Error("Channel not found!");
|
throw loggerUtils.exceptionSmith("Channel not found", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if current channel is active
|
//Check if current channel is active
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while queue item!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while queue item!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//For each item
|
//For each item
|
||||||
|
|
@ -409,7 +409,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while queue item!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while queue item!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Keep a copy of the archive that hasn't been changed
|
//Keep a copy of the archive that hasn't been changed
|
||||||
|
|
@ -470,7 +470,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while queue item!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while queue item!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Filter media out by UUID
|
//Filter media out by UUID
|
||||||
|
|
@ -611,7 +611,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while saving item to queue!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while saving item to queue!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add media to the persistant schedule
|
//Add media to the persistant schedule
|
||||||
|
|
@ -766,7 +766,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while ending queue item!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while ending queue item!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we haven't changed 'nowPlaying' in the play list
|
//If we haven't changed 'nowPlaying' in the play list
|
||||||
|
|
@ -909,7 +909,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while rehydrating queue!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while rehydrating queue!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create an empty array to hold our schedule
|
//Create an empty array to hold our schedule
|
||||||
|
|
@ -957,7 +957,7 @@ module.exports = class{
|
||||||
//If we couldn't find the channel
|
//If we couldn't find the channel
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
//FUCK
|
//FUCK
|
||||||
throw new Error(`Unable to find channel document ${this.channel.name} while rehydrating queue!`);
|
throw loggerUtils.exceptionSmith(`Unable to find channel document ${this.channel.name} while rehydrating queue!`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ module.exports.post = async function(req, res){
|
||||||
const channel = await channelModel.findOne({name: data.chanName});
|
const channel = await channelModel.findOne({name: data.chanName});
|
||||||
|
|
||||||
if(channel == null){
|
if(channel == null){
|
||||||
throw new Error("Chanenl does not exist!");
|
throw loggerUtils.exceptionSmith("Chanenl does not exist!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
await channel.nuke(data.confirm);
|
await channel.nuke(data.confirm);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ module.exports.get = async function(req, res){
|
||||||
|
|
||||||
|
|
||||||
if(channel == null){
|
if(channel == null){
|
||||||
throw new Error("Channel not found.");
|
throw loggerUtils.exceptionSmith("Channel not found.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200);
|
res.status(200);
|
||||||
|
|
@ -64,7 +64,7 @@ module.exports.post = async function(req, res){
|
||||||
var permError = null;
|
var permError = null;
|
||||||
|
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
throw new Error("Channel not found.");
|
throw loggerUtils.exceptionSmith("Channel not found.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//For each permission submitted
|
//For each permission submitted
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ module.exports.get = async function(req, res){
|
||||||
const channel = await channelModel.findOne({name: data.chanName});
|
const channel = await channelModel.findOne({name: data.chanName});
|
||||||
|
|
||||||
if(channel == null){
|
if(channel == null){
|
||||||
throw new Error("Channel not found.");
|
throw loggerUtils.exceptionSmith("Channel not found.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200);
|
res.status(200);
|
||||||
|
|
@ -56,7 +56,7 @@ module.exports.post = async function(req, res){
|
||||||
const settingsMap = new Map(Object.entries(data.settingsMap));
|
const settingsMap = new Map(Object.entries(data.settingsMap));
|
||||||
|
|
||||||
if(channel == null){
|
if(channel == null){
|
||||||
throw new Error("Channel not found.");
|
throw loggerUtils.exceptionSmith("Channel not found.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200);
|
res.status(200);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ module.exports.get = async function(req, res){
|
||||||
delete chanDB.permissions._doc._id;
|
delete chanDB.permissions._doc._id;
|
||||||
|
|
||||||
if(chanDB == null){
|
if(chanDB == null){
|
||||||
throw new Error("Channel not found.");
|
throw loggerUtils.exceptionSmith("Channel not found.", "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.render('channelSettings', {instance: config.instanceName, user: req.session.user, channel: chanDB, reqRank, rankEnum: permissionModel.rankEnum, csrfToken: csrfUtils.generateToken(req)});
|
return res.render('channelSettings', {instance: config.instanceName, user: req.session.user, channel: chanDB, reqRank, rankEnum: permissionModel.rankEnum, csrfToken: csrfUtils.generateToken(req)});
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ const channelSchema = new mongoose.Schema({
|
||||||
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){
|
||||||
throw new Error("Username must only contain alpha-numerics and the following symbols: '-_.'");
|
throw loggerUtils.exceptionSmith("Username must only contain alpha-numerics and the following symbols: '-_.'", "validation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ channelSchema.statics.register = async function(channelObj, ownerObj){
|
||||||
const chanDB = await this.findOne({ name });
|
const chanDB = await this.findOne({ name });
|
||||||
|
|
||||||
if(chanDB){
|
if(chanDB){
|
||||||
throw new Error("Channel name already taken!");
|
throw loggerUtils.exceptionSmith("Channel name already taken!", "validation");
|
||||||
}else{
|
}else{
|
||||||
const id = await statModel.incrementChannelCount();
|
const id = await statModel.incrementChannelCount();
|
||||||
const rankList = [{
|
const rankList = [{
|
||||||
|
|
@ -334,7 +334,7 @@ channelSchema.statics.processExpiredBans = async function(){
|
||||||
channelSchema.methods.updateSettings = async function(settingsMap){
|
channelSchema.methods.updateSettings = async function(settingsMap){
|
||||||
settingsMap.forEach((value, key) => {
|
settingsMap.forEach((value, key) => {
|
||||||
if(this.settings[key] == null){
|
if(this.settings[key] == null){
|
||||||
throw new Error("Invalid channel setting.");
|
throw loggerUtils.exceptionSmith("Invalid channel setting.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings[key] = value;
|
this.settings[key] = value;
|
||||||
|
|
@ -661,13 +661,13 @@ channelSchema.methods.getChanBans = async function(){
|
||||||
channelSchema.methods.banByUserDoc = async function(userDB, expirationDays, banAlts){
|
channelSchema.methods.banByUserDoc = async function(userDB, expirationDays, banAlts){
|
||||||
//Throw a shitfit if the user doesn't exist
|
//Throw a shitfit if the user doesn't exist
|
||||||
if(userDB == null){
|
if(userDB == null){
|
||||||
throw new Error("Cannot ban non-existant user!");
|
throw loggerUtils.exceptionSmith("Cannot ban non-existant user!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundBan = await this.checkBanByUserDoc(userDB);
|
const foundBan = await this.checkBanByUserDoc(userDB);
|
||||||
|
|
||||||
if(foundBan != null){
|
if(foundBan != null){
|
||||||
throw new Error("User already banned!");
|
throw loggerUtils.exceptionSmith("User already banned!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create a new ban document based on input
|
//Create a new ban document based on input
|
||||||
|
|
@ -703,13 +703,13 @@ channelSchema.methods.ban = async function(user, expirationDays, banAlts){
|
||||||
channelSchema.methods.unbanByUserDoc = async function(userDB){
|
channelSchema.methods.unbanByUserDoc = async function(userDB){
|
||||||
//Throw a shitfit if the user doesn't exist
|
//Throw a shitfit if the user doesn't exist
|
||||||
if(userDB == null){
|
if(userDB == null){
|
||||||
throw new Error("Cannot ban non-existant user!");
|
throw loggerUtils.exceptionSmith("Cannot ban non-existant user!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const foundBan = await this.checkBanByUserDoc(userDB);
|
const foundBan = await this.checkBanByUserDoc(userDB);
|
||||||
|
|
||||||
if(foundBan == null){
|
if(foundBan == null){
|
||||||
throw new Error("User already unbanned!");
|
throw loggerUtils.exceptionSmith("User already unbanned!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//You know I can't help but feel like an asshole for looking for the index of something I just pulled out of an array using forEach...
|
//You know I can't help but feel like an asshole for looking for the index of something I just pulled out of an array using forEach...
|
||||||
|
|
@ -727,16 +727,16 @@ channelSchema.methods.unban = async function(user){
|
||||||
|
|
||||||
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 loggerUtils.exceptionSmith("Empty Confirmation String!", "validation");
|
||||||
}else if(confirm != this.name){
|
}else if(confirm != this.name){
|
||||||
throw new Error("Bad Confirmation String!");
|
throw loggerUtils.exceptionSmith("Bad Confirmation String!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Annoyingly there isnt a good way to do this from 'this'
|
//Annoyingly there isnt a good way to do this from 'this'
|
||||||
var oldChan = await this.deleteOne();
|
var oldChan = await this.deleteOne();
|
||||||
|
|
||||||
if(oldChan.deletedCount == 0){
|
if(oldChan.deletedCount == 0){
|
||||||
throw new Error("Server Error: Unable to delete channel! Please report this error to your server administrator, and with timestamp.");
|
throw loggerUtils.exceptionSmith("Server Error: Unable to delete channel! Please report this error to your server administrator, and with timestamp.", "internal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ permissionSchema.methods.permCheckByUserDoc = function(userDB, perm){
|
||||||
return (userRank >= requiredRank);
|
return (userRank >= requiredRank);
|
||||||
}else{
|
}else{
|
||||||
//if not scream and shout
|
//if not scream and shout
|
||||||
throw new Error(`Permission check '${perm}' not found!`);
|
throw loggerUtils.exceptionSmith(`Permission check '${perm}' not found!`, "Validation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ permissionSchema.methods.overrideCheckByUserDoc = function(userDB, perm){
|
||||||
return (userRank >= requiredRank);
|
return (userRank >= requiredRank);
|
||||||
}else{
|
}else{
|
||||||
//if not scream and shout
|
//if not scream and shout
|
||||||
throw new Error(`Permission check '${perm}' not found!`);
|
throw loggerUtils.exceptionSmith(`Permission check '${perm}' not found!`, "validation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ const crypto = require("node:crypto");
|
||||||
const {mongoose} = require('mongoose');
|
const {mongoose} = require('mongoose');
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
const hashUtil = require('../../utils/hashUtils');
|
const hashUtil = require('../../utils/hashUtils.js');
|
||||||
|
const loggerUtils = require('../../utils/loggerUtils.js')
|
||||||
|
|
||||||
const daysToExpire = 7;
|
const daysToExpire = 7;
|
||||||
|
|
||||||
|
|
@ -85,7 +86,7 @@ passwordResetSchema.statics.processExpiredRequests = async function(){
|
||||||
passwordResetSchema.methods.consume = async function(pass, confirmPass){
|
passwordResetSchema.methods.consume = async function(pass, confirmPass){
|
||||||
//Check confirmation pass
|
//Check confirmation pass
|
||||||
if(pass != confirmPass){
|
if(pass != confirmPass){
|
||||||
throw new Error("Confirmation password does not match!");
|
throw loggerUtils.exceptionSmith("Confirmation password does not match!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Populate the user reference
|
//Populate the user reference
|
||||||
|
|
|
||||||
|
|
@ -18,8 +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 hashUtil = require('../../utils/hashUtils');
|
const hashUtil = require('../../utils/hashUtils.js');
|
||||||
const {userModel} = require('./userSchema');
|
const {userModel} = require('./userSchema.js');
|
||||||
|
const loggerUtils = require('../../utils/loggerUtils.js');
|
||||||
|
|
||||||
const userBanSchema = new mongoose.Schema({
|
const userBanSchema = new mongoose.Schema({
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -184,21 +185,21 @@ userBanSchema.statics.checkProcessedBans = async function(user){
|
||||||
userBanSchema.statics.banByUserDoc = async function(userDB, permanent, expirationDays, ipBan = false){
|
userBanSchema.statics.banByUserDoc = async function(userDB, permanent, expirationDays, ipBan = false){
|
||||||
//Prevent missing users
|
//Prevent missing users
|
||||||
if(userDB == null){
|
if(userDB == null){
|
||||||
throw new Error("User not found")
|
throw loggerUtils.exceptionSmith("User not found", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ensure the user isn't already banned
|
//Ensure the user isn't already banned
|
||||||
if(await this.checkBanByUserDoc(userDB) != null){
|
if(await this.checkBanByUserDoc(userDB) != null){
|
||||||
throw new Error("User already banned");
|
throw loggerUtils.exceptionSmith("User already banned", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Verify time to expire/delete depending on action
|
//Verify time to expire/delete depending on action
|
||||||
if(expirationDays < 0){
|
if(expirationDays < 0){
|
||||||
throw new Error("Expiration Days must be a positive integer!");
|
throw loggerUtils.exceptionSmith("Expiration Days must be a positive integer!", "validation");
|
||||||
}else if(expirationDays < 30 && permanent){
|
}else if(expirationDays < 30 && permanent){
|
||||||
throw new Error("Permanent bans must be given at least 30 days before automatic account deletion!");
|
throw loggerUtils.exceptionSmith("Permanent bans must be given at least 30 days before automatic account deletion!", "validation");
|
||||||
}else if(expirationDays > 185){
|
}else if(expirationDays > 185){
|
||||||
throw new Error("Expiration/Deletion date cannot be longer than half a year out from the original ban date.");
|
throw loggerUtils.exceptionSmith("Expiration/Deletion date cannot be longer than half a year out from the original ban date.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
await banSessions(userDB);
|
await banSessions(userDB);
|
||||||
|
|
@ -266,13 +267,13 @@ userBanSchema.statics.unbanByUserDoc = async function(userDB){
|
||||||
|
|
||||||
//Prevent missing users
|
//Prevent missing users
|
||||||
if(userDB == null){
|
if(userDB == null){
|
||||||
throw new Error("User not found")
|
throw loggerUtils.exceptionSmith("User not found", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const banDB = await this.checkBanByUserDoc(userDB);
|
const banDB = await this.checkBanByUserDoc(userDB);
|
||||||
|
|
||||||
if(!banDB){
|
if(!banDB){
|
||||||
throw new Error("User already un-banned");
|
throw loggerUtils.exceptionSmith("User already un-banned", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Use _id in-case mongoose wants to be a cunt
|
//Use _id in-case mongoose wants to be a cunt
|
||||||
|
|
@ -284,7 +285,7 @@ userBanSchema.statics.unbanDeleted = async function(user){
|
||||||
const banDB = await this.checkProcessedBans(user);
|
const banDB = await this.checkProcessedBans(user);
|
||||||
|
|
||||||
if(!banDB){
|
if(!banDB){
|
||||||
throw new Error("User already un-banned");
|
throw loggerUtils.exceptionSmith("User already un-banned", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldBan = await this.deleteOne({_id: banDB._id});
|
const oldBan = await this.deleteOne({_id: banDB._id});
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,6 @@ GNU Affero General Public License for more details.
|
||||||
You should have received a copy of the GNU Affero General Public License
|
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/>.*/
|
||||||
|
|
||||||
//Node Imports
|
|
||||||
const { profile } = require('console');
|
|
||||||
|
|
||||||
//NPM Imports
|
//NPM Imports
|
||||||
const {mongoose} = require('mongoose');
|
const {mongoose} = require('mongoose');
|
||||||
|
|
||||||
|
|
@ -33,6 +30,7 @@ const playlistSchema = require('../channel/media/playlistSchema');
|
||||||
//Utils
|
//Utils
|
||||||
const hashUtil = require('../../utils/hashUtils');
|
const hashUtil = require('../../utils/hashUtils');
|
||||||
const mailUtil = require('../../utils/mailUtils');
|
const mailUtil = require('../../utils/mailUtils');
|
||||||
|
const loggerUtils = require('../../utils/loggerUtils')
|
||||||
|
|
||||||
|
|
||||||
const userSchema = new mongoose.Schema({
|
const userSchema = new mongoose.Schema({
|
||||||
|
|
@ -161,7 +159,7 @@ userSchema.pre('save', async function (next){
|
||||||
await this.populate('flair');
|
await this.populate('flair');
|
||||||
|
|
||||||
if(permissionModel.rankToNum(this.rank) < permissionModel.rankToNum(this.flair.rank)){
|
if(permissionModel.rankToNum(this.rank) < permissionModel.rankToNum(this.flair.rank)){
|
||||||
throw new Error(`User '${this.user}' does not have a high enough rank for flair '${this.flair.displayName}'!`);
|
throw loggerUtils.exceptionSmith(`User '${this.user}' does not have a high enough rank for flair '${this.flair.displayName}'!`, "unauthorized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +221,7 @@ userSchema.statics.register = async function(userObj, ip){
|
||||||
|
|
||||||
//If the user is found or someones trying to impersonate tokeboi
|
//If the user is found or someones trying to impersonate tokeboi
|
||||||
if(userDB || user.toLowerCase() == "tokebot"){
|
if(userDB || user.toLowerCase() == "tokebot"){
|
||||||
throw new Error("User name/email already taken!");
|
throw loggerUtils.exceptionSmith("User name/email already taken!", "validation");
|
||||||
}else{
|
}else{
|
||||||
//Increment the user count, pulling the id to tattoo to the user
|
//Increment the user count, pulling the id to tattoo to the user
|
||||||
const id = await statModel.incrementUserCount();
|
const id = await statModel.incrementUserCount();
|
||||||
|
|
@ -242,14 +240,14 @@ userSchema.statics.register = async function(userObj, ip){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
throw new Error("Confirmation password doesn't match!");
|
throw loggerUtils.exceptionSmith("Confirmation password doesn't match!", "validation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userSchema.statics.authenticate = async function(user, pass, failLine = "Bad Username or Password."){
|
userSchema.statics.authenticate = async function(user, pass, failLine = "Bad Username or Password."){
|
||||||
//check for missing pass
|
//check for missing pass
|
||||||
if(!user || !pass){
|
if(!user || !pass){
|
||||||
throw new Error("Missing user/pass.");
|
throw loggerUtils.exceptionSmith("Missing user/pass.", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the user if it exists
|
//get the user if it exists
|
||||||
|
|
@ -268,9 +266,9 @@ userSchema.statics.authenticate = async function(user, pass, failLine = "Bad Use
|
||||||
badLogin();
|
badLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//standardize bad login response so it's unknowin which is bad for security reasons.
|
//standardize bad login response so it's unknown which is bad for security reasons.
|
||||||
function badLogin(){
|
function badLogin(){
|
||||||
throw new Error(failLine);
|
throw loggerUtils.exceptionSmith(failLine, "unauthorized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,11 +686,11 @@ userSchema.methods.changePassword = async function(passChange){
|
||||||
await this.killAllSessions("Your password has been reset.");
|
await this.killAllSessions("Your password has been reset.");
|
||||||
}else{
|
}else{
|
||||||
//confirmation pass doesn't match
|
//confirmation pass doesn't match
|
||||||
throw new Error("Mismatched confirmation password!");
|
throw loggerUtils.exceptionSmith("Mismatched confirmation password!", "validation");
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//Old password wrong
|
//Old password wrong
|
||||||
throw new Error("Incorrect Password!");
|
throw loggerUtils.exceptionSmith("Incorrect Password!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -716,7 +714,7 @@ userSchema.methods.nuke = async function(pass){
|
||||||
//Check we have a confirmation password
|
//Check we have a confirmation password
|
||||||
if(pass == "" || pass == null){
|
if(pass == "" || pass == null){
|
||||||
//scream and shout
|
//scream and shout
|
||||||
throw new Error("No confirmation password!");
|
throw loggerUtils.exceptionSmith("No confirmation password!", "validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check that the password is correct
|
//Check that the password is correct
|
||||||
|
|
@ -725,7 +723,7 @@ userSchema.methods.nuke = async function(pass){
|
||||||
var oldUser = await this.deleteOne();
|
var oldUser = await this.deleteOne();
|
||||||
}else{
|
}else{
|
||||||
//complain about a bad pass
|
//complain about a bad pass
|
||||||
throw new Error("Bad pass.");
|
throw loggerUtils.exceptionSmith("Bad pass.", "unauthorized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,20 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
//Config
|
//Config
|
||||||
const config = require('../../config.json');
|
const config = require('../../config.json');
|
||||||
|
|
||||||
//At some point this will be a bit more advanced, right now it's just a placeholder :P
|
module.exports.exceptionSmith = function(msg, type){
|
||||||
|
//Create the new error with the given message
|
||||||
|
const exception = new Error(msg);
|
||||||
|
|
||||||
|
//Set the error type
|
||||||
|
exception.type = type;
|
||||||
|
|
||||||
|
//Mark the error as a custom error
|
||||||
|
exception.custom = true;
|
||||||
|
|
||||||
|
//Return the error
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.errorHandler = function(res, msg, type = "Generic", status = 400){
|
module.exports.errorHandler = function(res, msg, type = "Generic", status = 400){
|
||||||
//Some controllers do things after sending headers, for those, we should remain silent
|
//Some controllers do things after sending headers, for those, we should remain silent
|
||||||
if(!res.headersSent){
|
if(!res.headersSent){
|
||||||
|
|
@ -35,11 +48,16 @@ module.exports.localExceptionHandler = function(err){
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.exceptionHandler = function(res, err){
|
module.exports.exceptionHandler = function(res, err){
|
||||||
//Locally handle the exception
|
//If this is a self-made problem
|
||||||
module.exports.localExceptionHandler(err);
|
if(err.custom){
|
||||||
|
module.exports.errorHandler(res, err.message, err.type);
|
||||||
|
}else{
|
||||||
|
//Locally handle the exception
|
||||||
|
module.exports.localExceptionHandler(err);
|
||||||
|
|
||||||
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
||||||
module.exports.errorHandler(res, err.message, "Caught Exception");
|
module.exports.errorHandler(res, "An unexpected server crash was just prevented. You should probably report this to an admin.", "Caught Exception");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.socketErrorHandler = function(socket, msg, type = "Generic"){
|
module.exports.socketErrorHandler = function(socket, msg, type = "Generic"){
|
||||||
|
|
@ -47,16 +65,28 @@ module.exports.socketErrorHandler = function(socket, msg, type = "Generic"){
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.socketExceptionHandler = function(socket, err){
|
module.exports.socketExceptionHandler = function(socket, err){
|
||||||
//Locally handle the exception
|
//If this is a self made problem
|
||||||
module.exports.localExceptionHandler(err);
|
if(err.custom){
|
||||||
|
//at the browser for fucking up, and tell it what it did wrong.
|
||||||
|
return module.exports.socketErrorHandler(socket, err.message, err.type);
|
||||||
|
}else{
|
||||||
|
//Locally handle the exception
|
||||||
|
module.exports.localExceptionHandler(err);
|
||||||
|
|
||||||
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
//if not yell at the browser for fucking up
|
||||||
return module.exports.socketErrorHandler(socket, err.msg, "Caught Exception");
|
return module.exports.socketErrorHandler(socket, "Caught Exception", "Caught Exception");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.socketCriticalExceptionHandler = function(socket, err){
|
module.exports.socketCriticalExceptionHandler = function(socket, err){
|
||||||
//if not yell at the browser for fucking up, and tell it what it did wrong.
|
//If this is a self made problem
|
||||||
socket.emit("kick", {type: "Disconnected", reason: `Server Error: ${err.message}`});
|
if(err.custom){
|
||||||
|
//yell at the browser for fucking up, and tell it what it did wrong.
|
||||||
|
socket.emit("kick", {type: "Disconnected", reason: `Server Error: ${err.message}`});
|
||||||
|
}else{
|
||||||
|
//yell at the browser for fucking up
|
||||||
|
socket.emit("kick", {type: "Disconnected", reason: "An unexpected server crash was just prevented. You should probably report this to an admin."});
|
||||||
|
}
|
||||||
return socket.disconnect();
|
return socket.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@ const url = require("node:url");
|
||||||
const validator = require('validator');
|
const validator = require('validator');
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
const regexUtils = require('../regexUtils');
|
const media = require('../../app/channel/media/media.js');
|
||||||
const media = require('../../app/channel/media/media');
|
const regexUtils = require('../regexUtils.js');
|
||||||
|
const loggerUtils = require('../loggerUtils.js')
|
||||||
|
|
||||||
module.exports.fetchMetadata = async function(link, title){
|
module.exports.fetchMetadata = async function(link, title){
|
||||||
//Parse link
|
//Parse link
|
||||||
|
|
@ -52,7 +53,7 @@ module.exports.fetchMetadata = async function(link, title){
|
||||||
if(!response.ok){
|
if(!response.ok){
|
||||||
//Scream and shout
|
//Scream and shout
|
||||||
const errorBody = await response.text();
|
const errorBody = await response.text();
|
||||||
throw new Error(`Internet Archive Error '${response.status}': ${errorBody}`);
|
throw loggerUtils.exceptionSmith(`Internet Archive Error '${response.status}': ${errorBody}`, "queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Collect our metadata
|
//Collect our metadata
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ module.exports.kickoff = function(){
|
||||||
//Process Hashed IP Records that haven't been recorded in a week or more
|
//Process Hashed IP Records that haven't been recorded in a week or more
|
||||||
userModel.processAgedIPRecords();
|
userModel.processAgedIPRecords();
|
||||||
//Process expired global bans that may have expired since last restart
|
//Process expired global bans that may have expired since last restart
|
||||||
userBanModel.processExpiredBans()
|
userBanModel.processExpiredBans();
|
||||||
//Process expired channel bans that may have expired since last restart
|
//Process expired channel bans that may have expired since last restart
|
||||||
channelModel.processExpiredBans();
|
channelModel.processExpiredBans();
|
||||||
//Process expired password reset requests that may have expired since last restart
|
//Process expired password reset requests that may have expired since last restart
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
|
|
||||||
//Local Imports
|
//Local Imports
|
||||||
const config = require('../../config.json');
|
const config = require('../../config.json');
|
||||||
const {userModel} = require('../schemas/user/userSchema');
|
const {userModel} = require('../schemas/user/userSchema.js');
|
||||||
const userBanModel = require('../schemas/user/userBanSchema')
|
const userBanModel = require('../schemas/user/userBanSchema.js')
|
||||||
const altchaUtils = require('../utils/altchaUtils');
|
const altchaUtils = require('../utils/altchaUtils.js');
|
||||||
|
const loggerUtils = require('../utils/loggerUtils.js')
|
||||||
|
|
||||||
//Create failed sign-in cache since it's easier and more preformant to implement it this way than adding extra burdon to the database
|
//Create failed sign-in cache since it's easier and more preformant to implement it this way than adding extra burdon to the database
|
||||||
//Server restarts are far and few between. It would take multiple during a single bruteforce attempt for this to become an issue.
|
//Server restarts are far and few between. It would take multiple during a single bruteforce attempt for this to become an issue.
|
||||||
|
|
@ -41,15 +42,24 @@ module.exports.authenticateSession = async function(user, pass, req){
|
||||||
|
|
||||||
//If this ip is randy bobandy
|
//If this ip is randy bobandy
|
||||||
if(ipBanDB != null){
|
if(ipBanDB != null){
|
||||||
//tell it to fuck off
|
//Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
|
||||||
throw new Error(`The IP address you are trying to login from has been banned.`);
|
const expiration = ipBanDB.getDaysUntilExpiration() < 1 ? 0 : ipBanDB.getDaysUntilExpiration();
|
||||||
|
|
||||||
|
//If the ban is permanent
|
||||||
|
if(ipBanDB.permanent){
|
||||||
|
//tell it to fuck off
|
||||||
|
throw loggerUtils.exceptionSmith(`The IP address you are trying to login from has been permanently banned. Your cleartext IP has been saved to the database. Any associated accounts will be nuked in ${expiration} day(s).`, "unauthorized");
|
||||||
|
}else{
|
||||||
|
//tell it to fuck off
|
||||||
|
throw loggerUtils.exceptionSmith(`The IP address you are trying to login from has been temporarily banned. Your cleartext IP has been saved to the database until the ban expires in ${expiration} day(s).`, "unauthorized");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we have failed attempts
|
//If we have failed attempts
|
||||||
if(attempt != null){
|
if(attempt != null){
|
||||||
//If we have more failed attempts than allowed
|
//If we have more failed attempts than allowed
|
||||||
if(attempt.count > maxAttempts){
|
if(attempt.count > maxAttempts){
|
||||||
throw new Error("This account has been locked for at 24 hours due to a large amount of failed log-in attempts");
|
throw loggerUtils.exceptionSmith("This account has been locked for at 24 hours due to a large amount of failed log-in attempts", "unauthorized");
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we're throttling logins
|
//If we're throttling logins
|
||||||
|
|
@ -57,9 +67,9 @@ module.exports.authenticateSession = async function(user, pass, req){
|
||||||
//Verification doesnt get sanatized or checked since that would most likely break the cryptography
|
//Verification doesnt get sanatized or checked since that would most likely break the cryptography
|
||||||
//Since we've already got access to the request and dont need to import anything, why bother getting it from a parameter?
|
//Since we've already got access to the request and dont need to import anything, why bother getting it from a parameter?
|
||||||
if(req.body.verification == null){
|
if(req.body.verification == null){
|
||||||
throw new Error("Verification failed!");
|
throw loggerUtils.exceptionSmith("Verification failed!", "unauthorized");
|
||||||
}else if(!altchaUtils.verify(req.body.verification, user)){
|
}else if(!altchaUtils.verify(req.body.verification, user)){
|
||||||
throw new Error("Verification failed!");
|
throw loggerUtils.exceptionSmith("Verification failed!", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,9 +85,9 @@ module.exports.authenticateSession = async function(user, pass, req){
|
||||||
//Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
|
//Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
|
||||||
const expiration = userBanDB.getDaysUntilExpiration() < 1 ? 0 : userBanDB.getDaysUntilExpiration();
|
const expiration = userBanDB.getDaysUntilExpiration() < 1 ? 0 : userBanDB.getDaysUntilExpiration();
|
||||||
if(userBanDB.permanent){
|
if(userBanDB.permanent){
|
||||||
throw new Error(`Your account has been permanently banned, and will be nuked from the database in: ${expiration} day(s)`);
|
throw loggerUtils.exceptionSmith(`Your account has been permanently banned, and will be nuked from the database in: ${expiration} day(s)`, "unauthorized");
|
||||||
}else{
|
}else{
|
||||||
throw new Error(`Your account has been temporarily banned, and will be reinstated in: ${expiration} day(s)`);
|
throw loggerUtils.exceptionSmith(`Your account has been temporarily banned, and will be reinstated in: ${expiration} day(s)`, "unauthorized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue