From deeb54af1c495e0fc21f48d0d1df58acae9e0e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 22 Jun 2026 20:22:37 +0400 Subject: [PATCH] export view=2 HTML table --- package.json | 2 +- v2/src/export/index.js | 46 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 98a9e8c..afda5ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.5.178", + "version": "0.5.179", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/v2/src/export/index.js b/v2/src/export/index.js index 28bcf55..ccff215 100644 --- a/v2/src/export/index.js +++ b/v2/src/export/index.js @@ -13,8 +13,9 @@ // // ПАРАМЕТРЫ: // ?companyId=X — фильтр по компании (внутренний id) -// ?view=1 — показать в браузере (иначе — скачивание) -// ?filename=X — имя файла (по умолчанию white-list.txt) +// ?view=1 — text/plain inline (копирование) +// ?view=2 — HTML таблица с выровненными IP +// ?filename=X — имя файла (скачивание, когда нет view) // ═══════════════════════════════════════════════════════════════════════════════ const express = require('express'); @@ -29,13 +30,26 @@ function createExportRouter() { 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, '_'); - const disp = req.query.view === '1' ? 'inline' : 'attachment'; - res.set('Content-Disposition', disp + '; filename="' + fname + '"'); + res.set('Content-Disposition', 'attachment; filename="' + fname + '"'); res.send(text); } catch (e) { console.error('[v2:export] Error:', e); @@ -46,4 +60,24 @@ function createExportRouter() { 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) + '').join('\n'); + return 'WhiteList Export' + + '' + + '

WhiteList — ' + cidrs.length + ' записей

' + + '' + rows + '
' + + ''; +} + module.exports = { createExportRouter };