Files
freeplanet_serverside/src/middleware/securityMiddleware.js
Surya Paolo 00bdc278d8 - aggiornato la guida per installare la App
- aggiornato la Guida Completa e Breve di RISO.
- pagina per ricevere i RIS.
- sistemato problema creazione nuovi Circuiti (admin non corretti).
- corretto giro delle email, invitante, invitato e ricezione msg su telegram.
2025-11-23 01:13:32 +01:00

152 lines
3.2 KiB
JavaScript

/**
* Security Middleware
* Handles rate limiting, IP blocking, and failed login attempts
*/
// Dictionary to track failed login attempts
const failedLoginAttempts = {};
// Constants
const MAX_FAILED_ATTEMPTS = 30;
const BLOCK_DURATION = 30 * 60 * 1000; // 30 minutes
/**
* Block user after too many failed attempts
*/
function blockUser(username) {
failedLoginAttempts[username] = Date.now() + BLOCK_DURATION;
}
/**
* Check if user is blocked
*/
function isUserBlocked(username) {
const now = Date.now();
return failedLoginAttempts[username] && failedLoginAttempts[username] > now;
}
/**
* Clear failed attempts for user (on successful login)
*/
function clearFailedAttempts(username) {
delete failedLoginAttempts[username];
}
/**
* Middleware to check if user is blocked before login
*/
function checkBlocked(req, res, next) {
const { username } = req.body;
console.log('checkBlocked');
if (!username) {
return res.status(400).json({
message: 'Username mancante',
});
}
if (isUserBlocked(username)) {
const text = `Utente bloccato. Riprova più tardi. (username=${username})`;
console.log(text);
return res.status(403).json({
message: 'Utente bloccato. Riprova più tardi.',
});
}
next();
}
/**
* Get failed attempts count for a user
*/
function getFailedAttempts(username) {
return failedLoginAttempts[username] || 0;
}
/**
* Increment failed attempts
*/
function incrementFailedAttempts(username) {
if (typeof failedLoginAttempts[username] === 'number') {
failedLoginAttempts[username]++;
} else {
failedLoginAttempts[username] = 1;
}
return failedLoginAttempts[username];
}
/**
* Check if user should be blocked after this attempt
*/
function shouldBlockUser(username) {
return (failedLoginAttempts[username] || 0) >= MAX_FAILED_ATTEMPTS;
}
/**
* Middleware to rate limit API requests per IP
*/
const requestCounts = {};
const REQUEST_WINDOW = 60 * 1000; // 1 minute
const MAX_REQUESTS = 100; // per window
function rateLimitByIP(req, res, next) {
const tools = require('../tools/general');
const ip = tools.getiPAddressUser(req);
const now = Date.now();
if (!requestCounts[ip]) {
requestCounts[ip] = {
count: 1,
resetTime: now + REQUEST_WINDOW,
};
return next();
}
if (now > requestCounts[ip].resetTime) {
// Reset window
requestCounts[ip] = {
count: 1,
resetTime: now + REQUEST_WINDOW,
};
return next();
}
if (requestCounts[ip].count >= MAX_REQUESTS) {
return res.status(429).json({
message: 'Troppi tentativi. Riprova più tardi.',
});
}
requestCounts[ip].count++;
next();
}
/**
* Clean up old blocked users (run periodically)
*/
function cleanupBlockedUsers() {
const now = Date.now();
Object.keys(failedLoginAttempts).forEach((username) => {
if (typeof failedLoginAttempts[username] === 'number' && failedLoginAttempts[username] < now) {
delete failedLoginAttempts[username];
}
});
}
// Run cleanup every 10 minutes
setInterval(cleanupBlockedUsers, 10 * 60 * 1000);
module.exports = {
checkBlocked,
blockUser,
isUserBlocked,
clearFailedAttempts,
getFailedAttempts,
incrementFailedAttempts,
shouldBlockUser,
rateLimitByIP,
MAX_FAILED_ATTEMPTS,
BLOCK_DURATION,
};