EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
deviceDiscovery.js
Go to the documentation of this file.
1/**
2 * @file deviceDiscovery.js
3 * @module routes/deviceDiscovery
4 * @description Network device discovery endpoint for agent scanner plugin.
5 * Receives network scan results (SNMP, ARP, etc.) from agents and stores in Redis/database.
6 * Enables automatic device inventory and network mapping.
7 * @requires express
8 * @requires middleware/auth
9 * @requires services/db
10 * @requires ioredis
11 * @author RMM-PSA Development Team
12 * @copyright 2026 RMM-PSA Platform
13 * @license Proprietary
14 */
15
16/**
17 * @apiDefine DeviceDiscovery Network Device Discovery
18 * Network scanner results from agent plugins
19 */
20
21const express = require('express');
22const router = express.Router();
23const authenticateToken = require('../middleware/auth');
24const pool = require('../services/db');
25
26/**
27 * @api {post} /api/device-discovery Submit discovered devices
28 * @apiName SubmitDeviceDiscovery
29 * @apiGroup DeviceDiscovery
30 * @apiDescription Agent network scanner plugin submits discovered devices (SNMP/ARP scan results).
31 * Data stored in Redis queue for processing. SNMP devices with sysDescr auto-inserted into database.
32 * Supports network topology mapping and automatic device inventory.
33 * @apiParam {string} agent_uuid Agent UUID performing scan
34 * @apiParam {string} [type="network"] Discovery type ("network", "snmp")
35 * @apiParam {object[]} data Array of discovered devices
36 * @apiParam {string} data.ip Device IP address
37 * @apiParam {string} [data.mac] Device MAC address
38 * @apiParam {string} [data.sysDescr] SNMP system description (sysDescr OID)
39 * @apiParam {string} [data.sysName] SNMP system name (sysName OID)
40 * @apiParam {string} [data.sysLocation] SNMP system location (sysLocation OID)
41 * @apiParam {DateTime} [ts] Discovery timestamp (default: now)
42 * @apiSuccess {string} status="ok" Success status
43 * @apiSuccess {number} devices Number of devices received
44 * @apiSuccess {number} dbAdded Number of devices auto-inserted to database (SNMP only)
45 * @apiError (400) {String} error="Missing agent_uuid or device data" Required parameters missing
46 * @apiError (500) {String} error="Failed to save device data" Redis or database error
47 * @apiExample {curl} Example (SNMP scan):
48 * curl -X POST http://localhost:3000/api/device-discovery \\\\
49 * -H "Authorization: Bearer YOUR_TOKEN" \\\\
50 * -H "Content-Type: application/json" \\\\
51 * -d '{
52 * "agent_uuid": "abc-123-uuid",
53 * "type": "snmp",
54 * "ts": "2026-03-12T10:00:00.000Z",
55 * "data": [
56 * {
57 * "ip": "192.168.1.1",
58 * "mac": "00:11:22:33:44:55",
59 * "sysDescr": "Cisco IOS Software",
60 * "sysName": "CORE-SWITCH-01",
61 * "sysLocation": "Server Room"
62 * }
63 * ]
64 * }'
65 * @apiSuccessExample {json} Success-Response:
66 * HTTP/1.1 200 OK
67 * {
68 * "status": "ok",
69 * "devices": 1,
70 * "dbAdded": 1
71 * }
72 */
73router.post('/', authenticateToken, async (req, res) => {
74 try {
75 const { agent_uuid, type, data, ts } = req.body;
76 if (!agent_uuid || !Array.isArray(data)) {
77 return res.status(400).json({ error: 'Missing agent_uuid or device data' });
78 }
79 // Use Redis for storing detected endpoints for later processing
80 const Redis = require('ioredis');
81 const redisConfig = require('../config/redis');
82 const redis = new Redis(redisConfig);
83 const key = `deviceDiscovery:${agent_uuid}`;
84 let dbAdded = 0;
85 for (const device of data) {
86 await redis.rpush(key, JSON.stringify({
87 ip: device.ip,
88 mac: device.mac,
89 type: type || 'network',
90 discovered_at: ts || new Date().toISOString(),
91 sysDescr: device.sysDescr || '',
92 sysName: device.sysName || '',
93 sysLocation: device.sysLocation || '',
94 discovered_by: agent_uuid
95 }));
96 // If SNMP fingerprint present, auto-add to DB
97 if (type === 'snmp' && device.sysDescr) {
98 try {
99 await pool.query(
100 `INSERT INTO devices (ip, mac, sys_descr, sys_name, sys_location, discovered_by, discovered_at)
101 VALUES ($1, $2, $3, $4, $5, $6, $7)
102 ON CONFLICT (ip, mac) DO UPDATE SET sys_descr = $3, sys_name = $4, sys_location = $5, discovered_by = $6, discovered_at = $7`,
103 [device.ip, device.mac, device.sysDescr, device.sysName, device.sysLocation, agent_uuid, ts || new Date().toISOString()]
104 );
105 dbAdded++;
106 } catch (e) {
107 console.error('[DeviceDiscovery] DB insert error:', e);
108 }
109 }
110 }
111 await redis.expire(key, 86400);
112 res.json({ status: 'ok', devices: data.length, dbAdded });
113 } catch (err) {
114 console.error('[DeviceDiscovery] Error:', err);
115 res.status(500).json({ error: 'Failed to save device data' });
116 }
117});
118
119module.exports = router;