Core services for activity logging system: 1. ActivityLog Service (backend/src/services/activityLog.js) - Centralized logging with fire-and-forget pattern - 18 action constants (auth, event, match, admin, chat) - Query interface with filtering (date, action, user, category) - Socket.IO emission for real-time streaming - Statistics and action types endpoints - Never throws - logging cannot crash app 2. Request Utility (backend/src/utils/request.js) - getClientIP() - Extract client IP from headers/socket - Handles X-Forwarded-For and X-Real-IP proxy headers - IPv6-mapped IPv4 conversion 3. Admin Middleware (backend/src/middleware/admin.js) - requireAdmin() - Protect admin routes - Fresh DB check of isAdmin flag - Returns 403 for non-admin users - Use after authenticate middleware Next phases: logging integration points, API endpoints, frontend UI
53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
/**
|
|
* Request utility functions
|
|
* Helpers for extracting information from Express requests
|
|
*/
|
|
|
|
/**
|
|
* Extract client IP address from request
|
|
* Considers proxy headers (X-Forwarded-For, X-Real-IP)
|
|
*
|
|
* @param {Object} req - Express request object
|
|
* @returns {string|null} - Client IP address or null
|
|
*/
|
|
function getClientIP(req) {
|
|
try {
|
|
// Check X-Forwarded-For header (used by proxies/load balancers)
|
|
const forwardedFor = req.headers['x-forwarded-for'];
|
|
if (forwardedFor) {
|
|
// X-Forwarded-For can contain multiple IPs, take the first one (client IP)
|
|
const ips = forwardedFor.split(',').map(ip => ip.trim());
|
|
if (ips.length > 0 && ips[0]) {
|
|
return ips[0];
|
|
}
|
|
}
|
|
|
|
// Check X-Real-IP header (used by some proxies)
|
|
const realIP = req.headers['x-real-ip'];
|
|
if (realIP) {
|
|
return realIP;
|
|
}
|
|
|
|
// Fallback to req.ip (Express built-in)
|
|
if (req.ip) {
|
|
// Express sometimes returns IPv6-mapped IPv4 (::ffff:192.168.1.1)
|
|
// Convert to standard IPv4 format
|
|
return req.ip.replace(/^::ffff:/, '');
|
|
}
|
|
|
|
// Fallback to socket remote address
|
|
if (req.connection && req.connection.remoteAddress) {
|
|
return req.connection.remoteAddress.replace(/^::ffff:/, '');
|
|
}
|
|
|
|
return null;
|
|
} catch (error) {
|
|
console.error('Error extracting client IP:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
getClientIP,
|
|
};
|