Compare commits

..

No commits in common. "d874f5e2daa7eb028e9c54150e7559bb3924dce4" and "1d5a087d79a302167b8a9bac24062c66a0521798" have entirely different histories.

6 changed files with 20 additions and 39 deletions

View file

@ -39,7 +39,7 @@ module.exports.post = async function(req, res){
const data = matchedData(req); const data = matchedData(req);
//try to authenticate the session, throwing an error and breaking the current code block if user is un-authorized //try to authenticate the session, throwing an error and breaking the current code block if user is un-authorized
const userDB = await sessionUtils.authenticateSession(data.user, data.pass, req); await sessionUtils.authenticateSession(data.user, data.pass, req);
//If the user already has a remember me token //If the user already has a remember me token
if(data.rememberme != null && data.rememberme.id != null){ if(data.rememberme != null && data.rememberme.id != null){
@ -57,10 +57,8 @@ module.exports.post = async function(req, res){
//requires second DB call, but this enforces password requirement for toke generation while ensuring we only //requires second DB call, but this enforces password requirement for toke generation while ensuring we only
//need one function in the userModel for authentication, even if the second woulda just been a wrapper. //need one function in the userModel for authentication, even if the second woulda just been a wrapper.
//Less attack surface is less attack surface, and this isn't something thats going to be getting constantly called //Less attack surface is less attack surface, and this isn't something thats going to be getting constantly called
const authToken = await rememberMeModel.genToken(userDB, data.pass); const authToken = await rememberMeModel.genToken(data.user, data.pass);
//If we properly authed
if(authToken != null){
//Check config for protocol //Check config for protocol
const secure = config.protocol.toLowerCase() == "https"; const secure = config.protocol.toLowerCase() == "https";
@ -72,7 +70,6 @@ module.exports.post = async function(req, res){
//This should be the servers last interaction with the plaintext token before saving the hashed copy, and dropping it out of RAM //This should be the servers last interaction with the plaintext token before saving the hashed copy, and dropping it out of RAM
res.cookie("rememberme.token", authToken.token, {sameSite: 'strict', httpOnly: true, secure, expires}); res.cookie("rememberme.token", authToken.token, {sameSite: 'strict', httpOnly: true, secure, expires});
} }
}
//Tell the browser everything is dandy //Tell the browser everything is dandy
return res.sendStatus(200); return res.sendStatus(200);

View file

@ -34,7 +34,7 @@ module.exports.post = async function(req, res){
const data = matchedData(req); const data = matchedData(req);
//If the user has a remember me token id they've submitted with the request //If the user has a remember me token id they've submitted with the request
if(data.rememberme != null && data.rememberme.id != null){ if(data.rememberme.id){
//Find the associated token and nuke it //Find the associated token and nuke it
await rememberMeModel.deleteOne({id: data.rememberme.id}) await rememberMeModel.deleteOne({id: data.rememberme.id})
} }

View file

@ -27,6 +27,7 @@ const crypto = require("node:crypto");
const {mongoose} = require('mongoose'); const {mongoose} = require('mongoose');
//Local Imports //Local Imports
const {userModel} = require('./userSchema');
const hashUtil = require('../../utils/hashUtils'); const hashUtil = require('../../utils/hashUtils');
const loggerUtils = require('../../utils/loggerUtils'); const loggerUtils = require('../../utils/loggerUtils');
@ -87,13 +88,9 @@ rememberMeToken.methods.checkToken = async function(token){
} }
//statics //statics
rememberMeToken.statics.genToken = async function(userDB, pass){ rememberMeToken.statics.genToken = async function(user, pass){
//Normally I'd use userModel auth, but this saves on DB calls and keeps us from having to refrence the userModel directly //Authenticate user and pull document
//Saving us from circular depedency hell const userDB = await userModel.authenticate(user, pass);
//Plus this is only really getting called along-side other auth, theres already going to be an error message if this is wrong XP
if(!await userDB.checkPass(pass)){
return;
}
try{ try{
//Generate a cryptographically secure string of 32 bytes in hexidecimal //Generate a cryptographically secure string of 32 bytes in hexidecimal

View file

@ -28,7 +28,6 @@ const permissionModel = require('../permissionSchema');
const emoteModel = require('../emoteSchema'); const emoteModel = require('../emoteSchema');
const emailChangeModel = require('./emailChangeSchema'); const emailChangeModel = require('./emailChangeSchema');
const playlistSchema = require('../channel/media/playlistSchema'); const playlistSchema = require('../channel/media/playlistSchema');
const rememberMeModel = require('./rememberMeSchema');
//Utils //Utils
const hashUtil = require('../../utils/hashUtils'); const hashUtil = require('../../utils/hashUtils');
const mailUtil = require('../../utils/mailUtils'); const mailUtil = require('../../utils/mailUtils');
@ -808,9 +807,6 @@ userSchema.methods.tattooIPRecord = async function(ip){
* @param {String} reason - Reason to kill user sessions * @param {String} reason - Reason to kill user sessions
*/ */
userSchema.methods.killAllSessions = async function(reason = "A full log-out from all devices was requested for your account."){ userSchema.methods.killAllSessions = async function(reason = "A full log-out from all devices was requested for your account."){
//Nuke all related remember me tokens
await rememberMeModel.deleteMany({user: this._id});
//get authenticated sessions //get authenticated sessions
var sessions = await this.getAuthenticatedSessions(); var sessions = await this.getAuthenticatedSessions();

View file

@ -64,8 +64,8 @@ module.exports.errorHandler = function(res, msg, type = "Generic", status = 400)
* @param {Error} err - Exception to handle * @param {Error} err - Exception to handle
*/ */
module.exports.localExceptionHandler = function(err){ module.exports.localExceptionHandler = function(err){
//If we're being verbose and this isn't just a basic bitch //If we're being verbose
if(!err.custom && config.verbose){ if(config.verbose){
//Log the error //Log the error
module.exports.dumpError(err); module.exports.dumpError(err);
} }

View file

@ -145,7 +145,7 @@ module.exports.authenticateSession = async function(identifier, secret, req, use
} }
//return user //return user
return userDB; return userDB.user;
}catch(err){ }catch(err){
//Failed attempts at good tokens are handled by the token schema by dropping the users effected tokens and screaming bloody murder //Failed attempts at good tokens are handled by the token schema by dropping the users effected tokens and screaming bloody murder
//Failed attempts with bad tokens don't need to be handled as it's not like attacking a bad UUID is going to get you anywhere anywho //Failed attempts with bad tokens don't need to be handled as it's not like attacking a bad UUID is going to get you anywhere anywho
@ -214,12 +214,6 @@ module.exports.processExpiredAttempts = function(){
} }
} }
/**
* Express Middleware for handling remember-me authentication tokens
* @param {express.Request} req - Express Request Object
* @param {express.Response} res - Express Response Object
* @param {function} next - Function to call upon next middleware
*/
module.exports.rememberMeMiddleware = function(req, res, next){ module.exports.rememberMeMiddleware = function(req, res, next){
//if we have an un-authenticated user //if we have an un-authenticated user
if(req.session.user == null || req.session.user == ""){ if(req.session.user == null || req.session.user == ""){
@ -242,11 +236,8 @@ module.exports.rememberMeMiddleware = function(req, res, next){
res.clearCookie('rememberme.id'); res.clearCookie('rememberme.id');
res.clearCookie('rememberme.token'); res.clearCookie('rememberme.token');
//Quietly handle exceptions without pestering the user //Bitch, Moan, and guess what? That's fuckin' right! COMPLAIN!!!!
loggerUtils.localExceptionHandler(err); return loggerUtils.exceptionHandler(res, err);
//Go on with life
next();
}); });
}else{ }else{
//Jump to next middleware, this looks gross but it's only because they made me use .then like a bunch of fucking dicks //Jump to next middleware, this looks gross but it's only because they made me use .then like a bunch of fucking dicks