Fix jwt-token

This commit is contained in:
2025-08-28 11:40:04 +02:00
parent f54a763ebb
commit 5919794408
6 changed files with 421 additions and 21 deletions

View File

@@ -2,6 +2,7 @@ const express = require('express');
const DroneDetection = require('../models/DroneDetection'); const DroneDetection = require('../models/DroneDetection');
const Device = require('../models/Device'); const Device = require('../models/Device');
const { authenticateToken } = require('../middleware/auth'); const { authenticateToken } = require('../middleware/auth');
const { getDroneTypeInfo } = require('../utils/droneTypes');
const router = express.Router(); const router = express.Router();
/** /**
@@ -66,8 +67,17 @@ router.get('/', authenticateToken, async (req, res) => {
const hasNextPage = parseInt(page) < totalPages; const hasNextPage = parseInt(page) < totalPages;
const hasPrevPage = parseInt(page) > 1; const hasPrevPage = parseInt(page) > 1;
// Enhance detections with drone type information
const enhancedDetections = detections.map(detection => {
const droneTypeInfo = getDroneTypeInfo(detection.drone_type);
return {
...detection.toJSON(),
drone_type_info: droneTypeInfo
};
});
res.json({ res.json({
detections, detections: enhancedDetections,
pagination: { pagination: {
currentPage: parseInt(page), currentPage: parseInt(page),
totalPages, totalPages,
@@ -107,7 +117,14 @@ router.get('/:id', authenticateToken, async (req, res) => {
return res.status(404).json({ error: 'Detection not found' }); return res.status(404).json({ error: 'Detection not found' });
} }
res.json(detection); // Enhance detection with drone type information
const droneTypeInfo = getDroneTypeInfo(detection.drone_type);
const enhancedDetection = {
...detection.toJSON(),
drone_type_info: droneTypeInfo
};
res.json(enhancedDetection);
} catch (error) { } catch (error) {
console.error('Error fetching detection:', error); console.error('Error fetching detection:', error);

View File

@@ -5,6 +5,7 @@ const { validateRequest } = require('../middleware/validation');
const { Heartbeat, Device, DroneDetection } = require('../models'); const { Heartbeat, Device, DroneDetection } = require('../models');
const AlertService = require('../services/alertService'); const AlertService = require('../services/alertService');
const DroneTrackingService = require('../services/droneTrackingService'); const DroneTrackingService = require('../services/droneTrackingService');
const { getDroneTypeInfo, getDroneTypeName } = require('../utils/droneTypes');
// Initialize services // Initialize services
const alertService = new AlertService(); const alertService = new AlertService();
@@ -191,7 +192,11 @@ async function handleHeartbeat(req, res) {
async function handleDetection(req, res) { async function handleDetection(req, res) {
const detectionData = req.body; const detectionData = req.body;
console.log(`🚁 Drone detection received from device ${detectionData.device_id}: drone_id=${detectionData.drone_id}, type=${detectionData.drone_type}, rssi=${detectionData.rssi}`); // Get drone type information
const droneTypeInfo = getDroneTypeInfo(detectionData.drone_type);
console.log(`🚁 Drone detection received from device ${detectionData.device_id}: drone_id=${detectionData.drone_id}, type=${detectionData.drone_type} (${droneTypeInfo.name}), rssi=${detectionData.rssi}`);
console.log(`🎯 Drone Type Details: ${droneTypeInfo.category} | Threat: ${droneTypeInfo.threat_level} | ${droneTypeInfo.description}`);
console.log('🔍 Complete detection data:', JSON.stringify(detectionData, null, 2)); console.log('🔍 Complete detection data:', JSON.stringify(detectionData, null, 2));
// Check if device exists and is approved // Check if device exists and is approved

160
server/routes/droneTypes.js Normal file
View File

@@ -0,0 +1,160 @@
const express = require('express');
const router = express.Router();
const {
getAllDroneTypes,
getDroneTypesByCategory,
getDroneTypesByThreatLevel,
getDroneTypeInfo
} = require('../utils/droneTypes');
/**
* GET /api/drone-types
* Get all available drone types
*/
router.get('/', (req, res) => {
try {
const droneTypes = getAllDroneTypes();
// Convert to array format with IDs
const droneTypesArray = Object.entries(droneTypes).map(([id, info]) => ({
id: parseInt(id),
...info
}));
res.json({
success: true,
data: droneTypesArray,
total: droneTypesArray.length
});
} catch (error) {
console.error('Error fetching drone types:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone types',
details: error.message
});
}
});
/**
* GET /api/drone-types/:id
* Get specific drone type by ID
*/
router.get('/:id', (req, res) => {
try {
const { id } = req.params;
const droneTypeInfo = getDroneTypeInfo(parseInt(id));
res.json({
success: true,
data: droneTypeInfo
});
} catch (error) {
console.error('Error fetching drone type:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone type',
details: error.message
});
}
});
/**
* GET /api/drone-types/category/:category
* Get drone types by category
*/
router.get('/category/:category', (req, res) => {
try {
const { category } = req.params;
const droneTypes = getDroneTypesByCategory(category);
res.json({
success: true,
data: droneTypes,
category: category,
total: droneTypes.length
});
} catch (error) {
console.error('Error fetching drone types by category:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone types by category',
details: error.message
});
}
});
/**
* GET /api/drone-types/threat/:threatLevel
* Get drone types by threat level
*/
router.get('/threat/:threatLevel', (req, res) => {
try {
const { threatLevel } = req.params;
const droneTypes = getDroneTypesByThreatLevel(threatLevel);
res.json({
success: true,
data: droneTypes,
threat_level: threatLevel,
total: droneTypes.length
});
} catch (error) {
console.error('Error fetching drone types by threat level:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone types by threat level',
details: error.message
});
}
});
/**
* GET /api/drone-types/categories
* Get all available categories
*/
router.get('/meta/categories', (req, res) => {
try {
const droneTypes = getAllDroneTypes();
const categories = [...new Set(Object.values(droneTypes).map(type => type.category))];
res.json({
success: true,
data: categories,
total: categories.length
});
} catch (error) {
console.error('Error fetching drone type categories:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone type categories',
details: error.message
});
}
});
/**
* GET /api/drone-types/threat-levels
* Get all available threat levels
*/
router.get('/meta/threat-levels', (req, res) => {
try {
const droneTypes = getAllDroneTypes();
const threatLevels = [...new Set(Object.values(droneTypes).map(type => type.threat_level))];
res.json({
success: true,
data: threatLevels,
total: threatLevels.length
});
} catch (error) {
console.error('Error fetching drone type threat levels:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch drone type threat levels',
details: error.message
});
}
});
module.exports = router;

View File

@@ -10,6 +10,7 @@ const healthRoutes = require('./health');
const debugRoutes = require('./debug'); const debugRoutes = require('./debug');
const detectorsRoutes = require('./detectors'); const detectorsRoutes = require('./detectors');
const detectionsRoutes = require('./detections'); const detectionsRoutes = require('./detections');
const droneTypesRoutes = require('./droneTypes');
// API versioning // API versioning
router.use('/v1/devices', deviceRoutes); router.use('/v1/devices', deviceRoutes);
@@ -19,6 +20,7 @@ router.use('/v1/dashboard', dashboardRoutes);
router.use('/v1/health', healthRoutes); router.use('/v1/health', healthRoutes);
router.use('/v1/detectors', detectorsRoutes); router.use('/v1/detectors', detectorsRoutes);
router.use('/v1/detections', detectionsRoutes); router.use('/v1/detections', detectionsRoutes);
router.use('/v1/drone-types', droneTypesRoutes);
// Default routes (no version prefix for backward compatibility) // Default routes (no version prefix for backward compatibility)
router.use('/devices', deviceRoutes); router.use('/devices', deviceRoutes);
@@ -29,6 +31,7 @@ router.use('/health', healthRoutes);
router.use('/debug', debugRoutes); router.use('/debug', debugRoutes);
router.use('/detectors', detectorsRoutes); router.use('/detectors', detectorsRoutes);
router.use('/detections', detectionsRoutes); router.use('/detections', detectionsRoutes);
router.use('/drone-types', droneTypesRoutes);
// API documentation endpoint // API documentation endpoint
router.get('/', (req, res) => { router.get('/', (req, res) => {

View File

@@ -1,6 +1,7 @@
const twilio = require('twilio'); const twilio = require('twilio');
const { AlertRule, AlertLog, User, Device, DroneDetection } = require('../models'); const { AlertRule, AlertLog, User, Device, DroneDetection } = require('../models');
const { Op } = require('sequelize'); const { Op } = require('sequelize');
const { getDroneTypeInfo } = require('../utils/droneTypes');
class AlertService { class AlertService {
constructor() { constructor() {
@@ -56,33 +57,28 @@ class AlertService {
actionRequired = false; actionRequired = false;
} }
// Adjust threat level based on drone type (if classified) // Get drone type information using our comprehensive mapping
const droneTypes = { const droneTypeInfo = getDroneTypeInfo(droneType);
0: 'Consumer/Hobby',
1: 'Orlan/Military', // Orlan drones - highest threat
2: 'Professional/Commercial',
3: 'Racing/High-speed',
4: 'Unknown/Custom'
};
// CRITICAL: Orlan drones (type 1) - ALWAYS CRITICAL regardless of distance // Adjust threat level based on drone type and category
if (droneType === 1) { if (droneTypeInfo.threat_level === 'critical' || droneTypeInfo.category.includes('Military')) {
// Military/Combat drones - ALWAYS CRITICAL regardless of distance
threatLevel = 'critical'; threatLevel = 'critical';
description = 'CRITICAL THREAT: ORLAN MILITARY DRONE DETECTED - IMMEDIATE RESPONSE REQUIRED'; description = `CRITICAL THREAT: ${droneTypeInfo.name.toUpperCase()} DETECTED - IMMEDIATE RESPONSE REQUIRED`;
actionRequired = true; actionRequired = true;
console.log(`🚨 ORLAN DRONE DETECTED - Force escalating to CRITICAL threat level (RSSI: ${rssi})`); console.log(`🚨 MILITARY DRONE DETECTED: ${droneTypeInfo.name} - Force escalating to CRITICAL threat level (RSSI: ${rssi})`);
} else if (droneType === 2) { } else if (droneTypeInfo.threat_level === 'high' || droneTypeInfo.category.includes('Professional')) {
// Professional/Commercial drone - escalate threat // Professional/Commercial drone - escalate threat one level
if (threatLevel === 'low') threatLevel = 'medium'; if (threatLevel === 'low') threatLevel = 'medium';
if (threatLevel === 'medium') threatLevel = 'high'; if (threatLevel === 'medium') threatLevel = 'high';
if (threatLevel === 'high') threatLevel = 'critical'; if (threatLevel === 'high') threatLevel = 'critical';
description += ' - PROFESSIONAL/COMMERCIAL DRONE DETECTED'; description += ` - ${droneTypeInfo.name.toUpperCase()} DETECTED`;
actionRequired = true; actionRequired = true;
} else if (droneType === 3) { } else if (droneTypeInfo.category.includes('Racing')) {
// Racing/Fast drone - escalate if close // Racing/Fast drone - escalate if close
if (rssi >= -55 && threatLevel !== 'critical') { if (rssi >= -55 && threatLevel !== 'critical') {
threatLevel = 'high'; threatLevel = 'high';
description += ' - HIGH-SPEED DRONE DETECTED'; description += ` - HIGH-SPEED ${droneTypeInfo.name.toUpperCase()} DETECTED`;
actionRequired = true; actionRequired = true;
} }
} }
@@ -91,7 +87,9 @@ class AlertService {
level: threatLevel, level: threatLevel,
estimatedDistance: Math.round(estimatedDistance), estimatedDistance: Math.round(estimatedDistance),
rssi, rssi,
droneType: droneTypes[droneType] || 'Unknown', droneType: droneTypeInfo.name,
droneCategory: droneTypeInfo.category,
threatLevel: droneTypeInfo.threat_level,
description, description,
requiresImmediateAction: actionRequired, requiresImmediateAction: actionRequired,
priority: threatLevel === 'critical' ? 1 : threatLevel === 'high' ? 2 : threatLevel === 'medium' ? 3 : 4 priority: threatLevel === 'critical' ? 1 : threatLevel === 'high' ? 2 : threatLevel === 'medium' ? 3 : 4

217
server/utils/droneTypes.js Normal file
View File

@@ -0,0 +1,217 @@
/**
* Drone Type Mappings
* Maps integer drone_type values to human-readable names and categories
*/
const DRONE_TYPES = {
// Military/Combat Drones
0: {
name: "Russian Orlan",
category: "Military/Reconnaissance",
threat_level: "high",
description: "Russian military reconnaissance drone"
},
1: {
name: "Bayraktar TB2",
category: "Military/Combat",
threat_level: "critical",
description: "Turkish military combat drone"
},
2: {
name: "MQ-9 Reaper",
category: "Military/Combat",
threat_level: "critical",
description: "US military combat drone"
},
3: {
name: "Iranian Shahed",
category: "Military/Kamikaze",
threat_level: "critical",
description: "Iranian kamikaze/suicide drone"
},
4: {
name: "Chinese Wing Loong",
category: "Military/Combat",
threat_level: "critical",
description: "Chinese military combat drone"
},
5: {
name: "Israeli Hermes",
category: "Military/Reconnaissance",
threat_level: "high",
description: "Israeli military reconnaissance drone"
},
// Commercial/Professional Drones
10: {
name: "DJI Mavic",
category: "Commercial/Professional",
threat_level: "medium",
description: "DJI professional quadcopter"
},
11: {
name: "DJI Phantom",
category: "Commercial/Professional",
threat_level: "medium",
description: "DJI professional quadcopter"
},
12: {
name: "DJI Inspire",
category: "Commercial/Professional",
threat_level: "medium",
description: "DJI professional cinematography drone"
},
13: {
name: "Autel EVO",
category: "Commercial/Professional",
threat_level: "medium",
description: "Autel professional quadcopter"
},
14: {
name: "Parrot Anafi",
category: "Commercial/Professional",
threat_level: "medium",
description: "Parrot professional quadcopter"
},
// Consumer/Hobby Drones
20: {
name: "DJI Mini",
category: "Consumer/Hobby",
threat_level: "low",
description: "DJI consumer mini drone"
},
21: {
name: "DJI Spark",
category: "Consumer/Hobby",
threat_level: "low",
description: "DJI consumer compact drone"
},
22: {
name: "Ryze Tello",
category: "Consumer/Hobby",
threat_level: "low",
description: "Consumer toy/education drone"
},
23: {
name: "Holy Stone",
category: "Consumer/Hobby",
threat_level: "low",
description: "Consumer hobby quadcopter"
},
24: {
name: "Syma X5C",
category: "Consumer/Hobby",
threat_level: "low",
description: "Consumer toy quadcopter"
},
// Racing/FPV Drones
30: {
name: "Racing Quadcopter",
category: "Racing/FPV",
threat_level: "low",
description: "Custom racing/FPV quadcopter"
},
31: {
name: "TinyHawk",
category: "Racing/FPV",
threat_level: "low",
description: "Micro racing quadcopter"
},
// Fixed-Wing Drones
40: {
name: "Fixed-Wing Surveillance",
category: "Fixed-Wing/Surveillance",
threat_level: "medium",
description: "Fixed-wing surveillance aircraft"
},
41: {
name: "Fixed-Wing Cargo",
category: "Fixed-Wing/Commercial",
threat_level: "medium",
description: "Fixed-wing cargo/delivery aircraft"
},
// Unknown/Unclassified
99: {
name: "Unknown Drone",
category: "Unknown/Unclassified",
threat_level: "medium",
description: "Unidentified or unclassified drone"
}
};
/**
* Get drone type information by ID
* @param {number} droneTypeId - The integer drone type ID
* @returns {object} Drone type information or default for unknown types
*/
function getDroneTypeInfo(droneTypeId) {
const typeInfo = DRONE_TYPES[droneTypeId];
if (typeInfo) {
return {
id: droneTypeId,
...typeInfo
};
}
// Return default for unknown types
return {
id: droneTypeId,
name: `Unknown Type ${droneTypeId}`,
category: "Unknown/Unclassified",
threat_level: "medium",
description: `Unrecognized drone type ID: ${droneTypeId}`
};
}
/**
* Get just the drone name by ID
* @param {number} droneTypeId - The integer drone type ID
* @returns {string} Drone name
*/
function getDroneTypeName(droneTypeId) {
return getDroneTypeInfo(droneTypeId).name;
}
/**
* Get all available drone types
* @returns {object} All drone type mappings
*/
function getAllDroneTypes() {
return DRONE_TYPES;
}
/**
* Get drone types by category
* @param {string} category - The category to filter by
* @returns {array} Array of drone types in the category
*/
function getDroneTypesByCategory(category) {
return Object.entries(DRONE_TYPES)
.filter(([id, info]) => info.category === category)
.map(([id, info]) => ({ id: parseInt(id), ...info }));
}
/**
* Get drone types by threat level
* @param {string} threatLevel - The threat level to filter by
* @returns {array} Array of drone types with the threat level
*/
function getDroneTypesByThreatLevel(threatLevel) {
return Object.entries(DRONE_TYPES)
.filter(([id, info]) => info.threat_level === threatLevel)
.map(([id, info]) => ({ id: parseInt(id), ...info }));
}
module.exports = {
DRONE_TYPES,
getDroneTypeInfo,
getDroneTypeName,
getAllDroneTypes,
getDroneTypesByCategory,
getDroneTypesByThreatLevel
};