MFA
This commit is contained in:
73
backend/middleware/stepUpAuth.js
Normal file
73
backend/middleware/stepUpAuth.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const TwoFactorService = require("../services/TwoFactorService");
|
||||
const logger = require("../utils/logger");
|
||||
|
||||
/**
|
||||
* Middleware to require step-up authentication for sensitive actions.
|
||||
* Only applies to users who have 2FA enabled.
|
||||
*
|
||||
* @param {string} action - The sensitive action being protected
|
||||
* @returns {Function} Express middleware function
|
||||
*/
|
||||
const requireStepUpAuth = (action) => {
|
||||
return async (req, res, next) => {
|
||||
try {
|
||||
// If user doesn't have 2FA enabled, skip step-up requirement
|
||||
if (!req.user.twoFactorEnabled) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// Check if user has a valid step-up session (within 5 minutes)
|
||||
const isValid = TwoFactorService.validateStepUpSession(req.user);
|
||||
|
||||
if (!isValid) {
|
||||
logger.info(
|
||||
`Step-up authentication required for user ${req.user.id}, action: ${action}`
|
||||
);
|
||||
|
||||
return res.status(403).json({
|
||||
error: "Multi-factor authentication required",
|
||||
code: "STEP_UP_REQUIRED",
|
||||
action: action,
|
||||
methods: getTwoFactorMethods(req.user),
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
logger.error("Step-up auth middleware error:", error);
|
||||
return res.status(500).json({
|
||||
error: "An error occurred during authentication",
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get available 2FA methods for a user
|
||||
* @param {Object} user - User object
|
||||
* @returns {string[]} Array of available methods
|
||||
*/
|
||||
function getTwoFactorMethods(user) {
|
||||
const methods = [];
|
||||
|
||||
// Primary method is always available
|
||||
if (user.twoFactorMethod === "totp") {
|
||||
methods.push("totp");
|
||||
}
|
||||
|
||||
// Email is always available as a backup method
|
||||
methods.push("email");
|
||||
|
||||
// Recovery codes are available if any remain
|
||||
if (user.recoveryCodesHash) {
|
||||
const recoveryData = JSON.parse(user.recoveryCodesHash);
|
||||
const remaining = TwoFactorService.getRemainingRecoveryCodesCount(recoveryData);
|
||||
if (remaining > 0) {
|
||||
methods.push("recovery");
|
||||
}
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
module.exports = { requireStepUpAuth };
|
||||
Reference in New Issue
Block a user