import { SECURITY_MONITORING } from "./constants"; import { type AuditLogContext, type AuditOutcome, AuditSeverity, SecurityEventType, securityAuditLogger, } from "./securityAuditLogger"; import { AlertManagementService } from "./services/AlertManagementService"; import { SecurityEventProcessor } from "./services/SecurityEventProcessor"; import { SecurityMetricsService } from "./services/SecurityMetricsService"; import { ThreatDetectionService } from "./services/ThreatDetectionService"; // Utility type for deep partial objects type DeepPartial = { [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; }; export interface SecurityAlert { id: string; timestamp: Date; severity: AlertSeverity; type: AlertType; title: string; description: string; eventType: SecurityEventType; context: AuditLogContext; metadata: Record; acknowledged: boolean; acknowledgedBy?: string; acknowledgedAt?: Date; } /* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */ export enum AlertSeverity { LOW = "LOW", MEDIUM = "MEDIUM", HIGH = "HIGH", CRITICAL = "CRITICAL", } /* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */ export enum AlertType { AUTHENTICATION_ANOMALY = "AUTHENTICATION_ANOMALY", RATE_LIMIT_BREACH = "RATE_LIMIT_BREACH", MULTIPLE_FAILED_LOGINS = "MULTIPLE_FAILED_LOGINS", SUSPICIOUS_IP_ACTIVITY = "SUSPICIOUS_IP_ACTIVITY", PRIVILEGE_ESCALATION = "PRIVILEGE_ESCALATION", DATA_BREACH_ATTEMPT = "DATA_BRECH_ATTEMPT", CSRF_ATTACK = "CSRF_ATTACK", CSP_VIOLATION_SPIKE = "CSP_VIOLATION_SPIKE", ACCOUNT_ENUMERATION = "ACCOUNT_ENUMERATION", BRUTE_FORCE_ATTACK = "BRUTE_FORCE_ATTACK", UNUSUAL_ADMIN_ACTIVITY = "UNUSUAL_ADMIN_ACTIVITY", GEOLOCATION_ANOMALY = "GEOLOCATION_ANOMALY", MASS_DATA_ACCESS = "MASS_DATA_ACCESS", SUSPICIOUS_USER_AGENT = "SUSPICIOUS_USER_AGENT", SESSION_HIJACKING = "SESSION_HIJACKING", } /* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */ export interface SecurityMetrics { totalEvents: number; criticalEvents: number; activeAlerts: number; resolvedAlerts: number; securityScore: number; threatLevel: ThreatLevel; eventsByType: Record; alertsByType: Record; topThreats: Array<{ type: AlertType; count: number }>; geoDistribution: Record; timeDistribution: Array<{ hour: number; count: number }>; userRiskScores: Array<{ userId: string; email: string; riskScore: number }>; } /* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */ export enum ThreatLevel { LOW = "LOW", MODERATE = "MODERATE", HIGH = "HIGH", CRITICAL = "CRITICAL", } /* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */ export interface MonitoringConfig { thresholds: { failedLoginsPerMinute: number; failedLoginsPerHour: number; rateLimitViolationsPerMinute: number; cspViolationsPerMinute: number; adminActionsPerHour: number; massDataAccessThreshold: number; suspiciousIPThreshold: number; }; alerting: { enabled: boolean; channels: AlertChannel[]; suppressDuplicateMinutes: number; escalationTimeoutMinutes: number; }; retention: { alertRetentionDays: number; metricsRetentionDays: number; }; } /* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */ export enum AlertChannel { EMAIL = "EMAIL", WEBHOOK = "WEBHOOK", SLACK = "SLACK", DISCORD = "DISCORD", PAGERDUTY = "PAGERDUTY", } /* eslint-enable @typescript-eslint/no-unused-vars, no-unused-vars */ export interface AnomalyDetectionResult { isAnomaly: boolean; confidence: number; type: string; description: string; recommendedActions: string[]; } /** * Refactored SecurityMonitoringService that coordinates focused services * Responsibilities: Configuration, coordination, and background processing */ class SecurityMonitoringService { private config: MonitoringConfig; private eventProcessor: SecurityEventProcessor; private threatDetection: ThreatDetectionService; private alertManagement: AlertManagementService; private metricsService: SecurityMetricsService; constructor() { this.config = this.getDefaultConfig(); // Initialize focused services this.eventProcessor = new SecurityEventProcessor(); this.threatDetection = new ThreatDetectionService(this.config); this.alertManagement = new AlertManagementService(this.config); this.metricsService = new SecurityMetricsService(); this.startBackgroundProcessing(); } /** * Process security event and check for threats */ async processSecurityEvent( eventType: SecurityEventType, outcome: AuditOutcome, context: AuditLogContext, severity: AuditSeverity = AuditSeverity.INFO, metadata?: Record ): Promise { // Add event to buffer for analysis this.eventProcessor.addEvent(eventType, outcome, context, severity); // Immediate threat detection const threatResult = await this.threatDetection.detectImmediateThreats( eventType, outcome, context, metadata ); for (const threat of threatResult.threats) { await this.alertManagement.createAlert(threat); } // Anomaly detection const recentEvents = this.eventProcessor.getRecentEvents(); const anomaly = await this.threatDetection.detectAnomalies( eventType, context, recentEvents ); if (anomaly.isAnomaly && anomaly.confidence > 0.7) { await this.alertManagement.createAlert({ severity: this.mapConfidenceToSeverity(anomaly.confidence), type: AlertType.AUTHENTICATION_ANOMALY, title: `Anomaly Detected: ${anomaly.type}`, description: anomaly.description, eventType, context, metadata: { anomaly, confidence: anomaly.confidence }, }); } // Clean old events to prevent memory issues this.eventProcessor.cleanup(); } /** * Get comprehensive security metrics */ async getSecurityMetrics( timeRange: { start: Date; end: Date }, companyId?: string ): Promise { const alerts = this.alertManagement.getAlertsInTimeRange(timeRange); return this.metricsService.calculateSecurityMetrics( timeRange, companyId, alerts ); } /** * Get active security alerts */ getActiveAlerts(severity?: AlertSeverity): SecurityAlert[] { return this.alertManagement.getActiveAlerts(severity); } /** * Acknowledge an alert */ async acknowledgeAlert( alertId: string, acknowledgedBy: string ): Promise { return this.alertManagement.acknowledgeAlert(alertId, acknowledgedBy); } /** * Export security data for analysis */ exportSecurityData( format: "json" | "csv", timeRange: { start: Date; end: Date } ): string { return this.alertManagement.exportAlertsData(format, timeRange); } /** * Configure monitoring thresholds */ updateConfig(config: DeepPartial): void { this.config = this.deepMerge(this.config, config); } /** * Deep merge helper function for config updates */ private deepMerge( target: Record, source: Record ): Record { const result = { ...target }; for (const key in source) { if ( source[key] !== null && typeof source[key] === "object" && !Array.isArray(source[key]) ) { result[key] = this.deepMerge(target[key] || {}, source[key]); } else { result[key] = source[key]; } } return result; } /** * Get current monitoring configuration */ getConfig(): MonitoringConfig { return { ...this.config }; } /** * Calculate threat level for a specific IP */ async calculateIPThreatLevel(ipAddress: string): Promise<{ threatLevel: ThreatLevel; riskFactors: string[]; recommendations: string[]; isBlacklisted: boolean; }> { return this.metricsService.calculateIPThreatLevel(ipAddress); } private mapConfidenceToSeverity(confidence: number): AlertSeverity { if (confidence >= 0.9) return AlertSeverity.CRITICAL; if (confidence >= 0.8) return AlertSeverity.HIGH; if (confidence >= 0.6) return AlertSeverity.MEDIUM; return AlertSeverity.LOW; } private getDefaultConfig(): MonitoringConfig { return { thresholds: { failedLoginsPerMinute: 5, failedLoginsPerHour: 20, rateLimitViolationsPerMinute: 10, cspViolationsPerMinute: 15, adminActionsPerHour: 25, massDataAccessThreshold: 100, suspiciousIPThreshold: 10, }, alerting: { enabled: process.env.SECURITY_ALERTING_ENABLED !== "false", channels: [AlertChannel.EMAIL], suppressDuplicateMinutes: 10, escalationTimeoutMinutes: 60, }, retention: { alertRetentionDays: 90, metricsRetentionDays: 365, }, }; } private startBackgroundProcessing(): void { // Clean up old data every cleanup interval setInterval(() => { this.cleanupOldData(); }, SECURITY_MONITORING.EVENT_BUFFER_CLEANUP_INTERVAL); // Process event buffer for threat detection setInterval(() => { this.processEventBuffer(); }, SECURITY_MONITORING.BACKGROUND_PROCESSING_INTERVAL); } private cleanupOldData(): void { this.alertManagement.cleanupOldAlerts(); this.eventProcessor.cleanup(); } private async processEventBuffer(): Promise { // Analyze patterns in event buffer for real-time threat detection const recentEvents = this.eventProcessor.getRecentEvents(); // Check for event spikes if (recentEvents.length > 50) { await this.alertManagement.createAlert({ severity: AlertSeverity.MEDIUM, type: AlertType.SUSPICIOUS_IP_ACTIVITY, title: "High Event Volume Detected", description: `${recentEvents.length} security events in the last minute`, eventType: SecurityEventType.API_SECURITY, context: { requestId: crypto.randomUUID() }, metadata: { eventCount: recentEvents.length }, }); } } } // Singleton instance export const securityMonitoring = new SecurityMonitoringService(); // Helper function to integrate with existing audit logger export async function enhancedSecurityLog( eventType: SecurityEventType, action: string, outcome: AuditOutcome, context: AuditLogContext, severity: AuditSeverity = AuditSeverity.INFO, errorMessage?: string, metadata?: Record ): Promise { // Log to audit system await securityAuditLogger.log({ eventType, action, outcome, severity, errorMessage, context, }); // Process through security monitoring await securityMonitoring.processSecurityEvent( eventType, outcome, context, severity, metadata ); }