Improved exception handling, started work on improving error messages for IP bans

This commit is contained in:
rainbow napkin 2025-05-29 09:48:48 -04:00
parent 7d3c31f0aa
commit 853f67fe15
15 changed files with 118 additions and 77 deletions

View file

@ -17,7 +17,20 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Config
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){
//Some controllers do things after sending headers, for those, we should remain silent
if(!res.headersSent){
@ -35,11 +48,16 @@ module.exports.localExceptionHandler = function(err){
}
module.exports.exceptionHandler = function(res, err){
//Locally handle the exception
module.exports.localExceptionHandler(err);
//If this is a self-made problem
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.
module.exports.errorHandler(res, err.message, "Caught Exception");
//if not yell at the browser for fucking up, and tell it what it did wrong.
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"){
@ -47,16 +65,28 @@ module.exports.socketErrorHandler = function(socket, msg, type = "Generic"){
}
module.exports.socketExceptionHandler = function(socket, err){
//Locally handle the exception
module.exports.localExceptionHandler(err);
//If this is a self made problem
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.
return module.exports.socketErrorHandler(socket, err.msg, "Caught Exception");
//if not yell at the browser for fucking up
return module.exports.socketErrorHandler(socket, "Caught Exception", "Caught Exception");
}
}
module.exports.socketCriticalExceptionHandler = function(socket, err){
//if not yell at the browser for fucking up, and tell it what it did wrong.
socket.emit("kick", {type: "Disconnected", reason: `Server Error: ${err.message}`});
//If this is a self made problem
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();
}

View file

@ -19,8 +19,9 @@ const url = require("node:url");
const validator = require('validator');
//Local Imports
const regexUtils = require('../regexUtils');
const media = require('../../app/channel/media/media');
const media = require('../../app/channel/media/media.js');
const regexUtils = require('../regexUtils.js');
const loggerUtils = require('../loggerUtils.js')
module.exports.fetchMetadata = async function(link, title){
//Parse link
@ -52,7 +53,7 @@ module.exports.fetchMetadata = async function(link, title){
if(!response.ok){
//Scream and shout
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

View file

@ -45,7 +45,7 @@ module.exports.kickoff = function(){
//Process Hashed IP Records that haven't been recorded in a week or more
userModel.processAgedIPRecords();
//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
channelModel.processExpiredBans();
//Process expired password reset requests that may have expired since last restart

View file

@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//Local Imports
const config = require('../../config.json');
const {userModel} = require('../schemas/user/userSchema');
const userBanModel = require('../schemas/user/userBanSchema')
const altchaUtils = require('../utils/altchaUtils');
const {userModel} = require('../schemas/user/userSchema.js');
const userBanModel = require('../schemas/user/userBanSchema.js')
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
//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(ipBanDB != null){
//tell it to fuck off
throw new Error(`The IP address you are trying to login from has been banned.`);
//Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
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(attempt != null){
//If we have more failed attempts than allowed
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
@ -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
//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){
throw new Error("Verification failed!");
throw loggerUtils.exceptionSmith("Verification failed!", "unauthorized");
}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
const expiration = userBanDB.getDaysUntilExpiration() < 1 ? 0 : userBanDB.getDaysUntilExpiration();
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{
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");
}
}