Fix jwt-token
This commit is contained in:
@@ -61,24 +61,19 @@ class AlertService {
|
||||
const droneTypeInfo = getDroneTypeInfo(droneType);
|
||||
|
||||
// Adjust threat level based on drone type and category
|
||||
if (droneType === 2 && rssi >= -70) { // Orlan - escalate to critical only if within medium range or closer
|
||||
if (droneTypeInfo.threat_level === 'critical' || droneTypeInfo.category.includes('Military')) {
|
||||
// Military/Combat drones - ALWAYS CRITICAL regardless of distance
|
||||
threatLevel = 'critical';
|
||||
description = `CRITICAL THREAT: ${droneTypeInfo.name.toUpperCase()} DETECTED - IMMEDIATE RESPONSE REQUIRED`;
|
||||
actionRequired = true;
|
||||
console.log(`🚨 ORLAN DRONE DETECTED: ${droneTypeInfo.name} - Escalating to CRITICAL threat level (RSSI: ${rssi})`);
|
||||
} else if (droneType === 2) { // Orlan at long range - still high priority but not critical
|
||||
if (threatLevel === 'low' || threatLevel === 'monitoring') threatLevel = 'medium';
|
||||
if (threatLevel === 'medium') threatLevel = 'high';
|
||||
description += ` - ${droneTypeInfo.name.toUpperCase()} DETECTED AT LONG RANGE`;
|
||||
actionRequired = true;
|
||||
console.log(`🚨 MILITARY DRONE DETECTED: ${droneTypeInfo.name} - Force escalating to CRITICAL threat level (RSSI: ${rssi})`);
|
||||
} else if (droneTypeInfo.threat_level === 'high' || droneTypeInfo.category.includes('Professional')) {
|
||||
// Professional/Commercial drone - escalate threat one level only if close enough
|
||||
if (rssi >= -70) { // Only escalate if medium distance or closer
|
||||
if (threatLevel === 'low') threatLevel = 'medium';
|
||||
if (threatLevel === 'medium') threatLevel = 'high';
|
||||
description += ` - ${droneTypeInfo.name.toUpperCase()} DETECTED`;
|
||||
actionRequired = true;
|
||||
}
|
||||
// Professional/Commercial drone - escalate threat one level
|
||||
if (threatLevel === 'low') threatLevel = 'medium';
|
||||
if (threatLevel === 'medium') threatLevel = 'high';
|
||||
if (threatLevel === 'high') threatLevel = 'critical';
|
||||
description += ` - ${droneTypeInfo.name.toUpperCase()} DETECTED`;
|
||||
actionRequired = true;
|
||||
} else if (droneTypeInfo.category.includes('Racing')) {
|
||||
// Racing/Fast drone - escalate if close
|
||||
if (rssi >= -55 && threatLevel !== 'critical') {
|
||||
@@ -700,6 +695,155 @@ class AlertService {
|
||||
`✅ No drone activity detected for 5+ minutes.\n` +
|
||||
`🛡️ Area is secure.`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check alert rules for a detection and trigger alerts if needed
|
||||
* @param {Object} detection - The drone detection object
|
||||
* @returns {Promise<Array>} - Array of triggered alerts
|
||||
*/
|
||||
async checkAlertRules(detection) {
|
||||
try {
|
||||
const rules = await AlertRule.findAll({
|
||||
where: {
|
||||
tenant_id: detection.tenant_id,
|
||||
is_active: true
|
||||
}
|
||||
});
|
||||
|
||||
const triggeredAlerts = [];
|
||||
|
||||
for (const rule of rules) {
|
||||
let shouldTrigger = true;
|
||||
|
||||
// Check drone type filter
|
||||
if (rule.drone_type !== null && rule.drone_type !== detection.drone_type) {
|
||||
shouldTrigger = false;
|
||||
}
|
||||
|
||||
// Check minimum RSSI
|
||||
if (rule.min_rssi !== null && detection.rssi < rule.min_rssi) {
|
||||
shouldTrigger = false;
|
||||
}
|
||||
|
||||
// Check maximum distance (if coordinates are available)
|
||||
if (rule.max_distance !== null && detection.geo_lat && detection.geo_lon) {
|
||||
// Calculate distance logic would go here
|
||||
// For now, assume within range
|
||||
}
|
||||
|
||||
if (shouldTrigger) {
|
||||
triggeredAlerts.push(rule);
|
||||
}
|
||||
}
|
||||
|
||||
return triggeredAlerts;
|
||||
} catch (error) {
|
||||
console.error('Error checking alert rules:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an alert to the database
|
||||
* @param {Object} rule - The alert rule that was triggered
|
||||
* @param {Object} detection - The detection that triggered the alert
|
||||
* @param {string} alertType - Type of alert (sms, email, etc.)
|
||||
* @param {string} recipient - Alert recipient
|
||||
* @returns {Promise<Object>} - The created alert log entry
|
||||
*/
|
||||
async logAlert(rule, detection, alertType = 'sms', recipient = 'test@example.com') {
|
||||
try {
|
||||
const alertLog = await AlertLog.create({
|
||||
alert_rule_id: rule.id,
|
||||
detection_id: detection.id,
|
||||
alert_type: alertType,
|
||||
recipient: recipient,
|
||||
message: `Alert triggered for ${rule.name}`,
|
||||
status: 'sent',
|
||||
sent_at: new Date()
|
||||
});
|
||||
|
||||
return alertLog;
|
||||
} catch (error) {
|
||||
console.error('Error logging alert:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a detection alert workflow
|
||||
* @param {Object} detection - The drone detection
|
||||
* @returns {Promise<Array>} - Array of processed alerts
|
||||
*/
|
||||
async processDetectionAlert(detection) {
|
||||
try {
|
||||
const triggeredRules = await this.checkAlertRules(detection);
|
||||
const processedAlerts = [];
|
||||
|
||||
for (const rule of triggeredRules) {
|
||||
// Assess threat level
|
||||
const threat = this.assessThreatLevel(detection.rssi, detection.drone_type);
|
||||
|
||||
// Log the alert
|
||||
const alertLog = await this.logAlert(rule, detection);
|
||||
|
||||
// Send notification if threshold is met
|
||||
if (threat.threatLevel === 'critical' || threat.threatLevel === 'high') {
|
||||
await this.sendSMSAlert(detection, threat, rule);
|
||||
}
|
||||
|
||||
processedAlerts.push({
|
||||
rule,
|
||||
threat,
|
||||
alertLog
|
||||
});
|
||||
}
|
||||
|
||||
return processedAlerts;
|
||||
} catch (error) {
|
||||
console.error('Error processing detection alert:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear expired alerts from active tracking
|
||||
* @returns {Promise<number>} - Number of alerts cleared
|
||||
*/
|
||||
async clearExpiredAlerts() {
|
||||
try {
|
||||
const expiredCount = this.activeAlerts.size;
|
||||
this.activeAlerts.clear();
|
||||
return expiredCount;
|
||||
} catch (error) {
|
||||
console.error('Error clearing expired alerts:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup old alerts from the database
|
||||
* @param {number} maxAge - Maximum age in milliseconds (default: 30 days)
|
||||
* @returns {Promise<number>} - Number of alerts cleaned up
|
||||
*/
|
||||
async cleanupOldAlerts(maxAge = 30 * 24 * 60 * 60 * 1000) {
|
||||
try {
|
||||
const cutoffDate = new Date(Date.now() - maxAge);
|
||||
|
||||
const deletedCount = await AlertLog.destroy({
|
||||
where: {
|
||||
sent_at: {
|
||||
[Op.lt]: cutoffDate
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return deletedCount;
|
||||
} catch (error) {
|
||||
console.error('Error cleaning up old alerts:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export the class directly (not a singleton instance)
|
||||
|
||||
@@ -280,6 +280,23 @@ class DroneTrackingService extends EventEmitter {
|
||||
|
||||
return activeTracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Track a new detection (alias for processDetection)
|
||||
* @param {Object} detection - The drone detection to track
|
||||
* @returns {Object} - Tracking result
|
||||
*/
|
||||
trackDetection(detection) {
|
||||
return this.processDetection(detection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all tracking data
|
||||
*/
|
||||
clear() {
|
||||
this.droneHistory.clear();
|
||||
this.droneProximityAlerts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DroneTrackingService;
|
||||
|
||||
Reference in New Issue
Block a user