Fix jwt-token
This commit is contained in:
@@ -265,10 +265,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
{
|
{
|
||||||
"type": "heartbeat",
|
"type": "heartbeat",
|
||||||
"key": "device_1941875381_key",
|
"key": "device_1941875381_key"
|
||||||
"battery_level": 85,
|
|
||||||
"signal_strength": -50,
|
|
||||||
"temperature": 22.5
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
5
SETUP.md
5
SETUP.md
@@ -127,10 +127,7 @@ curl -X POST http://localhost:3001/api/heartbeat \
|
|||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{
|
-d '{
|
||||||
"type": "heartbeat",
|
"type": "heartbeat",
|
||||||
"key": "device_1941875381_key",
|
"key": "device_1941875381_key"
|
||||||
"battery_level": 85,
|
|
||||||
"signal_strength": -50,
|
|
||||||
"temperature": 22.5
|
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ class DroneDevice:
|
|||||||
lon: float
|
lon: float
|
||||||
category: str
|
category: str
|
||||||
last_heartbeat: float = 0
|
last_heartbeat: float = 0
|
||||||
battery_level: int = 100
|
|
||||||
signal_strength: int = -45
|
|
||||||
temperature: float = 20.0
|
|
||||||
status: str = "active"
|
status: str = "active"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -118,10 +115,7 @@ class SwedishDroneSimulator:
|
|||||||
location=location["name"],
|
location=location["name"],
|
||||||
lat=location["lat"],
|
lat=location["lat"],
|
||||||
lon=location["lon"],
|
lon=location["lon"],
|
||||||
category=category,
|
category=category
|
||||||
battery_level=random.randint(75, 100),
|
|
||||||
signal_strength=random.randint(-60, -30),
|
|
||||||
temperature=random.uniform(15, 30)
|
|
||||||
)
|
)
|
||||||
devices.append(device)
|
devices.append(device)
|
||||||
|
|
||||||
|
|||||||
@@ -22,21 +22,6 @@ module.exports = (sequelize) => {
|
|||||||
defaultValue: 'test-device-key',
|
defaultValue: 'test-device-key',
|
||||||
comment: 'Unique key of the sensor from heartbeat message'
|
comment: 'Unique key of the sensor from heartbeat message'
|
||||||
},
|
},
|
||||||
signal_strength: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: true,
|
|
||||||
comment: 'Signal strength at time of heartbeat'
|
|
||||||
},
|
|
||||||
battery_level: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
allowNull: true,
|
|
||||||
comment: 'Battery level percentage (0-100)'
|
|
||||||
},
|
|
||||||
temperature: {
|
|
||||||
type: DataTypes.DECIMAL(4, 1),
|
|
||||||
allowNull: true,
|
|
||||||
comment: 'Device temperature in Celsius'
|
|
||||||
},
|
|
||||||
uptime: {
|
uptime: {
|
||||||
type: DataTypes.BIGINT,
|
type: DataTypes.BIGINT,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
|||||||
@@ -224,10 +224,7 @@ router.get('/activity', authenticateToken, async (req, res) => {
|
|||||||
timestamp: heartbeat.received_at,
|
timestamp: heartbeat.received_at,
|
||||||
data: {
|
data: {
|
||||||
device_id: heartbeat.device_id,
|
device_id: heartbeat.device_id,
|
||||||
device_name: heartbeat.device.name || `Device ${heartbeat.device_id}`,
|
device_name: heartbeat.device.name || `Device ${heartbeat.device_id}`
|
||||||
battery_level: heartbeat.battery_level,
|
|
||||||
signal_strength: heartbeat.signal_strength,
|
|
||||||
temperature: heartbeat.temperature
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -89,8 +89,7 @@ router.get('/heartbeat-payloads', authenticateToken, async (req, res) => {
|
|||||||
limit: parseInt(limit),
|
limit: parseInt(limit),
|
||||||
offset: parseInt(offset),
|
offset: parseInt(offset),
|
||||||
attributes: [
|
attributes: [
|
||||||
'id', 'device_id', 'device_key', 'signal_strength', 'battery_level',
|
'id', 'device_id', 'device_key', 'received_at', 'raw_payload'
|
||||||
'temperature', 'received_at', 'raw_payload'
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ const detectorSchema = Joi.alternatives().try(
|
|||||||
geo_lat: Joi.number().min(-90).max(90).optional(),
|
geo_lat: Joi.number().min(-90).max(90).optional(),
|
||||||
geo_lon: Joi.number().min(-180).max(180).optional(),
|
geo_lon: Joi.number().min(-180).max(180).optional(),
|
||||||
location_description: Joi.string().optional(),
|
location_description: Joi.string().optional(),
|
||||||
signal_strength: Joi.number().integer().optional(),
|
|
||||||
battery_level: Joi.number().integer().min(0).max(100).optional(),
|
|
||||||
temperature: Joi.number().optional(),
|
|
||||||
uptime: Joi.number().integer().min(0).optional(),
|
uptime: Joi.number().integer().min(0).optional(),
|
||||||
memory_usage: Joi.number().integer().min(0).max(100).optional(),
|
memory_usage: Joi.number().integer().min(0).max(100).optional(),
|
||||||
firmware_version: Joi.string().optional()
|
firmware_version: Joi.string().optional()
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ router.get('/', authenticateToken, async (req, res) => {
|
|||||||
limit: 1,
|
limit: 1,
|
||||||
order: [['received_at', 'DESC']],
|
order: [['received_at', 'DESC']],
|
||||||
required: false,
|
required: false,
|
||||||
attributes: ['received_at', 'battery_level', 'signal_strength', 'temperature']
|
attributes: ['received_at']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,17 +134,11 @@ const setupDatabase = async () => {
|
|||||||
const heartbeats = await Heartbeat.bulkCreate([
|
const heartbeats = await Heartbeat.bulkCreate([
|
||||||
{
|
{
|
||||||
device_id: 1941875381,
|
device_id: 1941875381,
|
||||||
battery_level: 85,
|
|
||||||
signal_strength: -45,
|
|
||||||
temperature: 22.5,
|
|
||||||
status: 'active',
|
status: 'active',
|
||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
device_id: 1941875382,
|
device_id: 1941875382,
|
||||||
battery_level: 72,
|
|
||||||
signal_strength: -38,
|
|
||||||
temperature: 24.1,
|
|
||||||
status: 'active',
|
status: 'active',
|
||||||
timestamp: new Date()
|
timestamp: new Date()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -552,10 +552,7 @@ describe('Models', () => {
|
|||||||
|
|
||||||
const heartbeatData = {
|
const heartbeatData = {
|
||||||
device_key: 'device_123_key',
|
device_key: 'device_123_key',
|
||||||
device_id: device.id,
|
device_id: device.id
|
||||||
signal_strength: -50,
|
|
||||||
battery_level: 85,
|
|
||||||
temperature: 22.5
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('DEBUG Creating heartbeat with data:', heartbeatData);
|
console.log('DEBUG Creating heartbeat with data:', heartbeatData);
|
||||||
@@ -566,7 +563,6 @@ describe('Models', () => {
|
|||||||
id: heartbeat.id,
|
id: heartbeat.id,
|
||||||
device_key: heartbeat.device_key,
|
device_key: heartbeat.device_key,
|
||||||
device_id: heartbeat.device_id,
|
device_id: heartbeat.device_id,
|
||||||
battery_level: heartbeat.battery_level,
|
|
||||||
allFields: Object.keys(heartbeat.dataValues)
|
allFields: Object.keys(heartbeat.dataValues)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -593,7 +589,7 @@ describe('Models', () => {
|
|||||||
expect(heartbeat.created_at).to.be.a('date');
|
expect(heartbeat.created_at).to.be.a('date');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate battery level range', async () => {
|
it('should validate device_key field', async () => {
|
||||||
const tenant = await createTestTenant();
|
const tenant = await createTestTenant();
|
||||||
const device = await models.Device.create({
|
const device = await models.Device.create({
|
||||||
id: 123,
|
id: 123,
|
||||||
@@ -601,14 +597,12 @@ describe('Models', () => {
|
|||||||
tenant_id: tenant.id
|
tenant_id: tenant.id
|
||||||
});
|
});
|
||||||
|
|
||||||
// SQLite doesn't enforce range validation, so test valid creation
|
|
||||||
const heartbeat = await models.Heartbeat.create({
|
const heartbeat = await models.Heartbeat.create({
|
||||||
device_key: 'device_123_key',
|
device_key: 'test-device-key-123',
|
||||||
device_id: device.id,
|
device_id: device.id
|
||||||
battery_level: 85 // Valid range
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(heartbeat.battery_level).to.equal(85);
|
expect(heartbeat.device_key).to.equal('test-device-key-123');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -258,10 +258,7 @@ describe('Detectors Routes', () => {
|
|||||||
key: 'device_123_key',
|
key: 'device_123_key',
|
||||||
device_id: 123,
|
device_id: 123,
|
||||||
geo_lat: 59.3293,
|
geo_lat: 59.3293,
|
||||||
geo_lon: 18.0686,
|
geo_lon: 18.0686
|
||||||
signal_strength: -50,
|
|
||||||
battery_level: 85,
|
|
||||||
temperature: 22.5
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@@ -302,11 +299,10 @@ describe('Detectors Routes', () => {
|
|||||||
expect(response.body.success).to.be.true;
|
expect(response.body.success).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should validate battery level range', async () => {
|
it('should validate required fields', async () => {
|
||||||
const heartbeatData = {
|
const heartbeatData = {
|
||||||
type: 'heartbeat',
|
type: 'heartbeat'
|
||||||
key: 'device_123_key',
|
// Missing required key field
|
||||||
battery_level: 150 // Invalid range
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@@ -323,8 +319,7 @@ describe('Detectors Routes', () => {
|
|||||||
const heartbeatData = {
|
const heartbeatData = {
|
||||||
type: 'heartbeat',
|
type: 'heartbeat',
|
||||||
key: 'device_123_key',
|
key: 'device_123_key',
|
||||||
device_id: 123,
|
device_id: 123
|
||||||
battery_level: 85
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
|
|||||||
@@ -234,8 +234,7 @@ describe('Healthcheck Routes', () => {
|
|||||||
status: 'online',
|
status: 'online',
|
||||||
cpu_usage: 15.5,
|
cpu_usage: 15.5,
|
||||||
memory_usage: 40.2,
|
memory_usage: 40.2,
|
||||||
disk_usage: 25.0,
|
disk_usage: 25.0
|
||||||
temperature: 42.5
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@@ -307,9 +306,7 @@ describe('Healthcheck Routes', () => {
|
|||||||
status: 'online',
|
status: 'online',
|
||||||
cpu_usage: 25.5,
|
cpu_usage: 25.5,
|
||||||
memory_usage: 60.2,
|
memory_usage: 60.2,
|
||||||
disk_usage: 45.0,
|
disk_usage: 45.0
|
||||||
temperature: 38.5,
|
|
||||||
signal_strength: -65
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@@ -382,7 +379,7 @@ describe('Healthcheck Routes', () => {
|
|||||||
{
|
{
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
status: 'online',
|
status: 'online',
|
||||||
temperature: -50 // Unrealistic temperature
|
invalid_field: 'test' // Invalid field
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user