mcp-wordpress 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/security/AISecurityScanner.d.ts +175 -0
  2. package/dist/security/AISecurityScanner.d.ts.map +1 -0
  3. package/dist/security/AISecurityScanner.js +645 -0
  4. package/dist/security/AISecurityScanner.js.map +1 -0
  5. package/dist/security/AutomatedRemediation.d.ts +145 -0
  6. package/dist/security/AutomatedRemediation.d.ts.map +1 -0
  7. package/dist/security/AutomatedRemediation.js +535 -0
  8. package/dist/security/AutomatedRemediation.js.map +1 -0
  9. package/dist/security/SecurityCIPipeline.d.ts +213 -0
  10. package/dist/security/SecurityCIPipeline.d.ts.map +1 -0
  11. package/dist/security/SecurityCIPipeline.js +684 -0
  12. package/dist/security/SecurityCIPipeline.js.map +1 -0
  13. package/dist/security/SecurityConfigManager.d.ts +294 -0
  14. package/dist/security/SecurityConfigManager.d.ts.map +1 -0
  15. package/dist/security/SecurityConfigManager.js +553 -0
  16. package/dist/security/SecurityConfigManager.js.map +1 -0
  17. package/dist/security/SecurityMonitoring.d.ts +245 -0
  18. package/dist/security/SecurityMonitoring.d.ts.map +1 -0
  19. package/dist/security/SecurityMonitoring.js +596 -0
  20. package/dist/security/SecurityMonitoring.js.map +1 -0
  21. package/dist/security/SecurityReviewer.d.ts +168 -0
  22. package/dist/security/SecurityReviewer.d.ts.map +1 -0
  23. package/dist/security/SecurityReviewer.js +683 -0
  24. package/dist/security/SecurityReviewer.js.map +1 -0
  25. package/dist/security/index.d.ts +182 -0
  26. package/dist/security/index.d.ts.map +1 -0
  27. package/dist/security/index.js +189 -0
  28. package/dist/security/index.js.map +1 -0
  29. package/package.json +8 -3
  30. package/src/security/AISecurityScanner.ts +780 -0
  31. package/src/security/AutomatedRemediation.ts +665 -0
  32. package/src/security/SecurityCIPipeline.ts +969 -0
  33. package/src/security/SecurityConfigManager.ts +829 -0
  34. package/src/security/SecurityMonitoring.ts +841 -0
  35. package/src/security/SecurityReviewer.ts +855 -0
  36. package/src/security/index.ts +249 -0
@@ -0,0 +1,841 @@
1
+ /**
2
+ * Security Monitoring and Alerting System
3
+ * Provides real-time security monitoring, threat detection, and incident response
4
+ */
5
+
6
+ import { EventEmitter } from "events";
7
+ import { SecurityUtils } from "./SecurityConfig";
8
+
9
+ export interface SecurityEvent {
10
+ id: string;
11
+ timestamp: Date;
12
+ type: "authentication" | "authorization" | "input-validation" | "data-access" | "system" | "anomaly";
13
+ severity: "critical" | "high" | "medium" | "low";
14
+ source: string;
15
+ details: {
16
+ userId?: string;
17
+ sessionId?: string;
18
+ ipAddress?: string;
19
+ userAgent?: string;
20
+ endpoint?: string;
21
+ method?: string;
22
+ payload?: any;
23
+ error?: string;
24
+ metadata?: Record<string, any>;
25
+ };
26
+ description: string;
27
+ riskScore: number;
28
+ handled: boolean;
29
+ actions: SecurityAction[];
30
+ }
31
+
32
+ interface SecurityAction {
33
+ id: string;
34
+ type: "block" | "throttle" | "alert" | "log" | "investigate" | "escalate";
35
+ timestamp: Date;
36
+ automated: boolean;
37
+ result: "success" | "failure" | "pending";
38
+ details: string;
39
+ }
40
+
41
+ interface SecurityAlert {
42
+ id: string;
43
+ eventId: string;
44
+ timestamp: Date;
45
+ severity: "critical" | "high" | "medium" | "low";
46
+ title: string;
47
+ description: string;
48
+ category: string;
49
+ affectedSystems: string[];
50
+ indicators: {
51
+ type: string;
52
+ value: string;
53
+ confidence: number;
54
+ }[];
55
+ recommendations: string[];
56
+ status: "new" | "investigating" | "resolved" | "false-positive";
57
+ assignee?: string;
58
+ resolution?: {
59
+ timestamp: Date;
60
+ action: string;
61
+ details: string;
62
+ };
63
+ }
64
+
65
+ interface ThreatIntelligence {
66
+ id: string;
67
+ type: "ip" | "domain" | "hash" | "pattern" | "signature";
68
+ value: string;
69
+ confidence: number;
70
+ severity: "critical" | "high" | "medium" | "low";
71
+ source: string;
72
+ description: string;
73
+ indicators: string[];
74
+ lastSeen: Date;
75
+ expiry?: Date;
76
+ }
77
+
78
+ interface SecurityMetrics {
79
+ timestamp: Date;
80
+ events: {
81
+ total: number;
82
+ byType: Record<string, number>;
83
+ bySeverity: Record<string, number>;
84
+ };
85
+ threats: {
86
+ blocked: number;
87
+ detected: number;
88
+ investigated: number;
89
+ };
90
+ alerts: {
91
+ new: number;
92
+ resolved: number;
93
+ falsePositives: number;
94
+ };
95
+ performance: {
96
+ responseTime: number;
97
+ detectionRate: number;
98
+ falsePositiveRate: number;
99
+ };
100
+ }
101
+
102
+ interface AnomalyPattern {
103
+ id: string;
104
+ type: "traffic" | "authentication" | "access" | "behavior";
105
+ pattern: string;
106
+ threshold: number;
107
+ timeWindow: number;
108
+ description: string;
109
+ enabled: boolean;
110
+ }
111
+
112
+ /**
113
+ * Real-time Security Monitor
114
+ */
115
+ export class SecurityMonitor extends EventEmitter {
116
+ private events: SecurityEvent[] = [];
117
+ private alerts: SecurityAlert[] = [];
118
+ private threatIntel: Map<string, ThreatIntelligence> = new Map();
119
+ private anomalyPatterns: AnomalyPattern[] = [];
120
+ private metrics: SecurityMetrics[] = [];
121
+ private isMonitoring = false;
122
+ private metricsInterval?: NodeJS.Timeout | undefined;
123
+
124
+ constructor() {
125
+ super();
126
+ this.initializeAnomalyPatterns();
127
+ }
128
+
129
+ /**
130
+ * Start security monitoring
131
+ */
132
+ start(): void {
133
+ if (this.isMonitoring) {
134
+ console.warn("[Security Monitor] Already monitoring");
135
+ return;
136
+ }
137
+
138
+ this.isMonitoring = true;
139
+ console.log("[Security Monitor] Starting security monitoring");
140
+
141
+ // Start metrics collection
142
+ this.metricsInterval = setInterval(() => {
143
+ this.collectMetrics();
144
+ }, 60000); // Every minute
145
+
146
+ this.emit("monitoring-started");
147
+ }
148
+
149
+ /**
150
+ * Stop security monitoring
151
+ */
152
+ stop(): void {
153
+ if (!this.isMonitoring) {
154
+ console.warn("[Security Monitor] Not currently monitoring");
155
+ return;
156
+ }
157
+
158
+ this.isMonitoring = false;
159
+
160
+ if (this.metricsInterval) {
161
+ clearInterval(this.metricsInterval);
162
+ this.metricsInterval = undefined;
163
+ }
164
+
165
+ console.log("[Security Monitor] Stopped security monitoring");
166
+ this.emit("monitoring-stopped");
167
+ }
168
+
169
+ /**
170
+ * Log security event
171
+ */
172
+ async logSecurityEvent(
173
+ eventData: Omit<SecurityEvent, "id" | "timestamp" | "handled" | "actions">,
174
+ ): Promise<SecurityEvent> {
175
+ const event: SecurityEvent = {
176
+ ...eventData,
177
+ id: SecurityUtils.generateSecureToken(16),
178
+ timestamp: new Date(),
179
+ handled: false,
180
+ actions: [],
181
+ };
182
+
183
+ this.events.push(event);
184
+
185
+ // Process event in real-time
186
+ await this.processSecurityEvent(event);
187
+
188
+ // Check for anomalies
189
+ await this.checkForAnomalies(event);
190
+
191
+ // Emit event for real-time processing
192
+ this.emit("security-event", event);
193
+
194
+ console.log(`[Security Monitor] Logged ${event.severity} event: ${event.type} - ${event.description}`);
195
+
196
+ return event;
197
+ }
198
+
199
+ /**
200
+ * Process security event and take automated actions
201
+ */
202
+ private async processSecurityEvent(event: SecurityEvent): Promise<void> {
203
+ const actions: SecurityAction[] = [];
204
+
205
+ // High-severity events get immediate attention
206
+ if (event.severity === "critical" || event.severity === "high") {
207
+ actions.push(await this.createAction("alert", event, true));
208
+
209
+ if (event.type === "authentication" && event.details.ipAddress) {
210
+ // Consider blocking suspicious IPs
211
+ const suspiciousActivity = await this.checkSuspiciousActivity(event.details.ipAddress);
212
+ if (suspiciousActivity) {
213
+ actions.push(await this.createAction("block", event, true));
214
+ }
215
+ }
216
+ }
217
+
218
+ // Rate limiting for authentication events
219
+ if (event.type === "authentication" && event.details.userId) {
220
+ const failedAttempts = await this.getFailedAuthAttempts(event.details.userId);
221
+ if (failedAttempts > 5) {
222
+ actions.push(await this.createAction("throttle", event, true));
223
+ }
224
+ }
225
+
226
+ // Check against threat intelligence
227
+ if (event.details.ipAddress) {
228
+ const threat = this.threatIntel.get(event.details.ipAddress);
229
+ if (threat) {
230
+ actions.push(await this.createAction("block", event, true));
231
+ actions.push(await this.createAction("alert", event, true));
232
+ }
233
+ }
234
+
235
+ event.actions = actions;
236
+ event.handled = actions.length > 0;
237
+
238
+ // Create alert if necessary
239
+ if (event.severity === "critical" || (event.severity === "high" && event.riskScore > 7)) {
240
+ await this.createAlert(event);
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Create security action
246
+ */
247
+ private async createAction(
248
+ type: SecurityAction["type"],
249
+ event: SecurityEvent,
250
+ automated: boolean,
251
+ ): Promise<SecurityAction> {
252
+ const action: SecurityAction = {
253
+ id: SecurityUtils.generateSecureToken(12),
254
+ type,
255
+ timestamp: new Date(),
256
+ automated,
257
+ result: "pending",
258
+ details: `${type} action triggered for ${event.type} event`,
259
+ };
260
+
261
+ try {
262
+ // Execute the action
263
+ switch (type) {
264
+ case "block":
265
+ await this.executeBlockAction(event);
266
+ break;
267
+ case "throttle":
268
+ await this.executeThrottleAction(event);
269
+ break;
270
+ case "alert":
271
+ await this.executeAlertAction(event);
272
+ break;
273
+ case "log":
274
+ await this.executeLogAction(event);
275
+ break;
276
+ default:
277
+ console.log(`[Security Monitor] Action ${type} queued for manual processing`);
278
+ }
279
+
280
+ action.result = "success";
281
+ action.details += " - executed successfully";
282
+ } catch (error) {
283
+ action.result = "failure";
284
+ action.details += ` - failed: ${error instanceof Error ? error.message : String(error)}`;
285
+ console.error(`[Security Monitor] Action ${type} failed:`, error);
286
+ }
287
+
288
+ return action;
289
+ }
290
+
291
+ /**
292
+ * Execute block action
293
+ */
294
+ private async executeBlockAction(event: SecurityEvent): Promise<void> {
295
+ if (event.details.ipAddress) {
296
+ console.log(`[Security Monitor] Blocking IP: ${event.details.ipAddress}`);
297
+ // In a real implementation, this would interface with firewall/load balancer
298
+ this.emit("ip-blocked", { ip: event.details.ipAddress, reason: event.description });
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Execute throttle action
304
+ */
305
+ private async executeThrottleAction(event: SecurityEvent): Promise<void> {
306
+ if (event.details.userId) {
307
+ console.log(`[Security Monitor] Throttling user: ${event.details.userId}`);
308
+ // In a real implementation, this would apply rate limiting
309
+ this.emit("user-throttled", { userId: event.details.userId, reason: event.description });
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Execute alert action
315
+ */
316
+ private async executeAlertAction(event: SecurityEvent): Promise<void> {
317
+ console.log(`[Security Monitor] Alert triggered for event: ${event.id}`);
318
+ this.emit("security-alert", event);
319
+ }
320
+
321
+ /**
322
+ * Execute log action
323
+ */
324
+ private async executeLogAction(event: SecurityEvent): Promise<void> {
325
+ console.log(`[Security Monitor] Enhanced logging for event: ${event.id}`);
326
+ // Additional detailed logging would go here
327
+ }
328
+
329
+ /**
330
+ * Create security alert
331
+ */
332
+ private async createAlert(event: SecurityEvent): Promise<SecurityAlert> {
333
+ const alert: SecurityAlert = {
334
+ id: SecurityUtils.generateSecureToken(16),
335
+ eventId: event.id,
336
+ timestamp: new Date(),
337
+ severity: event.severity,
338
+ title: `Security Alert: ${event.type}`,
339
+ description: event.description,
340
+ category: event.type,
341
+ affectedSystems: [event.source],
342
+ indicators: this.extractIndicators(event),
343
+ recommendations: this.generateRecommendations(event),
344
+ status: "new",
345
+ };
346
+
347
+ this.alerts.push(alert);
348
+
349
+ console.log(`[Security Monitor] Created ${alert.severity} alert: ${alert.title}`);
350
+ this.emit("alert-created", alert);
351
+
352
+ return alert;
353
+ }
354
+
355
+ /**
356
+ * Extract indicators from security event
357
+ */
358
+ private extractIndicators(event: SecurityEvent): SecurityAlert["indicators"] {
359
+ const indicators: SecurityAlert["indicators"] = [];
360
+
361
+ if (event.details.ipAddress) {
362
+ indicators.push({
363
+ type: "ip-address",
364
+ value: event.details.ipAddress,
365
+ confidence: 0.8,
366
+ });
367
+ }
368
+
369
+ if (event.details.userAgent) {
370
+ indicators.push({
371
+ type: "user-agent",
372
+ value: event.details.userAgent,
373
+ confidence: 0.6,
374
+ });
375
+ }
376
+
377
+ if (event.details.endpoint) {
378
+ indicators.push({
379
+ type: "endpoint",
380
+ value: event.details.endpoint,
381
+ confidence: 0.7,
382
+ });
383
+ }
384
+
385
+ return indicators;
386
+ }
387
+
388
+ /**
389
+ * Generate recommendations for event
390
+ */
391
+ private generateRecommendations(event: SecurityEvent): string[] {
392
+ const recommendations: string[] = [];
393
+
394
+ switch (event.type) {
395
+ case "authentication":
396
+ recommendations.push("Review authentication logs for patterns");
397
+ recommendations.push("Consider implementing multi-factor authentication");
398
+ if (event.severity === "high" || event.severity === "critical") {
399
+ recommendations.push("Temporarily block suspicious IP addresses");
400
+ }
401
+ break;
402
+
403
+ case "authorization":
404
+ recommendations.push("Review user permissions and access controls");
405
+ recommendations.push("Audit privilege escalation attempts");
406
+ break;
407
+
408
+ case "input-validation":
409
+ recommendations.push("Review input validation rules");
410
+ recommendations.push("Update WAF rules if applicable");
411
+ break;
412
+
413
+ case "data-access":
414
+ recommendations.push("Review data access patterns");
415
+ recommendations.push("Implement data loss prevention measures");
416
+ break;
417
+
418
+ case "system":
419
+ recommendations.push("Check system integrity");
420
+ recommendations.push("Review system logs for correlating events");
421
+ break;
422
+
423
+ case "anomaly":
424
+ recommendations.push("Investigate unusual patterns");
425
+ recommendations.push("Tune anomaly detection thresholds");
426
+ break;
427
+ }
428
+
429
+ return recommendations;
430
+ }
431
+
432
+ /**
433
+ * Check for suspicious activity from IP
434
+ */
435
+ private async checkSuspiciousActivity(ipAddress: string): Promise<boolean> {
436
+ const recentEvents = this.events.filter(
437
+ (event) => event.details.ipAddress === ipAddress && event.timestamp.getTime() > Date.now() - 3600000, // Last hour
438
+ );
439
+
440
+ // Multiple failed authentication attempts
441
+ const failedAuth = recentEvents.filter((event) => event.type === "authentication" && event.severity === "high");
442
+
443
+ if (failedAuth.length > 5) {
444
+ return true;
445
+ }
446
+
447
+ // Multiple different user attempts from same IP
448
+ const userIds = new Set(recentEvents.map((event) => event.details.userId).filter(Boolean));
449
+ if (userIds.size > 10) {
450
+ return true;
451
+ }
452
+
453
+ return false;
454
+ }
455
+
456
+ /**
457
+ * Get failed authentication attempts for user
458
+ */
459
+ private async getFailedAuthAttempts(userId: string): Promise<number> {
460
+ const recentEvents = this.events.filter(
461
+ (event) =>
462
+ event.type === "authentication" &&
463
+ event.details.userId === userId &&
464
+ event.severity === "high" &&
465
+ event.timestamp.getTime() > Date.now() - 900000, // Last 15 minutes
466
+ );
467
+
468
+ return recentEvents.length;
469
+ }
470
+
471
+ /**
472
+ * Check for anomalies
473
+ */
474
+ private async checkForAnomalies(event: SecurityEvent): Promise<void> {
475
+ for (const pattern of this.anomalyPatterns) {
476
+ if (!pattern.enabled) continue;
477
+
478
+ if (await this.matchesAnomalyPattern(event, pattern)) {
479
+ await this.logSecurityEvent({
480
+ type: "anomaly",
481
+ severity: "medium",
482
+ source: "anomaly-detection",
483
+ description: `Anomaly detected: ${pattern.description}`,
484
+ riskScore: 5,
485
+ details: {
486
+ metadata: { pattern: pattern.pattern, patternId: pattern.id, originalEvent: event.id },
487
+ },
488
+ });
489
+ }
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Check if event matches anomaly pattern
495
+ */
496
+ private async matchesAnomalyPattern(event: SecurityEvent, pattern: AnomalyPattern): Promise<boolean> {
497
+ // Simplified pattern matching - in practice this would be more sophisticated
498
+ const timeWindow = Date.now() - pattern.timeWindow;
499
+ const relatedEvents = this.events.filter((e) => e.timestamp.getTime() > timeWindow && e.type === event.type);
500
+
501
+ switch (pattern.type) {
502
+ case "traffic":
503
+ return relatedEvents.length > pattern.threshold;
504
+
505
+ case "authentication":
506
+ return event.type === "authentication" && relatedEvents.length > pattern.threshold;
507
+
508
+ case "access":
509
+ return event.type === "data-access" && relatedEvents.length > pattern.threshold;
510
+
511
+ case "behavior":
512
+ // Check for unusual user behavior patterns
513
+ if (event.details.userId) {
514
+ const userEvents = relatedEvents.filter((e) => e.details.userId === event.details.userId);
515
+ return userEvents.length > pattern.threshold;
516
+ }
517
+ return false;
518
+
519
+ default:
520
+ return false;
521
+ }
522
+ }
523
+
524
+ /**
525
+ * Initialize default anomaly patterns
526
+ */
527
+ private initializeAnomalyPatterns(): void {
528
+ this.anomalyPatterns = [
529
+ {
530
+ id: "high-auth-failures",
531
+ type: "authentication",
532
+ pattern: "failed-auth-attempts",
533
+ threshold: 10,
534
+ timeWindow: 300000, // 5 minutes
535
+ description: "High number of authentication failures",
536
+ enabled: true,
537
+ },
538
+ {
539
+ id: "unusual-access-pattern",
540
+ type: "access",
541
+ pattern: "data-access-spike",
542
+ threshold: 50,
543
+ timeWindow: 900000, // 15 minutes
544
+ description: "Unusual data access pattern",
545
+ enabled: true,
546
+ },
547
+ {
548
+ id: "traffic-spike",
549
+ type: "traffic",
550
+ pattern: "request-volume",
551
+ threshold: 100,
552
+ timeWindow: 300000, // 5 minutes
553
+ description: "Traffic volume spike",
554
+ enabled: true,
555
+ },
556
+ {
557
+ id: "user-behavior-anomaly",
558
+ type: "behavior",
559
+ pattern: "user-activity",
560
+ threshold: 20,
561
+ timeWindow: 3600000, // 1 hour
562
+ description: "Unusual user behavior pattern",
563
+ enabled: true,
564
+ },
565
+ ];
566
+ }
567
+
568
+ /**
569
+ * Collect security metrics
570
+ */
571
+ private collectMetrics(): void {
572
+ const now = new Date();
573
+ const hourAgo = new Date(now.getTime() - 3600000);
574
+
575
+ const recentEvents = this.events.filter((event) => event.timestamp > hourAgo);
576
+ const recentAlerts = this.alerts.filter((alert) => alert.timestamp > hourAgo);
577
+
578
+ const metrics: SecurityMetrics = {
579
+ timestamp: now,
580
+ events: {
581
+ total: recentEvents.length,
582
+ byType: this.groupBy(recentEvents, "type"),
583
+ bySeverity: this.groupBy(recentEvents, "severity"),
584
+ },
585
+ threats: {
586
+ blocked: recentEvents.filter((e) => e.actions.some((a) => a.type === "block")).length,
587
+ detected: recentEvents.filter((e) => e.riskScore > 5).length,
588
+ investigated: recentAlerts.filter((a) => a.status === "investigating").length,
589
+ },
590
+ alerts: {
591
+ new: recentAlerts.filter((a) => a.status === "new").length,
592
+ resolved: recentAlerts.filter((a) => a.status === "resolved").length,
593
+ falsePositives: recentAlerts.filter((a) => a.status === "false-positive").length,
594
+ },
595
+ performance: {
596
+ responseTime: this.calculateAverageResponseTime(recentEvents),
597
+ detectionRate: this.calculateDetectionRate(recentEvents),
598
+ falsePositiveRate: this.calculateFalsePositiveRate(recentAlerts),
599
+ },
600
+ };
601
+
602
+ this.metrics.push(metrics);
603
+
604
+ // Keep only last 24 hours of metrics
605
+ const dayAgo = new Date(now.getTime() - 86400000);
606
+ this.metrics = this.metrics.filter((m) => m.timestamp > dayAgo);
607
+
608
+ this.emit("metrics-collected", metrics);
609
+ }
610
+
611
+ /**
612
+ * Group array by property
613
+ */
614
+ private groupBy(array: any[], property: string): Record<string, number> {
615
+ return array.reduce((acc, item) => {
616
+ const key = item[property] || "unknown";
617
+ acc[key] = (acc[key] || 0) + 1;
618
+ return acc;
619
+ }, {});
620
+ }
621
+
622
+ /**
623
+ * Calculate average response time for security events
624
+ */
625
+ private calculateAverageResponseTime(events: SecurityEvent[]): number {
626
+ const handledEvents = events.filter((e) => e.handled && e.actions.length > 0);
627
+ if (handledEvents.length === 0) return 0;
628
+
629
+ const totalTime = handledEvents.reduce((sum, event) => {
630
+ const firstAction = event.actions[0];
631
+ if (firstAction) {
632
+ return sum + (firstAction.timestamp.getTime() - event.timestamp.getTime());
633
+ }
634
+ return sum;
635
+ }, 0);
636
+
637
+ return totalTime / handledEvents.length;
638
+ }
639
+
640
+ /**
641
+ * Calculate detection rate
642
+ */
643
+ private calculateDetectionRate(events: SecurityEvent[]): number {
644
+ const totalEvents = events.length;
645
+ if (totalEvents === 0) return 1;
646
+
647
+ const detectedEvents = events.filter((e) => e.handled || e.riskScore > 3).length;
648
+ return detectedEvents / totalEvents;
649
+ }
650
+
651
+ /**
652
+ * Calculate false positive rate
653
+ */
654
+ private calculateFalsePositiveRate(alerts: SecurityAlert[]): number {
655
+ const totalAlerts = alerts.length;
656
+ if (totalAlerts === 0) return 0;
657
+
658
+ const falsePositives = alerts.filter((a) => a.status === "false-positive").length;
659
+ return falsePositives / totalAlerts;
660
+ }
661
+
662
+ /**
663
+ * Add threat intelligence
664
+ */
665
+ addThreatIntelligence(threat: ThreatIntelligence): void {
666
+ this.threatIntel.set(threat.value, threat);
667
+ console.log(`[Security Monitor] Added threat intelligence: ${threat.type} - ${threat.value}`);
668
+ }
669
+
670
+ /**
671
+ * Remove threat intelligence
672
+ */
673
+ removeThreatIntelligence(value: string): boolean {
674
+ const removed = this.threatIntel.delete(value);
675
+ if (removed) {
676
+ console.log(`[Security Monitor] Removed threat intelligence: ${value}`);
677
+ }
678
+ return removed;
679
+ }
680
+
681
+ /**
682
+ * Update alert status
683
+ */
684
+ updateAlertStatus(alertId: string, status: SecurityAlert["status"], assignee?: string): boolean {
685
+ const alert = this.alerts.find((a) => a.id === alertId);
686
+ if (!alert) {
687
+ return false;
688
+ }
689
+
690
+ alert.status = status;
691
+ if (assignee) {
692
+ alert.assignee = assignee;
693
+ }
694
+
695
+ if (status === "resolved") {
696
+ alert.resolution = {
697
+ timestamp: new Date(),
698
+ action: "manual-resolution",
699
+ details: "Alert marked as resolved",
700
+ };
701
+ }
702
+
703
+ console.log(`[Security Monitor] Updated alert ${alertId} status to ${status}`);
704
+ this.emit("alert-updated", alert);
705
+ return true;
706
+ }
707
+
708
+ /**
709
+ * Get security events
710
+ */
711
+ getEvents(
712
+ options: {
713
+ limit?: number;
714
+ offset?: number;
715
+ severity?: string;
716
+ type?: string;
717
+ since?: Date;
718
+ } = {},
719
+ ): SecurityEvent[] {
720
+ let events = [...this.events];
721
+
722
+ if (options.since) {
723
+ events = events.filter((e) => e.timestamp >= options.since!);
724
+ }
725
+
726
+ if (options.severity) {
727
+ events = events.filter((e) => e.severity === options.severity);
728
+ }
729
+
730
+ if (options.type) {
731
+ events = events.filter((e) => e.type === options.type);
732
+ }
733
+
734
+ // Sort by timestamp (newest first)
735
+ events.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
736
+
737
+ if (options.offset) {
738
+ events = events.slice(options.offset);
739
+ }
740
+
741
+ if (options.limit) {
742
+ events = events.slice(0, options.limit);
743
+ }
744
+
745
+ return events;
746
+ }
747
+
748
+ /**
749
+ * Get security alerts
750
+ */
751
+ getAlerts(
752
+ options: {
753
+ limit?: number;
754
+ offset?: number;
755
+ severity?: string;
756
+ status?: string;
757
+ since?: Date;
758
+ } = {},
759
+ ): SecurityAlert[] {
760
+ let alerts = [...this.alerts];
761
+
762
+ if (options.since) {
763
+ alerts = alerts.filter((a) => a.timestamp >= options.since!);
764
+ }
765
+
766
+ if (options.severity) {
767
+ alerts = alerts.filter((a) => a.severity === options.severity);
768
+ }
769
+
770
+ if (options.status) {
771
+ alerts = alerts.filter((a) => a.status === options.status);
772
+ }
773
+
774
+ // Sort by timestamp (newest first)
775
+ alerts.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
776
+
777
+ if (options.offset) {
778
+ alerts = alerts.slice(options.offset);
779
+ }
780
+
781
+ if (options.limit) {
782
+ alerts = alerts.slice(0, options.limit);
783
+ }
784
+
785
+ return alerts;
786
+ }
787
+
788
+ /**
789
+ * Get security metrics
790
+ */
791
+ getMetrics(
792
+ options: {
793
+ since?: Date;
794
+ until?: Date;
795
+ } = {},
796
+ ): SecurityMetrics[] {
797
+ let metrics = [...this.metrics];
798
+
799
+ if (options.since) {
800
+ metrics = metrics.filter((m) => m.timestamp >= options.since!);
801
+ }
802
+
803
+ if (options.until) {
804
+ metrics = metrics.filter((m) => m.timestamp <= options.until!);
805
+ }
806
+
807
+ return metrics.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
808
+ }
809
+
810
+ /**
811
+ * Get system status
812
+ */
813
+ getStatus(): {
814
+ monitoring: boolean;
815
+ eventsToday: number;
816
+ alertsOpen: number;
817
+ threatsBlocked: number;
818
+ systemHealth: "healthy" | "degraded" | "critical";
819
+ } {
820
+ const today = new Date();
821
+ today.setHours(0, 0, 0, 0);
822
+
823
+ const eventsToday = this.events.filter((e) => e.timestamp >= today).length;
824
+ const alertsOpen = this.alerts.filter((a) => a.status === "new" || a.status === "investigating").length;
825
+ const threatsBlocked = this.events.filter(
826
+ (e) => e.timestamp >= today && e.actions.some((a) => a.type === "block"),
827
+ ).length;
828
+
829
+ let systemHealth: "healthy" | "degraded" | "critical" = "healthy";
830
+ if (alertsOpen > 10) systemHealth = "critical";
831
+ else if (alertsOpen > 5 || eventsToday > 100) systemHealth = "degraded";
832
+
833
+ return {
834
+ monitoring: this.isMonitoring,
835
+ eventsToday,
836
+ alertsOpen,
837
+ threatsBlocked,
838
+ systemHealth,
839
+ };
840
+ }
841
+ }