Fix jwt-token
This commit is contained in:
@@ -158,24 +158,57 @@ class AlertService {
|
||||
model: User,
|
||||
as: 'user',
|
||||
where: { is_active: true }
|
||||
}]
|
||||
}],
|
||||
order: [
|
||||
// Order by priority: critical, high, medium, low
|
||||
['priority', 'DESC']
|
||||
]
|
||||
});
|
||||
|
||||
console.log(`📋 Found ${alertRules.length} active alert rules`);
|
||||
|
||||
// ENHANCED: Filter rules that match this detection and find the highest priority one
|
||||
const matchingRules = [];
|
||||
|
||||
for (const rule of alertRules) {
|
||||
if (await this.shouldTriggerAlert(rule, detection, threatAssessment)) {
|
||||
await this.triggerAlert(rule, detection, threatAssessment);
|
||||
|
||||
// Track active alert for potential clear notification
|
||||
const alertKey = `${rule.id}-${detection.device_id}`;
|
||||
this.activeAlerts.set(alertKey, {
|
||||
rule,
|
||||
detection,
|
||||
threatAssessment,
|
||||
alertTime: new Date()
|
||||
});
|
||||
matchingRules.push(rule);
|
||||
console.log(`✅ Rule "${rule.name}" matches (priority: ${rule.priority})`);
|
||||
} else {
|
||||
console.log(`❌ Rule "${rule.name}" does not match conditions`);
|
||||
}
|
||||
}
|
||||
|
||||
if (matchingRules.length === 0) {
|
||||
console.log('📭 No alert rules match this detection');
|
||||
return;
|
||||
}
|
||||
|
||||
// PRIORITY-BASED DEDUPLICATION: Only trigger the highest priority rule
|
||||
const highestPriorityRule = matchingRules[0]; // Already sorted by priority DESC
|
||||
|
||||
console.log(`🎯 ALERT DEDUPLICATION: ${matchingRules.length} rules matched, triggering only highest priority:`);
|
||||
console.log(` Selected Rule: "${highestPriorityRule.name}" (priority: ${highestPriorityRule.priority})`);
|
||||
|
||||
if (matchingRules.length > 1) {
|
||||
console.log(` Skipped Rules:`);
|
||||
matchingRules.slice(1).forEach(rule => {
|
||||
console.log(` - "${rule.name}" (priority: ${rule.priority})`);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger only the highest priority alert
|
||||
await this.triggerAlert(highestPriorityRule, detection, threatAssessment);
|
||||
|
||||
// Track active alert for potential clear notification
|
||||
const alertKey = `${highestPriorityRule.id}-${detection.device_id}`;
|
||||
this.activeAlerts.set(alertKey, {
|
||||
rule: highestPriorityRule,
|
||||
detection,
|
||||
threatAssessment,
|
||||
alertTime: new Date()
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error processing alert:', error);
|
||||
throw error;
|
||||
@@ -184,64 +217,84 @@ class AlertService {
|
||||
|
||||
async shouldTriggerAlert(rule, detection, threatAssessment) {
|
||||
try {
|
||||
// CRITICAL SECURITY: Orlan drones (type 1) ALWAYS trigger alerts regardless of any other conditions
|
||||
if (detection.drone_type === 1) {
|
||||
console.log(`🚨 ORLAN DRONE DETECTED - Force triggering alert for rule ${rule.name} (bypassing all filters)`);
|
||||
console.log(`🔍 Evaluating rule "${rule.name}" for detection from device ${detection.device_id}`);
|
||||
|
||||
// PRIORITY 1: Device-specific filter (most important)
|
||||
if (rule.device_ids && rule.device_ids.length > 0) {
|
||||
if (!rule.device_ids.includes(detection.device_id)) {
|
||||
console.log(`❌ Rule "${rule.name}": Device ${detection.device_id} not in allowed devices [${rule.device_ids.join(', ')}]`);
|
||||
return false;
|
||||
} else {
|
||||
console.log(`✅ Rule "${rule.name}": Device ${detection.device_id} is in allowed devices`);
|
||||
}
|
||||
} else {
|
||||
console.log(`✅ Rule "${rule.name}": No device filter (applies to all devices)`);
|
||||
}
|
||||
|
||||
// PRIORITY 2: Critical threats and Orlan drones (security overrides)
|
||||
const isOrlanDrone = detection.drone_type === 1;
|
||||
const isCriticalThreat = threatAssessment.level === 'critical';
|
||||
|
||||
if (isOrlanDrone) {
|
||||
console.log(`🚨 ORLAN DRONE DETECTED - Rule "${rule.name}" will trigger (security override)`);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isCriticalThreat) {
|
||||
console.log(`🚨 CRITICAL THREAT DETECTED - Rule "${rule.name}" will trigger (security override)`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SECURITY ENHANCEMENT: Check threat level requirements
|
||||
// PRIORITY 3: Threat level requirements
|
||||
if (rule.min_threat_level) {
|
||||
const threatLevels = { 'monitoring': 0, 'low': 1, 'medium': 2, 'high': 3, 'critical': 4 };
|
||||
const requiredLevel = threatLevels[rule.min_threat_level] || 0;
|
||||
const currentLevel = threatLevels[threatAssessment.level] || 0;
|
||||
|
||||
if (currentLevel < requiredLevel) {
|
||||
console.log(`Alert rule ${rule.name}: Threat level ${threatAssessment.level} below minimum ${rule.min_threat_level}`);
|
||||
console.log(`❌ Rule "${rule.name}": Threat level ${threatAssessment.level} below minimum ${rule.min_threat_level}`);
|
||||
return false;
|
||||
} else {
|
||||
console.log(`✅ Rule "${rule.name}": Threat level ${threatAssessment.level} meets minimum ${rule.min_threat_level}`);
|
||||
}
|
||||
}
|
||||
|
||||
// SECURITY ENHANCEMENT: For government/sensitive sites, always alert on critical threats
|
||||
if (threatAssessment.level === 'critical') {
|
||||
console.log(`🚨 CRITICAL THREAT DETECTED - Force triggering alert for rule ${rule.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check device filter
|
||||
if (rule.device_ids && rule.device_ids.length > 0 &&
|
||||
!rule.device_ids.includes(detection.device_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check drone type filter
|
||||
// PRIORITY 4: Drone type filter
|
||||
if (rule.drone_types && rule.drone_types.length > 0 &&
|
||||
!rule.drone_types.includes(detection.drone_type)) {
|
||||
console.log(`❌ Rule "${rule.name}": Drone type ${detection.drone_type} not in allowed types [${rule.drone_types.join(', ')}]`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check RSSI thresholds (enhanced for security)
|
||||
// PRIORITY 5: RSSI thresholds (distance-based)
|
||||
if (rule.min_rssi && detection.rssi < rule.min_rssi) {
|
||||
console.log(`❌ Rule "${rule.name}": RSSI ${detection.rssi} below minimum ${rule.min_rssi}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// SECURITY ENHANCEMENT: Check estimated distance
|
||||
if (rule.max_rssi && detection.rssi > rule.max_rssi) {
|
||||
console.log(`❌ Rule "${rule.name}": RSSI ${detection.rssi} above maximum ${rule.max_rssi}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// PRIORITY 6: Distance requirements
|
||||
if (rule.max_distance && threatAssessment.estimatedDistance > rule.max_distance) {
|
||||
console.log(`Alert rule ${rule.name}: Distance ${threatAssessment.estimatedDistance}m exceeds maximum ${rule.max_distance}m`);
|
||||
console.log(`❌ Rule "${rule.name}": Distance ${threatAssessment.estimatedDistance}m exceeds maximum ${rule.max_distance}m`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check frequency ranges
|
||||
// PRIORITY 7: Frequency ranges
|
||||
if (rule.frequency_ranges && rule.frequency_ranges.length > 0) {
|
||||
const inRange = rule.frequency_ranges.some(range =>
|
||||
detection.freq >= range.min && detection.freq <= range.max
|
||||
);
|
||||
if (!inRange) {
|
||||
console.log(`❌ Rule "${rule.name}": Frequency ${detection.freq}MHz not in allowed ranges`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check time window and minimum detections
|
||||
// PRIORITY 8: Time window and minimum detections
|
||||
if (rule.min_detections > 1) {
|
||||
const timeWindowStart = new Date(Date.now() - rule.time_window * 1000);
|
||||
const recentDetections = await DroneDetection.count({
|
||||
@@ -255,11 +308,12 @@ class AlertService {
|
||||
});
|
||||
|
||||
if (recentDetections < rule.min_detections) {
|
||||
console.log(`❌ Rule "${rule.name}": Only ${recentDetections} detections, need ${rule.min_detections}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check cooldown period
|
||||
// PRIORITY 9: Cooldown period check
|
||||
if (rule.cooldown_period > 0) {
|
||||
const cooldownStart = new Date(Date.now() - rule.cooldown_period * 1000);
|
||||
const recentAlert = await AlertLog.findOne({
|
||||
@@ -281,11 +335,12 @@ class AlertService {
|
||||
});
|
||||
|
||||
if (recentAlert) {
|
||||
console.log(`❌ Rule "${rule.name}": Still in cooldown period`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check active hours and days
|
||||
// PRIORITY 10: Active hours and days
|
||||
if (rule.active_hours || rule.active_days) {
|
||||
const now = new Date();
|
||||
const currentHour = now.getHours();
|
||||
@@ -294,6 +349,7 @@ class AlertService {
|
||||
const currentDay = now.getDay() || 7; // Convert Sunday from 0 to 7
|
||||
|
||||
if (rule.active_days && !rule.active_days.includes(currentDay)) {
|
||||
console.log(`❌ Rule "${rule.name}": Not active on day ${currentDay}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -305,11 +361,13 @@ class AlertService {
|
||||
if (startTime <= endTime) {
|
||||
// Same day range
|
||||
if (currentTime < startTime || currentTime > endTime) {
|
||||
console.log(`❌ Rule "${rule.name}": Outside active hours`);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Overnight range
|
||||
if (currentTime < startTime && currentTime > endTime) {
|
||||
console.log(`❌ Rule "${rule.name}": Outside active hours (overnight)`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -317,10 +375,11 @@ class AlertService {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ Rule "${rule.name}": All conditions met - WILL TRIGGER`);
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error checking alert conditions:', error);
|
||||
console.error(`Error evaluating alert rule ${rule.name}:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user