Fix jwt-token
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user