Add LAN device discovery (ping sweep + ARP, known/unknown labeling)
Runs as a host-level systemd timer on CT122 (scripts/discover-devices.sh) rather than inside the api container, since real ARP entries live in the host's network namespace, not Docker's bridge network. See docs/device-discovery.md for the full writeup, including why literal passive-only ARP reading was dropped (near-empty result in practice). API reads the resulting JSON file each poll cycle, cross-references config/hosts.yaml's knownDevices list by IP, and serves /api/devices. Dashboard gets a new "Network Devices" table. Closes #9. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import type Database from "better-sqlite3";
|
||||
import { getRecentDevices } from "../db/index.js";
|
||||
|
||||
async function requireAuth(req: FastifyRequest, reply: FastifyReply) {
|
||||
if (!req.session.username) {
|
||||
reply.code(401).send({ error: "not authenticated" });
|
||||
}
|
||||
}
|
||||
|
||||
export function registerDeviceRoutes(app: FastifyInstance, db: Database.Database): void {
|
||||
app.get("/api/devices", { preHandler: requireAuth }, async () => {
|
||||
const rows = getRecentDevices(db);
|
||||
return {
|
||||
devices: rows.map((r) => ({
|
||||
ip: r.ip,
|
||||
mac: r.mac,
|
||||
name: r.known_name,
|
||||
known: r.known_name !== null,
|
||||
firstSeen: r.first_seen,
|
||||
lastSeen: r.last_seen,
|
||||
})),
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user