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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /** * Routes Webhooks — CRUD des webhooks de notification. * * @module routes/webhooks */ const express = require('express'); const { pool: db } = require('../db'); const { requireAuth } = require('../middleware/auth'); const { checkQuota } = require('../middleware/planLimits'); const { validatePublicUrl } = require('../utils/networkValidator'); const { VALID_PLATFORMS, VALID_EVENTS } = require('../helpers/webhookConstants'); const { requireGroupContext, requireGroupPermission } = require('../middleware/groupContext'); const router = express.Router(); router.use(requireAuth); router.use(requireGroupContext()); router.get('/', requireGroupPermission('webhooks', 'read'), async (req, res, next) => { try { const { rows } = await db.query('SELECT * FROM webhooks WHERE user_id = $1 ORDER BY created_at DESC', [req.user.id]); res.json(rows); } catch (err) { next(err); } }); router.post('/', requireGroupPermission('webhooks', 'read'), checkQuota('webhooks', 'webhooks'), async (req, res, next) => { try { const { label, url, platform = 'discord', events } = req.body; if (!label || !url) return res.status(400).json({ error: 'label et url sont requis.' }); if (!VALID_PLATFORMS.includes(platform)) return res.status(400).json({ error: `Platform invalide. Valeurs: ${VALID_PLATFORMS.join(', ')}` }); // Protection SSRF : bloquer les IPs privees const urlCheck = await validatePublicUrl(url); if (!urlCheck.valid) { return res.status(400).json({ error: urlCheck.reason }); } const filteredEvents = (events || VALID_EVENTS).filter((e) => VALID_EVENTS.includes(e)); const { rows } = await db.query( `INSERT INTO webhooks (user_id, label, url, platform, events) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [req.user.id, label, url, platform, filteredEvents], ); res.status(201).json(rows[0]); } catch (err) { next(err); } }); router.patch('/:id', requireGroupPermission('webhooks', 'read'), async (req, res, next) => { try { const { label, url, platform, events, enabled } = req.body; const existing = await db.query('SELECT * FROM webhooks WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]); if (existing.rows.length === 0) return res.status(404).json({ error: 'Webhook introuvable.' }); const w = existing.rows[0]; const { rows } = await db.query( 'UPDATE webhooks SET label=$1, url=$2, platform=$3, events=$4, enabled=$5 WHERE id=$6 AND user_id=$7 RETURNING *', [label ?? w.label, url ?? w.url, platform ?? w.platform, events ?? w.events, enabled == null ? w.enabled : Boolean(enabled), req.params.id, req.user.id], ); res.json(rows[0]); } catch (err) { next(err); } }); router.delete('/:id', requireGroupPermission('webhooks', 'read'), async (req, res, next) => { try { const result = await db.query('DELETE FROM webhooks WHERE id = $1 AND user_id = $2 RETURNING id', [req.params.id, req.user.id]); if (result.rows.length === 0) return res.status(404).json({ error: 'Webhook introuvable.' }); res.json({ message: 'Webhook supprimé.' }); } catch (err) { next(err); } }); // Test : envoie un message de test au webhook router.post('/:id/test', requireGroupPermission('webhooks', 'read'), async (req, res, next) => { try { const { rows } = await db.query('SELECT * FROM webhooks WHERE id = $1 AND user_id = $2', [req.params.id, req.user.id]); if (rows.length === 0) return res.status(404).json({ error: 'Webhook introuvable.' }); const { notify } = require('../services/webhookNotifier'); // Envoyer directement au webhook spécifique const wh = rows[0]; await notify(req.user.id, 'server_alert', { title: 'Test IliaCloud', message: `Webhook "${wh.label}" fonctionne correctement !`, fields: [{ name: 'Plateforme', value: wh.platform, inline: true }], }); res.json({ ok: true, message: 'Message de test envoyé.' }); } catch (err) { next(err); } }); module.exports = router; |