Fix jwt-token
This commit is contained in:
@@ -6,7 +6,9 @@ import {
|
|||||||
ExclamationTriangleIcon,
|
ExclamationTriangleIcon,
|
||||||
InformationCircleIcon,
|
InformationCircleIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
TrashIcon
|
TrashIcon,
|
||||||
|
DocumentTextIcon,
|
||||||
|
XMarkIcon
|
||||||
} from '@heroicons/react/24/outline';
|
} from '@heroicons/react/24/outline';
|
||||||
|
|
||||||
const Debug = () => {
|
const Debug = () => {
|
||||||
@@ -15,6 +17,9 @@ const Debug = () => {
|
|||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [pagination, setPagination] = useState({});
|
const [pagination, setPagination] = useState({});
|
||||||
const [debugInfo, setDebugInfo] = useState({});
|
const [debugInfo, setDebugInfo] = useState({});
|
||||||
|
const [showPayloadModal, setShowPayloadModal] = useState(false);
|
||||||
|
const [selectedPayload, setSelectedPayload] = useState(null);
|
||||||
|
const [payloadLoading, setPayloadLoading] = useState(false);
|
||||||
const [filters, setFilters] = useState({
|
const [filters, setFilters] = useState({
|
||||||
drone_type: '',
|
drone_type: '',
|
||||||
device_id: '',
|
device_id: '',
|
||||||
@@ -64,6 +69,48 @@ const Debug = () => {
|
|||||||
setFilters(prev => ({ ...prev, page: newPage }));
|
setFilters(prev => ({ ...prev, page: newPage }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchRawPayload = async (detectionId) => {
|
||||||
|
try {
|
||||||
|
setPayloadLoading(true);
|
||||||
|
const response = await api.get(`/debug/detection-payloads?limit=1&detection_id=${detectionId}`);
|
||||||
|
|
||||||
|
if (response.data.success && response.data.data.length > 0) {
|
||||||
|
const detection = response.data.data[0];
|
||||||
|
setSelectedPayload({
|
||||||
|
id: detection.id,
|
||||||
|
timestamp: detection.server_timestamp,
|
||||||
|
deviceId: detection.device_id,
|
||||||
|
rawPayload: detection.raw_payload,
|
||||||
|
processedData: {
|
||||||
|
drone_id: detection.drone_id,
|
||||||
|
drone_type: detection.drone_type,
|
||||||
|
rssi: detection.rssi,
|
||||||
|
freq: detection.freq,
|
||||||
|
geo_lat: detection.geo_lat,
|
||||||
|
geo_lon: detection.geo_lon,
|
||||||
|
device_timestamp: detection.device_timestamp,
|
||||||
|
confidence_level: detection.confidence_level,
|
||||||
|
signal_duration: detection.signal_duration
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setShowPayloadModal(true);
|
||||||
|
} else {
|
||||||
|
console.error('No payload data found for detection:', detectionId);
|
||||||
|
alert('No raw payload data found for this detection');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error fetching payload:', err);
|
||||||
|
alert('Failed to fetch payload data');
|
||||||
|
} finally {
|
||||||
|
setPayloadLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const closePayloadModal = () => {
|
||||||
|
setShowPayloadModal(false);
|
||||||
|
setSelectedPayload(null);
|
||||||
|
};
|
||||||
|
|
||||||
const getDroneTypeColor = (droneType) => {
|
const getDroneTypeColor = (droneType) => {
|
||||||
if (droneType === 0) return 'bg-gray-100 text-gray-800';
|
if (droneType === 0) return 'bg-gray-100 text-gray-800';
|
||||||
return 'bg-blue-100 text-blue-800';
|
return 'bg-blue-100 text-blue-800';
|
||||||
@@ -243,6 +290,9 @@ const Debug = () => {
|
|||||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Debug
|
Debug
|
||||||
</th>
|
</th>
|
||||||
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-white divide-y divide-gray-200">
|
<tbody className="bg-white divide-y divide-gray-200">
|
||||||
@@ -288,6 +338,16 @@ const Debug = () => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="px-6 py-4 whitespace-nowrap">
|
||||||
|
<button
|
||||||
|
onClick={() => fetchRawPayload(detection.id)}
|
||||||
|
disabled={payloadLoading}
|
||||||
|
className="inline-flex items-center px-3 py-1 border border-gray-300 shadow-sm text-xs font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<DocumentTextIcon className="h-4 w-4 mr-1" />
|
||||||
|
{payloadLoading ? 'Loading...' : 'View Payload'}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -347,6 +407,108 @@ const Debug = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Raw Payload Modal */}
|
||||||
|
{showPayloadModal && selectedPayload && (
|
||||||
|
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
|
||||||
|
<div className="relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 shadow-lg rounded-md bg-white">
|
||||||
|
<div className="mt-3">
|
||||||
|
{/* Modal Header */}
|
||||||
|
<div className="flex items-center justify-between pb-4 border-b">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<DocumentTextIcon className="h-6 w-6 text-blue-500 mr-2" />
|
||||||
|
<h3 className="text-lg font-medium text-gray-900">
|
||||||
|
Raw Payload Data
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={closePayloadModal}
|
||||||
|
className="text-gray-400 hover:text-gray-600"
|
||||||
|
>
|
||||||
|
<XMarkIcon className="h-6 w-6" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Detection Info */}
|
||||||
|
<div className="mt-4 bg-gray-50 rounded-lg p-4">
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">Detection Information</h4>
|
||||||
|
<div className="grid grid-cols-2 gap-4 text-sm">
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-600">Detection ID:</span>
|
||||||
|
<span className="ml-2 font-mono">{selectedPayload.id}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-600">Device ID:</span>
|
||||||
|
<span className="ml-2 font-mono">{selectedPayload.deviceId}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-600">Server Timestamp:</span>
|
||||||
|
<span className="ml-2 font-mono">
|
||||||
|
{format(new Date(selectedPayload.timestamp), 'yyyy-MM-dd HH:mm:ss')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-600">Drone Type:</span>
|
||||||
|
<span className="ml-2 font-mono">{selectedPayload.processedData.drone_type}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Processed Data */}
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">Processed Data</h4>
|
||||||
|
<div className="bg-gray-100 rounded-lg p-4 font-mono text-sm overflow-x-auto">
|
||||||
|
<pre className="whitespace-pre-wrap">
|
||||||
|
{JSON.stringify(selectedPayload.processedData, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Raw Payload */}
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium text-gray-900 mb-2">Raw Payload from Detector</h4>
|
||||||
|
{selectedPayload.rawPayload ? (
|
||||||
|
<div className="bg-black text-green-400 rounded-lg p-4 font-mono text-sm overflow-x-auto max-h-96 overflow-y-auto">
|
||||||
|
<pre className="whitespace-pre-wrap">
|
||||||
|
{JSON.stringify(selectedPayload.rawPayload, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
|
||||||
|
<p className="text-yellow-800 text-sm">
|
||||||
|
⚠️ No raw payload data available. This might occur if:
|
||||||
|
</p>
|
||||||
|
<ul className="mt-2 text-yellow-700 text-sm list-disc list-inside">
|
||||||
|
<li>STORE_RAW_PAYLOAD environment variable is disabled</li>
|
||||||
|
<li>This detection was created before raw payload storage was enabled</li>
|
||||||
|
<li>The detection was processed without storing the original payload</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Modal Footer */}
|
||||||
|
<div className="mt-6 flex justify-end space-x-3">
|
||||||
|
<button
|
||||||
|
onClick={closePayloadModal}
|
||||||
|
className="px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(JSON.stringify(selectedPayload, null, 2));
|
||||||
|
alert('Payload data copied to clipboard!');
|
||||||
|
}}
|
||||||
|
className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
>
|
||||||
|
Copy to Clipboard
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ router.get('/debug-test', (req, res) => {
|
|||||||
// Get recent detection payloads with raw data
|
// Get recent detection payloads with raw data
|
||||||
router.get('/detection-payloads', authenticateToken, async (req, res) => {
|
router.get('/detection-payloads', authenticateToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { limit = 50, offset = 0, device_id } = req.query;
|
const { limit = 50, offset = 0, device_id, detection_id } = req.query;
|
||||||
|
|
||||||
const whereClause = {
|
const whereClause = {
|
||||||
raw_payload: { [Op.ne]: null }
|
raw_payload: { [Op.ne]: null }
|
||||||
@@ -37,6 +37,10 @@ router.get('/detection-payloads', authenticateToken, async (req, res) => {
|
|||||||
whereClause.device_id = device_id;
|
whereClause.device_id = device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (detection_id) {
|
||||||
|
whereClause.id = detection_id;
|
||||||
|
}
|
||||||
|
|
||||||
const detections = await DroneDetection.findAll({
|
const detections = await DroneDetection.findAll({
|
||||||
where: whereClause,
|
where: whereClause,
|
||||||
order: [['server_timestamp', 'DESC']],
|
order: [['server_timestamp', 'DESC']],
|
||||||
@@ -44,7 +48,7 @@ router.get('/detection-payloads', authenticateToken, async (req, res) => {
|
|||||||
offset: parseInt(offset),
|
offset: parseInt(offset),
|
||||||
attributes: [
|
attributes: [
|
||||||
'id', 'device_id', 'drone_id', 'drone_type', 'rssi', 'freq',
|
'id', 'device_id', 'drone_id', 'drone_type', 'rssi', 'freq',
|
||||||
'server_timestamp', 'device_timestamp', 'raw_payload'
|
'server_timestamp', 'device_timestamp', 'raw_payload', 'confidence_level', 'signal_duration', 'geo_lat', 'geo_lon'
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user