/** * Security Audit Logger for Data Retention Access * Logs all access attempts to data retention metrics */ const fs = require('fs').promises; const path = require('path'); class DataRetentionAuditLogger { constructor() { this.logDir = process.env.SECURITY_LOG_DIR || './logs'; this.logFile = path.join(this.logDir, 'data_retention_access.log'); this.loggedWriteError = false; // Flag to avoid spamming write error messages } async ensureLogDir() { try { await fs.mkdir(this.logDir, { recursive: true }); } catch (error) { console.error('Failed to create security log directory:', error); } } async logAccess(event) { try { await this.ensureLogDir(); const logEntry = { timestamp: new Date().toISOString(), event: event.type, user: { id: event.user?.id, username: event.user?.username, role: event.user?.role }, request: { ip: event.ip, userAgent: event.userAgent, endpoint: event.endpoint, method: event.method }, result: event.result, error: event.error }; const logLine = JSON.stringify(logEntry) + '\n'; try { await fs.appendFile(this.logFile, logLine, 'utf8'); } catch (writeError) { // Fallback to console logging if file writing fails (e.g., permission issues) console.log('[DATA_RETENTION_AUDIT]', JSON.stringify(logEntry)); // Only log the file write error once to avoid spam if (!this.loggedWriteError) { console.warn('Failed to write security log to file, using console logging:', writeError.message); this.loggedWriteError = true; } } } catch (error) { // Fallback to console logging for any errors console.log('[DATA_RETENTION_AUDIT_ERROR]', error.message); console.log('[DATA_RETENTION_AUDIT_FALLBACK]', JSON.stringify({ timestamp: new Date().toISOString(), event: event.type || 'UNKNOWN', result: event.result || 'error', error: event.error || error.message })); } } // Log successful access async logSuccess(user, req, endpoint) { await this.logAccess({ type: 'DATA_RETENTION_ACCESS_SUCCESS', user, ip: req.ip, userAgent: req.headers['user-agent'], endpoint, method: req.method, result: 'success' }); } // Log authentication failure async logAuthFailure(req, endpoint, reason) { await this.logAccess({ type: 'DATA_RETENTION_ACCESS_AUTH_FAILED', ip: req.ip, userAgent: req.headers['user-agent'], endpoint, method: req.method, result: 'auth_failed', error: reason }); } // Log permission denied async logPermissionDenied(user, req, endpoint, reason) { await this.logAccess({ type: 'DATA_RETENTION_ACCESS_PERMISSION_DENIED', user, ip: req.ip, userAgent: req.headers['user-agent'], endpoint, method: req.method, result: 'permission_denied', error: reason }); } // Log network access denied async logNetworkDenied(req, endpoint) { await this.logAccess({ type: 'DATA_RETENTION_ACCESS_NETWORK_DENIED', ip: req.ip, userAgent: req.headers['user-agent'], endpoint, method: req.method, result: 'network_denied', error: 'Access from unauthorized network' }); } } module.exports = new DataRetentionAuditLogger();