Files
ipwhitelist-app/v2/src/export/index.js
T
2026-06-22 20:22:37 +04:00

84 lines
3.7 KiB
JavaScript

// ═══════════════════════════════════════════════════════════════════════════════
// 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 => '<tr><td><code>' + padIP(c) + '</code></td></tr>').join('\n');
return '<!DOCTYPE html><html><head><meta charset="utf-8"><title>WhiteList Export</title>'
+ '<style>body{font-family:monospace;background:#fff;color:#111;padding:1rem}'
+ 'h2{font-size:1rem;color:#666;margin-bottom:.5rem}'
+ 'table{border-collapse:collapse}'
+ 'td{padding:.15rem 1rem .15rem 0}'
+ 'code{font-size:.9rem}'
+ '</style></head><body>'
+ '<h2>WhiteList — ' + cidrs.length + ' записей</h2>'
+ '<table>' + rows + '</table>'
+ '</body></html>';
}
module.exports = { createExportRouter };