// ═══════════════════════════════════════════════════════════════════════════════ // V2 — Экспорт CIDR (отдельный слой) // // ЭТО: выгрузка разрешённых CIDR в текстовом виде. // НЕ: CRUD, валидация (использует db + validators). // // ЗАЧЕМ: // 1. Отдать CIDR для firewall/nginx белого списка. // 2. Агрегировать соседние CIDR в минимальный набор (экономия правил). // 3. Поддержка фильтрации по компании (?companyId=X). // // ЦЕПОЧКА: GET /v2/export → q.getExportCIDRs → aggregateCIDRs → text/plain // // ПАРАМЕТРЫ: // ?companyId=X — фильтр по компании (внутренний id) // ?view=1 — text/plain inline (копирование) // ?view=2 — HTML таблица с выровненными IP // ?filename=X — имя файла (скачивание, когда нет view) // ═══════════════════════════════════════════════════════════════════════════════ const express = require('express'); const q = require('../db/queries'); const { aggregateCIDRs } = require('../validators'); function createExportRouter() { const router = express.Router(); router.get('/', async (req, res) => { try { const companyId = req.query.companyId ? parseInt(req.query.companyId) : null; const cidrs = await q.getExportCIDRs(companyId); const aggregated = aggregateCIDRs(cidrs); // ?view=2 — HTML таблица с выровненными IP if (req.query.view === '2') { res.set('Content-Type', 'text/html; charset=utf-8'); return res.send(renderTable(aggregated)); } // ?view=1 — text/plain inline if (req.query.view === '1') { const text = aggregated.join('\n') + (aggregated.length ? '\n' : ''); res.set('Content-Type', 'text/plain; charset=utf-8'); res.set('Content-Disposition', 'inline'); return res.send(text); } // Скачивание (по умолчанию) const text = aggregated.join('\n') + (aggregated.length ? '\n' : ''); res.set('Content-Type', 'text/plain; charset=utf-8'); const fname = (req.query.filename || 'white-list.txt').replace(/[^\w\-_. ]/g, '_'); res.set('Content-Disposition', 'attachment; filename="' + fname + '"'); res.send(text); } catch (e) { console.error('[v2:export] Error:', e); res.status(500).send('Ошибка экспорта'); } }); return router; } function padIP(cidr) { const [ip, mask] = cidr.split('/'); const octets = ip.split('.').map(o => o.padStart(3, ' ')); return octets.join('.') + '/' + mask; } function renderTable(cidrs) { const rows = cidrs.map(c => '
' + padIP(c) + '