completeness pass 2: agent-token auth on /api/agent/*, token-injected agent.py downloads, export-all zip endpoint, node detail drawer (metrics/loot/tags/ping), screenshot watch mode, honest Linux-only binary note, token-aware binary command, watch-state render persistence
This commit is contained in:
37
server.js
37
server.js
@@ -31,9 +31,19 @@ const AUTH_TOKEN = process.env.NEXUS_AUTH_TOKEN || null;
|
||||
if (!AUTH_TOKEN) {
|
||||
console.log('!!! AUTH DISABLED — set NEXUS_AUTH_TOKEN in .env to protect the dashboard !!!');
|
||||
}
|
||||
const AUTH_EXEMPT_PREFIXES = ['/api/agent/', '/install', '/agent.py', '/bin/'];
|
||||
const AGENT_TOKEN = process.env.NEXUS_AGENT_TOKEN || '';
|
||||
const AUTH_EXEMPT_PREFIXES = ['/install', '/agent.py', '/bin/'];
|
||||
function agentAuthOk(req) {
|
||||
if (!AGENT_TOKEN) return true; // agent auth disabled when no token configured
|
||||
const t = req.headers['x-agent-token'] || req.query.agenttoken || '';
|
||||
return t === AGENT_TOKEN;
|
||||
}
|
||||
function authMiddleware(req, res, next) {
|
||||
if (!AUTH_TOKEN) return next();
|
||||
if (req.path.startsWith('/api/agent/')) {
|
||||
if (agentAuthOk(req)) return next();
|
||||
return res.status(401).json({ error: 'agent token required' });
|
||||
}
|
||||
if (AUTH_EXEMPT_PREFIXES.some(p => req.path.startsWith(p))) return next();
|
||||
const h = req.headers.authorization || '';
|
||||
if (h === 'Bearer ' + AUTH_TOKEN) return next();
|
||||
@@ -953,7 +963,30 @@ echo "[*] Agent deployment initiated — it will register within 10 seconds"
|
||||
});
|
||||
|
||||
app.get('/agent.py', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'agents', 'agent.py'));
|
||||
try {
|
||||
const src = fs.readFileSync(path.join(__dirname, 'agents', 'agent.py'), 'utf8');
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.send(AGENT_TOKEN ? src.split('__AGENT_TOKEN__').join(AGENT_TOKEN) : src);
|
||||
} catch (e) {
|
||||
res.status(500).send('agent unavailable');
|
||||
}
|
||||
});
|
||||
|
||||
// ── Completeness additions 2026-09-29 ──
|
||||
app.get('/api/agenttoken', (req, res) => {
|
||||
res.json({ token: AGENT_TOKEN || '' });
|
||||
});
|
||||
app.get('/api/export/all', (req, res) => {
|
||||
try {
|
||||
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const out = `/tmp/nexusops-export-${stamp}.tar.gz`;
|
||||
require('child_process').execSync(`tar czf ${out} -C ${DATA_DIR} .`);
|
||||
res.download(out, `nexusops-full-export-${stamp}.tar.gz`, () => {
|
||||
try { fs.unlinkSync(out); } catch (e) {}
|
||||
});
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: 'export failed: ' + e.message });
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(PORT, '0.0.0.0', () => {
|
||||
|
||||
Reference in New Issue
Block a user