Files
drone-detector/server/middleware/logger.js
2025-09-20 07:37:14 +02:00

109 lines
2.8 KiB
JavaScript

const fs = require('fs');
const path = require('path');
class SecurityLogger {
constructor() {
// Default to logs directory, but allow override via environment
this.logDir = process.env.SECURITY_LOG_DIR || path.join(__dirname, '..', 'logs');
this.logFile = path.join(this.logDir, 'security-audit.log');
// Ensure log directory exists
this.ensureLogDirectory();
}
ensureLogDirectory() {
try {
if (!fs.existsSync(this.logDir)) {
fs.mkdirSync(this.logDir, { recursive: true });
}
} catch (error) {
console.error('Failed to create log directory:', error.message);
// Fallback to console logging only
this.logFile = null;
}
}
logSecurityEvent(level, message, metadata = {}) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level: level.toUpperCase(),
message,
...metadata
};
// Always log to console for immediate visibility
console.log(`[SECURITY AUDIT] ${timestamp} - ${message}`);
// Also log to file if available
if (this.logFile) {
try {
const logLine = JSON.stringify(logEntry) + '\n';
fs.appendFileSync(this.logFile, logLine);
} catch (error) {
console.error('Failed to write to security log file:', error.message);
}
}
}
logIPRestriction(ip, tenant, userAgent, denied = true) {
const action = denied ? 'denied access to' : 'granted access to';
this.logSecurityEvent('WARNING', `IP ${ip} ${action} tenant ${tenant}`, {
type: 'IP_RESTRICTION',
ip,
tenant,
userAgent: userAgent || 'unknown',
denied
});
}
logAuthFailure(reason, metadata = {}) {
this.logSecurityEvent('ERROR', `Authentication failure: ${reason}`, {
type: 'AUTH_FAILURE',
reason,
...metadata
});
}
logSuspiciousActivity(activity, metadata = {}) {
this.logSecurityEvent('CRITICAL', `Suspicious activity detected: ${activity}`, {
type: 'SUSPICIOUS_ACTIVITY',
activity,
...metadata
});
}
// Get recent security events for monitoring
getRecentEvents(count = 100) {
if (!this.logFile || !fs.existsSync(this.logFile)) {
return [];
}
try {
const content = fs.readFileSync(this.logFile, 'utf8');
const lines = content.trim().split('\n').filter(line => line);
return lines
.slice(-count)
.map(line => {
try {
return JSON.parse(line);
} catch {
return null;
}
})
.filter(Boolean);
} catch (error) {
console.error('Failed to read security log file:', error.message);
return [];
}
}
}
// Singleton instance
const securityLogger = new SecurityLogger();
module.exports = {
SecurityLogger,
securityLogger
};