Fix jwt-token

This commit is contained in:
2025-09-17 22:32:55 +02:00
parent 6c74c7c524
commit 43b548c05a
5 changed files with 77 additions and 19 deletions

View File

@@ -37,6 +37,51 @@ router.post('/devices/:id/heartbeat', async (req, res) => {
const { Device, Heartbeat } = models;
const deviceId = parseInt(req.params.id);
// Validate heartbeat payload
const { type, key, status, cpu_usage, memory_usage, disk_usage, uptime, firmware_version, timestamp } = req.body;
// Check for unexpected fields
const allowedFields = ['type', 'key', 'status', 'cpu_usage', 'memory_usage', 'disk_usage', 'uptime', 'firmware_version', 'timestamp'];
const receivedFields = Object.keys(req.body);
const unexpectedFields = receivedFields.filter(field => !allowedFields.includes(field));
if (unexpectedFields.length > 0) {
return res.status(400).json({
success: false,
message: `Unexpected fields: ${unexpectedFields.join(', ')}`
});
}
// Validate status if provided
if (status && !['online', 'offline', 'error', 'maintenance'].includes(status)) {
return res.status(400).json({
success: false,
message: 'Invalid status. Must be one of: online, offline, error, maintenance'
});
}
// Validate percentage fields
const percentageFields = ['cpu_usage', 'memory_usage', 'disk_usage'];
for (const field of percentageFields) {
if (req.body[field] !== undefined) {
const value = parseFloat(req.body[field]);
if (isNaN(value) || value < 0 || value > 100) {
return res.status(400).json({
success: false,
message: `${field} must be a number between 0 and 100`
});
}
}
}
// Validate timestamp if provided
if (timestamp && isNaN(Date.parse(timestamp))) {
return res.status(400).json({
success: false,
message: 'Invalid timestamp format'
});
}
// Find the device
const device = await Device.findByPk(deviceId);
if (!device) {
@@ -50,12 +95,13 @@ router.post('/devices/:id/heartbeat', async (req, res) => {
if (!device.is_approved) {
return res.status(403).json({
success: false,
message: 'Device not approved for heartbeat reporting'
message: 'Device not approved for heartbeat reporting',
approval_required: true
});
}
// Extract heartbeat data - handle both simple device heartbeats and detailed health reports
const { type, key, status, cpu_usage, memory_usage, disk_usage, uptime, firmware_version } = req.body;
// Variables already destructured above: type, key, status, cpu_usage, memory_usage, disk_usage, uptime, firmware_version
// For simple device heartbeats: {type:"heartbeat", key:"unique device ID"}
// For detailed health reports: {status:"online", cpu_usage:25.5, memory_usage:60.2, etc.}
@@ -486,6 +532,16 @@ router.get('/metrics', async (req, res) => {
const models = getModels();
const { sequelize } = models;
// Get user tenant ID with proper fallback
const tenantId = req.user?.tenant_id || req.tenantId || req.tenant?.id;
if (!tenantId) {
return res.status(400).json({
status: 'error',
message: 'No tenant context available'
});
}
// Get system metrics
const memUsage = process.memoryUsage();
const startTime = Date.now();
@@ -501,7 +557,7 @@ router.get('/metrics', async (req, res) => {
const [deviceCount] = await sequelize.query(
'SELECT COUNT(*) as count FROM "Devices" WHERE tenant_id = :tenantId',
{
replacements: { tenantId: req.user.tenant_id },
replacements: { tenantId: tenantId },
type: sequelize.QueryTypes.SELECT
}
);
@@ -509,7 +565,7 @@ router.get('/metrics', async (req, res) => {
const [detectionCount] = await sequelize.query(
'SELECT COUNT(*) as count FROM "DroneDetections" WHERE tenant_id = :tenantId',
{
replacements: { tenantId: req.user.tenant_id },
replacements: { tenantId: tenantId },
type: sequelize.QueryTypes.SELECT
}
);