Fix jwt-token

This commit is contained in:
2025-09-17 20:00:11 +02:00
parent 2881f171ff
commit 86932f5c8e
4 changed files with 39 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
import { io } from 'socket.io-client'; import { io } from 'socket.io-client';
import { useAuth } from './AuthContext'; import { useAuth } from './AuthContext';
import { useMultiTenantAuth } from './MultiTenantAuthContext';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import APP_CONFIG from '../config/app'; import APP_CONFIG from '../config/app';
@@ -17,6 +18,7 @@ export const SocketProvider = ({ children }) => {
localStorage.getItem('notificationsEnabled') !== 'false' // Default to enabled localStorage.getItem('notificationsEnabled') !== 'false' // Default to enabled
); );
const { isAuthenticated } = useAuth(); const { isAuthenticated } = useAuth();
const { state: { tenant } } = useMultiTenantAuth();
// Mobile notification management // Mobile notification management
const [notificationCooldown, setNotificationCooldown] = useState(new Map()); const [notificationCooldown, setNotificationCooldown] = useState(new Map());
@@ -135,6 +137,12 @@ export const SocketProvider = ({ children }) => {
// Join dashboard room for general updates // Join dashboard room for general updates
newSocket.emit('join_dashboard'); newSocket.emit('join_dashboard');
// 🔒 SECURITY: Join tenant-specific room for isolated updates
if (tenant) {
newSocket.emit('join_tenant_room', tenant);
console.log(`🔒 Joined tenant room: ${tenant}`);
}
toast.success('Connected to real-time updates'); toast.success('Connected to real-time updates');
}); });
@@ -224,7 +232,7 @@ export const SocketProvider = ({ children }) => {
setConnected(false); setConnected(false);
} }
} }
}, [isAuthenticated]); }, [isAuthenticated, tenant]);
const joinDeviceRoom = (deviceId) => { const joinDeviceRoom = (deviceId) => {
if (socket) { if (socket) {

View File

@@ -378,7 +378,7 @@ async function handleDetection(req, res) {
// Emit real-time update via Socket.IO with movement analysis (from original) // Emit real-time update via Socket.IO with movement analysis (from original)
// Skip real-time updates for debug detections (drone_type 0) // Skip real-time updates for debug detections (drone_type 0)
if (!isDebugDetection) { if (!isDebugDetection) {
req.io.emit('drone_detection', { const detectionPayload = {
id: detection.id, id: detection.id,
device_id: detection.device_id, device_id: detection.device_id,
drone_id: detection.drone_id, drone_id: detection.drone_id,
@@ -397,7 +397,17 @@ async function handleDetection(req, res) {
geo_lat: device.geo_lat, geo_lat: device.geo_lat,
geo_lon: device.geo_lon geo_lon: device.geo_lon
} }
}); };
// 🔒 SECURITY: Emit only to the tenant's room to prevent cross-tenant data leakage
if (device.tenant_id) {
req.io.to(`tenant_${device.tenant_id}`).emit('drone_detection', detectionPayload);
console.log(`🔒 Detection emitted to tenant room: tenant_${device.tenant_id}`);
} else {
// Fallback for devices without tenant_id (legacy support)
console.warn(`⚠️ Device ${device.id} has no tenant_id - using global broadcast (security risk)`);
req.io.emit('drone_detection', detectionPayload);
}
// Process alerts asynchronously (from original) // Process alerts asynchronously (from original)
alertService.processAlert(detection, req.io).catch(error => { alertService.processAlert(detection, req.io).catch(error => {

View File

@@ -14,6 +14,12 @@ function initializeSocketHandlers(io) {
console.log(`Client ${socket.id} (IP: ${clientIP}) joined device room: device_${deviceId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) joined device room: device_${deviceId}`);
}); });
// 🔒 SECURITY: Join tenant-specific room for multi-tenant isolation
socket.on('join_tenant_room', (tenantId) => {
socket.join(`tenant_${tenantId}`);
console.log(`Client ${socket.id} (IP: ${clientIP}) joined tenant room: tenant_${tenantId}`);
});
// Join dashboard room for general updates // Join dashboard room for general updates
socket.on('join_dashboard', () => { socket.on('join_dashboard', () => {
socket.join('dashboard'); socket.join('dashboard');
@@ -26,6 +32,11 @@ function initializeSocketHandlers(io) {
console.log(`Client ${socket.id} (IP: ${clientIP}) left device room: device_${deviceId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) left device room: device_${deviceId}`);
}); });
socket.on('leave_tenant_room', (tenantId) => {
socket.leave(`tenant_${tenantId}`);
console.log(`Client ${socket.id} (IP: ${clientIP}) left tenant room: tenant_${tenantId}`);
});
socket.on('leave_dashboard', () => { socket.on('leave_dashboard', () => {
socket.leave('dashboard'); socket.leave('dashboard');
console.log(`Client ${socket.id} (IP: ${clientIP}) left dashboard room`); console.log(`Client ${socket.id} (IP: ${clientIP}) left dashboard room`);
@@ -49,6 +60,10 @@ function initializeSocketHandlers(io) {
io.to(`device_${deviceId}`).emit(event, data); io.to(`device_${deviceId}`).emit(event, data);
}; };
io.emitToTenant = function(tenantId, event, data) {
io.to(`tenant_${tenantId}`).emit(event, data);
};
io.emitToDashboard = function(event, data) { io.emitToDashboard = function(event, data) {
io.to('dashboard').emit(event, data); io.to('dashboard').emit(event, data);
}; };

View File

@@ -144,13 +144,14 @@ def send_detection(drone_type=2, drone_id=None, geo_lat=0, geo_lon=0, rssi=-45,
print(f"❌ Connection error: {e}") print(f"❌ Connection error: {e}")
return False return False
def simulate_drone_approach(drone_type=2, drone_id=None, steps=10): def simulate_drone_approach(drone_type=2, drone_id=None, device_id=None, steps=10):
""" """
Simulate a drone approaching from distance Simulate a drone approaching from distance
Args: Args:
drone_type: Type of drone to simulate drone_type: Type of drone to simulate
drone_id: Specific drone ID (auto-generated if None) drone_id: Specific drone ID (auto-generated if None)
device_id: Device ID to use (uses global DEVICE_ID if None)
steps: Number of detection steps steps: Number of detection steps
""" """
@@ -189,6 +190,7 @@ def simulate_drone_approach(drone_type=2, drone_id=None, steps=10):
geo_lon=lon, geo_lon=lon,
rssi=rssi, rssi=rssi,
freq=2400, freq=2400,
device_id=device_id,
show_response=True show_response=True
) )