From f779b799c0888b33e09cadb6d9755ac5f32b81ce Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Tue, 23 Sep 2025 06:20:37 +0200 Subject: [PATCH] Fix jwt-token --- server/routes/detectors.js | 147 +++++++++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 5 deletions(-) diff --git a/server/routes/detectors.js b/server/routes/detectors.js index 08a303c..ef3e952 100644 --- a/server/routes/detectors.js +++ b/server/routes/detectors.js @@ -306,13 +306,150 @@ async function handleDetection(req, res) { isDebugDetection = true; } - // Create detection record with string device_id - const detectionRecord = { - ...detectionData, - device_id: deviceIdString, // Use the string version for consistency - server_timestamp: new Date() + // Validate and convert data types to match database schema + const validateAndConvertDetectionData = (data) => { + const errors = []; + const converted = {}; + + // Required fields validation and conversion + try { + // device_id - already converted to string above + converted.device_id = deviceIdString; + + // drone_id - must be BIGINT (convert to integer) + if (data.drone_id === undefined || data.drone_id === null) { + errors.push('drone_id is required'); + } else { + const droneId = parseInt(data.drone_id); + if (isNaN(droneId)) { + errors.push(`drone_id must be a number, received: ${data.drone_id}`); + } else { + converted.drone_id = droneId; + } + } + + // drone_type - must be INTEGER + if (data.drone_type === undefined || data.drone_type === null) { + errors.push('drone_type is required'); + } else { + const droneType = parseInt(data.drone_type); + if (isNaN(droneType) || droneType < 0) { + errors.push(`drone_type must be a non-negative integer, received: ${data.drone_type}`); + } else { + converted.drone_type = droneType; + } + } + + // rssi - must be INTEGER + if (data.rssi === undefined || data.rssi === null) { + errors.push('rssi is required'); + } else { + const rssi = parseInt(data.rssi); + if (isNaN(rssi)) { + errors.push(`rssi must be a number, received: ${data.rssi}`); + } else { + converted.rssi = rssi; + } + } + + // freq - must be INTEGER (convert from MHz decimal to MHz integer) + if (data.freq === undefined || data.freq === null) { + errors.push('freq is required'); + } else { + let freq = parseFloat(data.freq); + if (isNaN(freq)) { + errors.push(`freq must be a number, received: ${data.freq}`); + } else { + // Convert GHz to MHz if needed (e.g., 2.4 GHz = 2400 MHz) + if (freq < 100) { + // Likely in GHz, convert to MHz + freq = freq * 1000; + } + converted.freq = Math.round(freq); // Round to nearest integer MHz + } + } + + // geo_lat - must be DECIMAL (latitude -90 to 90) + if (data.geo_lat !== undefined && data.geo_lat !== null) { + const lat = parseFloat(data.geo_lat); + if (isNaN(lat) || lat < -90 || lat > 90) { + errors.push(`geo_lat must be a number between -90 and 90, received: ${data.geo_lat}`); + } else { + converted.geo_lat = lat; + } + } + + // geo_lon - must be DECIMAL (longitude -180 to 180) + if (data.geo_lon !== undefined && data.geo_lon !== null) { + const lon = parseFloat(data.geo_lon); + if (isNaN(lon) || lon < -180 || lon > 180) { + errors.push(`geo_lon must be a number between -180 and 180, received: ${data.geo_lon}`); + } else { + converted.geo_lon = lon; + } + } + + // device_timestamp - must be BIGINT (Unix timestamp) + if (data.device_timestamp !== undefined && data.device_timestamp !== null) { + const timestamp = parseInt(data.device_timestamp); + if (isNaN(timestamp) || timestamp < 0) { + errors.push(`device_timestamp must be a positive integer (Unix timestamp), received: ${data.device_timestamp}`); + } else { + converted.device_timestamp = timestamp; + } + } + + // confidence_level - must be DECIMAL between 0 and 1 + if (data.confidence_level !== undefined && data.confidence_level !== null) { + const confidence = parseFloat(data.confidence_level); + if (isNaN(confidence) || confidence < 0 || confidence > 1) { + errors.push(`confidence_level must be a number between 0 and 1, received: ${data.confidence_level}`); + } else { + converted.confidence_level = confidence; + } + } + + // signal_duration - must be INTEGER (milliseconds) + if (data.signal_duration !== undefined && data.signal_duration !== null) { + const duration = parseInt(data.signal_duration); + if (isNaN(duration) || duration < 0) { + errors.push(`signal_duration must be a non-negative integer, received: ${data.signal_duration}`); + } else { + converted.signal_duration = duration; + } + } + + // Add server timestamp + converted.server_timestamp = new Date(); + + } catch (error) { + errors.push(`Data conversion error: ${error.message}`); + } + + return { converted, errors }; }; + // Validate and convert the detection data + const { converted: validatedData, errors: validationErrors } = validateAndConvertDetectionData(detectionData); + + if (validationErrors.length > 0) { + console.error(`❌ Validation errors for device ${deviceIdString}:`, validationErrors); + return res.status(400).json({ + success: false, + error: 'Validation error', + message: 'Detection data validation failed', + details: validationErrors, + device_id: deviceIdString, + drone_id: detectionData.drone_id + }); + } + + console.log(`🔍 Original data:`, detectionData); + console.log(`✅ Validated data:`, validatedData); + + // Create detection record with validated data + const detectionRecord = validatedData; + // Add raw payload if debugging is enabled if (DEBUG_CONFIG.storeRawPayload) { detectionRecord.raw_payload = req.body;