All files / src/routes dashboard.js

0% Statements 0/24
0% Branches 0/8
0% Functions 0/2
0% Lines 0/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61                                                                                                                         
/**
 * Routes Dashboard — Métriques système du serveur distant.
 *
 * Endpoint :
 *   GET /servers/:serverId/dashboard — CPU, RAM, disque, uptime, load
 *
 * Les commandes exécutées sont hardcodées (pas d'injection possible).
 * Les 5 commandes sont lancées en parallèle pour minimiser la latence.
 *
 * @module routes/dashboard
 */
 
const express = require('express');
const { requireAuth } = require('../middleware/auth');
const { requireGroupContext, requireGroupPermission, requireGroupServer } = require('../middleware/groupContext');
const { exec } = require('../services/ssh');
const { parseCpu, parseFree, parseDf } = require('../utils/parsers');
 
const router = express.Router({ mergeParams: true });
 
router.use(requireAuth);
router.use(requireGroupContext());
 
// ─── GET /servers/:serverId/dashboard ────────────────────────────────────────
 
router.get('/', requireGroupServer(), requireGroupPermission('dashboard', 'read'), async (req, res, next) => {
  const { serverId } = req.params;
  const userId = req.user.id;
 
  try {
    // Lancer toutes les commandes en parallèle (commandes hardcodées = sûres)
    const [cpuRes, memRes, diskRes, uptimeRes, loadRes] = await Promise.allSettled([
      exec(userId, serverId, String.raw`top -bn1 | grep '%Cpu\|cpu'`),
      exec(userId, serverId, 'free -m'),
      exec(userId, serverId, 'df -h'),
      exec(userId, serverId, 'uptime -p'),
      exec(userId, serverId, 'cat /proc/loadavg'),
    ]);
 
    // Helper pour extraire stdout d'un résultat Promise.allSettled
    const getData = (r) => (r.status === 'fulfilled' ? r.value.stdout : '');
 
    const cpu = parseCpu(getData(cpuRes));
    const memory = parseFree(getData(memRes));
    const disk = parseDf(getData(diskRes));
    const uptime = getData(uptimeRes).trim().replace(/^up /, '');
    const loadRaw = getData(loadRes).trim().split(' ');
    const load = {
      '1m': Number.parseFloat(loadRaw[0]) || null,
      '5m': Number.parseFloat(loadRaw[1]) || null,
      '15m': Number.parseFloat(loadRaw[2]) || null,
    };
 
    res.json({ cpu, memory, disk, uptime, load });
  } catch (err) {
    next(err);
  }
});
 
module.exports = router;