Add device diagnostics and P2P access controls

This commit is contained in:
Jonathan Sykes
2026-10-14 02:45:33 +08:00
parent e9a597c415
commit 5177a4d441
11 changed files with 147 additions and 8 deletions

35
server/p2p-admin.js Normal file
View File

@@ -0,0 +1,35 @@
import { audit } from './audit-log.js';
export function registerP2pAdminRoutes(app, { db, adminAuth, p2pDb, hub, stats = async () => ({}) }) {
app.get('/api/admin/p2p/devices', adminAuth, async c => {
const offset = Math.max(0, Number(c.req.query('offset')) || 0);
const devices = await p2pDb.listAdminDevices({ limit: 100, offset });
return c.json({ ok: true, devices: devices.map(d => ({
id: d.device_id, fingerprint: d.fingerprint || '', fingerprintShort: (d.fingerprint || d.device_id).slice(0, 12),
profile: d.profile || '', userAgent: d.user_agent || '', share: !!Number(d.share), banned: !!d.banned_at,
lastSeenAt: Number(d.last_seen_at), online: hub.isOnline(d.device_id), holdings: Number(d.holdings), holdingBytes: Number(d.holding_bytes),
bytesUp: Number(d.bytes_up), bytesDown: Number(d.bytes_down),
})), network: { online: hub.onlineCount(), ...(await stats()) }, offset }, 200, { 'Cache-Control': 'no-store' });
});
app.post('/api/admin/p2p/devices/:id/ban', adminAuth, async c => {
const id = c.req.param('id'); if (!/^dev_[0-9a-f]{16}$/.test(id)) return c.json({ ok: false, error: 'Invalid device.' }, 400);
const body = await c.req.json().catch(() => ({})); const banned = body.banned === true;
const changed = await p2pDb.setDeviceBanned(id, banned);
if (!changed) return c.json({ ok: false, error: 'Device not found.' }, 404);
if (banned) hub.disconnect(id);
await audit(db, 'admin', banned ? 'p2p.device.ban' : 'p2p.device.unban', id);
return c.json({ ok: true, banned });
});
app.post('/api/admin/p2p/devices/:id/reannounce', adminAuth, async c => {
const id = c.req.param('id'); if (!/^dev_[0-9a-f]{16}$/.test(id)) return c.json({ ok: false, error: 'Invalid device.' }, 400);
const sent = hub.send(id, { type: 'force-sync' });
await audit(db, 'admin', 'p2p.device.reannounce', id, { sent });
return c.json({ ok: true, sent });
});
app.delete('/api/admin/p2p/devices/:id/holdings', adminAuth, async c => {
const id = c.req.param('id'); if (!/^dev_[0-9a-f]{16}$/.test(id)) return c.json({ ok: false, error: 'Invalid device.' }, 400);
const removed = await p2pDb.removeDeviceHolders(id);
await audit(db, 'admin', 'p2p.device.holdings.revoke', id, { removed });
return c.json({ ok: true, removed });
});
}