- Fixed unused function parameters by prefixing with underscore - Removed unused imports and variables - Applied eslint --fix for automatic style fixes - Property shorthand - String template literals - Prefer const over let where appropriate - Spacing and formatting Reduces lint errors from 108+ to 78 (61 unused vars, 17 other issues) Related to CI lint failures in previous commit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
72 lines
2.3 KiB
JavaScript
72 lines
2.3 KiB
JavaScript
/**
|
|
* Security Event Logger (inst_046 - Quick Win Version)
|
|
* Centralized logging for all security events
|
|
*
|
|
* QUICK WIN: Simple file-based logging with JSON format
|
|
* Full version in Phase 5 will add ProtonMail/Signal alerts
|
|
*/
|
|
|
|
const fs = require('fs').promises;
|
|
const path = require('path');
|
|
|
|
const SECURITY_LOG_PATH = process.env.SECURITY_LOG_PATH ||
|
|
(process.env.HOME ? `${process.env.HOME}/var/log/tractatus/security-audit.log` : '/var/log/tractatus/security-audit.log');
|
|
|
|
/**
|
|
* Log a security event to audit trail
|
|
*
|
|
* @param {Object} event - Security event details
|
|
* @param {string} event.type - Event type (e.g., 'rate_limit_violation')
|
|
* @param {string} event.sourceIp - Source IP address
|
|
* @param {string} event.userId - User ID (if authenticated)
|
|
* @param {string} event.endpoint - Request endpoint
|
|
* @param {string} event.userAgent - User agent string
|
|
* @param {Object} event.details - Additional event details
|
|
* @param {string} event.action - Action taken (e.g., 'blocked', 'logged')
|
|
* @param {string} event.severity - Severity level ('low', 'medium', 'high', 'critical')
|
|
*/
|
|
async function logSecurityEvent(event) {
|
|
const logEntry = {
|
|
timestamp: new Date().toISOString(),
|
|
event_type: event.type || 'unknown',
|
|
source_ip: event.sourceIp || 'unknown',
|
|
user_id: event.userId || 'anonymous',
|
|
endpoint: event.endpoint || 'unknown',
|
|
user_agent: event.userAgent || 'unknown',
|
|
violation_details: event.details || {},
|
|
action_taken: event.action || 'logged',
|
|
severity: event.severity || 'medium'
|
|
};
|
|
|
|
const logLine = `${JSON.stringify(logEntry) }\n`;
|
|
|
|
try {
|
|
// Ensure log directory exists
|
|
const logDir = path.dirname(SECURITY_LOG_PATH);
|
|
await fs.mkdir(logDir, { recursive: true, mode: 0o750 });
|
|
|
|
// Append to log file
|
|
await fs.appendFile(SECURITY_LOG_PATH, logLine, { encoding: 'utf-8' });
|
|
} catch (error) {
|
|
// Fallback to console if file logging fails
|
|
console.error('[SECURITY LOGGER ERROR]', error.message);
|
|
console.error('[SECURITY EVENT]', logEntry);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper: Extract client IP from request (handles proxies)
|
|
*/
|
|
function getClientIp(req) {
|
|
return (
|
|
req.ip ||
|
|
req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
|
|
req.connection.remoteAddress ||
|
|
'unknown'
|
|
);
|
|
}
|
|
|
|
module.exports = {
|
|
logSecurityEvent,
|
|
getClientIp
|
|
};
|