From 5b92dfe1e7ed334f1ca766b9d36803590590ff1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 15 Jun 2026 09:33:45 +0400 Subject: [PATCH] =?UTF-8?q?v2=E2=86=92main:=20=D0=B8=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=E2=80=94=20v2=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BA=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=B9?= =?UTF-8?q?=20UI=20(/),=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D0=B9=20UI=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- server.js | 5 +++-- v2/server.js | 26 +++++++++++++------------- v2/src/admin/index.js | 14 +++++++------- v2/src/config/index.js | 2 +- v2/src/router/index.js | 2 +- v2/src/user/index.js | 16 ++++++++-------- views/v2/admin-audit.ejs | 2 +- views/v2/admin-entries.ejs | 2 +- views/v2/admin.ejs | 12 ++++++------ views/v2/user.ejs | 18 +++++++++--------- 11 files changed, 51 insertions(+), 50 deletions(-) diff --git a/package.json b/package.json index ccba39c..bd28f3c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.5.98", + "version": "0.5.99", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/server.js b/server.js index 3264bc7..0f61797 100644 --- a/server.js +++ b/server.js @@ -137,9 +137,10 @@ async function start() { // Монтируется ПОСЛЕ /api/v1/ — не перехватывает API-запросы. // ── V2 — тестовый роутер (Keycloak → IAM → вывод) ───────────────── const { createV2Router } = require('./v2/server'); - app.use('/v2', createV2Router()); + app.use('/', createV2Router()); // Хранит Bearer token в сессии, рендерит те же views/*.ejs. - app.use('/', createUiRouter({ auth, MOCK_USERS, authLimiter })); + // ── Старый UI (заменён на v2) ──────────────────────────────────────── + // app.use('/', createUiRouter({ auth, MOCK_USERS, authLimiter })); // ── Общий обработчик ошибок ─────────────────────────────────────────────── // eslint-disable-next-line no-unused-vars diff --git a/v2/server.js b/v2/server.js index 9e95a79..f3b5100 100644 --- a/v2/server.js +++ b/v2/server.js @@ -5,7 +5,7 @@ // ЗАЧЕМ: единственная точка входа v2 в основное приложение. // // МОНТАЖ В ОСНОВНОМ server.js: -// const { createV2Router } = require('./v2/server'); +// const { createV2Router } = require('./server'); // app.use('/v2', createV2Router()); // // ПОРЯДОК МАРШРУТОВ (важен!): @@ -38,39 +38,39 @@ function createV2Router() { const router = express.Router(); - // ── GET /v2/login — редирект на основной вход (KC OIDC) ───────────── + // ── GET /login-v2 — редирект на основной вход (KC OIDC) ───────────── router.get('/login', (req, res) => { - res.redirect('/login?returnTo=' + encodeURIComponent('/v2/app')); + res.redirect('/login?returnTo=' + encodeURIComponent('/app')); }); - // ── GET /v2/iam — отладка: показать IAM-данные из сессии ──────────── + // ── GET /iam — отладка: показать IAM-данные из сессии ──────────── router.get('/iam', (req, res) => { const u = req.session && req.session.user; - if (!u) return res.send('

Нет данных

Войти

'); + if (!u) return res.send('

Нет данных

Войти

'); res.send(debugPage(u, config.version)); }); - // ── /v2/app — пользовательский CRUD (только с сессией) ────────────── + // ── /app — пользовательский CRUD (только с сессией) ────────────── router.use('/app', enhanceImpersonation, resolveContext, createUserRouter()); - // ── /v2/admin — админка (только для isAdmin=true) ──────────────────── + // ── /admin — админка (только для isAdmin=true) ──────────────────── router.use('/admin', enhanceImpersonation, resolveContext, createAdminRouter()); - // ── GET /v2/ — редирект на /v2/app ────────────────────────────────── - router.get('/', (req, res) => res.redirect('/v2/app')); + // ── GET / — редирект на /app ────────────────────────────────── + router.get('/', (req, res) => res.redirect('/app')); - // ── /v2/test — тестовый API (отключить: ENABLE_TEST_API=false) ────── + // ── /test — тестовый API (отключить: ENABLE_TEST_API=false) ────── // Код остаётся, роутер не монтируется при ENABLE_TEST_API=false. if (process.env.ENABLE_TEST_API !== 'false') { const { createTestRouter } = require('./src/test'); router.use('/test', createTestRouter()); } - // ── /v2/export — выгрузка CIDR (публичный, без авторизации) ────── + // ── /export — выгрузка CIDR (публичный, без авторизации) ────── const { createExportRouter } = require('./src/export'); router.use('/export', createExportRouter()); - // ── GET /v2/logout — редирект на основной выход ───────────────────── + // ── GET /logout — редирект на основной выход ───────────────────── router.get('/logout', (req, res) => res.redirect('/logout')); return router; @@ -88,7 +88,7 @@ function debugPage(u, version) {

ФИО: ${(u.fio && u.fio.fullName) || u.fio || '—'}

Компаний: ${u.allClientIds ? u.allClientIds.length : 0} — ${(u.allClientIds || []).join(', ')}


${JSON.stringify(u, null, 2)}
-

Выйти | CRUD | Админка

+

Выйти | CRUD | Админка

`; } diff --git a/v2/src/admin/index.js b/v2/src/admin/index.js index 6f26e07..c3bb3ca 100644 --- a/v2/src/admin/index.js +++ b/v2/src/admin/index.js @@ -5,9 +5,9 @@ // НЕ: доступно обычным юзерам (middleware: req.isAdmin). // // ШАБЛОНЫ: -// views/v2/admin.ejs — дашборд (companies, user, version) -// views/v2/admin-audit.ejs — аудит (audit, company, version) -// views/v2/admin-entries.ejs — записи (entries, company, used, limit, ...) +// views/admin.ejs — дашборд (companies, user, version) +// views/admin-audit.ejs — аудит (audit, company, version) +// views/admin-entries.ejs — записи (entries, company, used, limit, ...) // ═══════════════════════════════════════════════════════════════════════════════ const express = require('express'); @@ -19,7 +19,7 @@ function createAdminRouter() { const router = express.Router(); router.use((req, res, next) => { - if (!req.isAdmin) return res.redirect('/v2/app'); + if (!req.isAdmin) return res.redirect('/app'); next(); }); @@ -52,9 +52,9 @@ function createAdminRouter() { const newLimit = parseInt(req.body.limit); if (!companyId || !newLimit || newLimit < 1) throw new Error('Неверные параметры'); await q.setLimit(companyId, newLimit); - res.redirect('/v2/admin?msg=' + encodeURIComponent('Лимит установлен: ' + newLimit)); + res.redirect('/admin?msg=' + encodeURIComponent('Лимит установлен: ' + newLimit)); } catch (e) { - res.redirect('/v2/admin?error=' + encodeURIComponent(e.message)); + res.redirect('/admin?error=' + encodeURIComponent(e.message)); } }); @@ -63,7 +63,7 @@ function createAdminRouter() { try { const companyId = parseInt(req.query.companyId); const company = companyId ? await q.getCompanyById(companyId) : null; - if (!company) return res.redirect('/v2/admin'); + if (!company) return res.redirect('/admin'); const includeDeleted = req.query.deleted === '1'; const { entries, used, limit } = await crud.list(company.client_id, includeDeleted); res.render('v2/admin-entries', { entries, company, used, limit, includeDeleted, version: config.version }); diff --git a/v2/src/config/index.js b/v2/src/config/index.js index 4559e21..985c632 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -9,7 +9,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.5.98', + version: '0.5.99', // ── IAM ────────────────────────────────────────────────────────────────── iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user', diff --git a/v2/src/router/index.js b/v2/src/router/index.js index 31574d0..a6d988a 100644 --- a/v2/src/router/index.js +++ b/v2/src/router/index.js @@ -30,7 +30,7 @@ function resolveContext(req, res, next) { const u = req.session && req.session.user; // Нет сессии — нет доступа - if (!u) return res.redirect('/v2/login'); + if (!u) return res.redirect('/login'); // Имперсонация: админ действует от имени компании // u.originalUserEmail — реальный админ diff --git a/v2/src/user/index.js b/v2/src/user/index.js index 676c283..fe74780 100644 --- a/v2/src/user/index.js +++ b/v2/src/user/index.js @@ -29,7 +29,7 @@ function createUserRouter() { // Переключение компании if (req.query.switchTo && allCompanies.find(c => c.client_id === req.query.switchTo)) { req.session.user.activeClientId = req.query.switchTo; - return res.redirect('/v2/app'); + return res.redirect('/app'); } res.render('v2/user', { @@ -41,7 +41,7 @@ function createUserRouter() { version: config.version, }); } catch (e) { - res.status(500).send('

Ошибка

' + e.message + '
Назад'); + res.status(500).send('

Ошибка

' + e.message + '
Назад'); } }); @@ -50,9 +50,9 @@ function createUserRouter() { try { const result = await crud.add(req.clientId, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy); const msg = result.wasNormalized ? 'Добавлено (адрес нормализован)' : 'Добавлено'; - res.redirect('/v2/app?msg=' + encodeURIComponent(msg)); + res.redirect('/app?msg=' + encodeURIComponent(msg)); } catch (e) { - res.redirect('/v2/app?error=' + encodeURIComponent(e.message)); + res.redirect('/app?error=' + encodeURIComponent(e.message)); } }); @@ -61,9 +61,9 @@ function createUserRouter() { try { const result = await crud.edit(parseInt(req.params.id), req.clientId, req.body.cidr || '', req.body.comment || '', req.email, req.impersonatedBy); const msg = result.wasNormalized ? 'Изменено (адрес нормализован)' : 'Изменено'; - res.redirect('/v2/app?msg=' + encodeURIComponent(msg)); + res.redirect('/app?msg=' + encodeURIComponent(msg)); } catch (e) { - res.redirect('/v2/app?error=' + encodeURIComponent(e.message)); + res.redirect('/app?error=' + encodeURIComponent(e.message)); } }); @@ -71,9 +71,9 @@ function createUserRouter() { router.post('/delete/:id', async (req, res) => { try { await crud.remove(parseInt(req.params.id), req.clientId, req.email, req.impersonatedBy); - res.redirect('/v2/app?msg=Удалено'); + res.redirect('/app?msg=Удалено'); } catch (e) { - res.redirect('/v2/app?error=' + encodeURIComponent(e.message)); + res.redirect('/app?error=' + encodeURIComponent(e.message)); } }); diff --git a/views/v2/admin-audit.ejs b/views/v2/admin-audit.ejs index 547cdbf..79520b8 100644 --- a/views/v2/admin-audit.ejs +++ b/views/v2/admin-audit.ejs @@ -10,7 +10,7 @@
📋 Аудит <%= company ? company.client_id : 'Все компании' %> - ← Админка | Пользовательский + ← Админка | Пользовательский
diff --git a/views/v2/admin-entries.ejs b/views/v2/admin-entries.ejs index e277802..23716c0 100644 --- a/views/v2/admin-entries.ejs +++ b/views/v2/admin-entries.ejs @@ -10,7 +10,7 @@
📋 Записи <%= company.client_id %> — <%= company.name || company.client_id %> - ← Админка + ← Админка

Записей: <%= used %> из <%= limit %> <%= includeDeleted ? '(с удалёнными: ' + entries.length + ')' : '' %>

ДатаДействиеКтоОт имениКомпанияЗначения
diff --git a/views/v2/admin.ejs b/views/v2/admin.ejs index 3afdb8a..bcd5656 100644 --- a/views/v2/admin.ejs +++ b/views/v2/admin.ejs @@ -13,12 +13,12 @@
🛡️ ADMIN v<%= version %> - <%= user.email || '—' %> | ← Пользовательский | Выйти + <%= user.email || '—' %> | ← Пользовательский | Выйти

Компании (<%= companies.length %>)

@@ -31,11 +31,11 @@ <% }) %>
<%= c.active_count %> / <%= c.custom_limit != null ? c.custom_limit : 15 %> <%= c.custom_limit != null ? c.custom_limit : '—' %> - аудит | - записи + аудит | + записи -
+ diff --git a/views/v2/user.ejs b/views/v2/user.ejs index 67e74ac..a69df32 100644 --- a/views/v2/user.ejs +++ b/views/v2/user.ejs @@ -11,26 +11,26 @@
V2 IP WhiteList v<%= version %> - <%= user.email %> <% if (user.isAdmin) { %>| ADMIN<% } %> + <%= user.email %> <% if (user.isAdmin) { %>| ADMIN<% } %> - + - Выйти + Выйти

Записей: <%= used %> из <%= limit %>

-
+ @@ -51,12 +51,12 @@ <% if (e.deleted_at) { %> удалено <% } else { %> - +
-
+
<% } %> @@ -64,5 +64,5 @@
-

<%= includeDeleted ? 'Скрыть удалённые' : 'Показать удалённые' %>

+

<%= includeDeleted ? 'Скрыть удалённые' : 'Показать удалённые' %>