63 lines
2.1 KiB
JavaScript
63 lines
2.1 KiB
JavaScript
import express from 'express';
|
|
import { enqueueCmd } from '../services/natQueue.js';
|
|
import { runRouterCmds } from '../services/sshExec.js';
|
|
import { error, info } from '../util/Console.js';
|
|
|
|
const router = express.Router();
|
|
|
|
const SAFE_CMD_REGX = /^\s*(show|ping|traceroute|terminal length|show ip|show interfaces|show version|show running-config|show ip nat)\b/i;
|
|
|
|
function checkAdminToken(req) {
|
|
const token = req.headers['x-admin-token'] || req.body.token || req.query.token;
|
|
const saved = req.app.get('adminToken');
|
|
const expiry = req.app.get('adminTokenExpory') || 0;
|
|
if (!token || !saved) return false;
|
|
if (Date.now() > expiry) return false;
|
|
return token === saved;
|
|
}
|
|
|
|
router.post('/', async (req, res) => {
|
|
const cmd = (req.body && req.body.cmd) || '';
|
|
if (!cmd) return res.status(400).json({ error: 'no command' });
|
|
const isAdmin = checkAdminToken(req);
|
|
if (!isAdmin && !SAFE_CMD_REGX.test(cmd)) return res.status(403).json({ error: 'not allowed' });
|
|
|
|
info(`Exec requested${isAdmin ? ' [admin]' : ''}: ${cmd}`);
|
|
|
|
try {
|
|
enqueueCmd(() => runRouterCmds([cmd]));
|
|
res.json({ success: true });
|
|
} catch (err) {
|
|
error(err);
|
|
res.status(500).json({ error: 'exec failed' });
|
|
}
|
|
});
|
|
|
|
router.get('/stream', (req, res) => {
|
|
const cmd = req.query.cmd || '';
|
|
if (!cmd) return res.status(400).send('no command');
|
|
const isAdmin = checkAdminToken(req);
|
|
if (!isAdmin && !SAFE_CMD_REGX.test(cmd)) return res.status(400).send('not allowed');
|
|
|
|
res.setHeader('Content-Type', 'text/event-stream');
|
|
res.setHeader('Cache-Control', 'no-cache');
|
|
res.setHeader('Connection', 'keep-alive');
|
|
res.flushHeaders && res.flushHeaders();
|
|
|
|
enqueueCmd(() => new Promise(async (resolve) => {
|
|
try {
|
|
await runRouterCmds([cmd], chunk => {
|
|
res.write(`data: ${chunk.replace(/\n/g, '\\n')}\n\n`);
|
|
});
|
|
res.write('data: [[EOF]]\n\n');
|
|
res.end();
|
|
resolve()
|
|
} catch (err) {
|
|
res.write(`data: [ERROR] ${String(err)}\n\n`);
|
|
res.end();
|
|
resolve();
|
|
}
|
|
}));
|
|
});
|
|
|
|
export default router; |