From 631641bbf067598dd2d6b240afff2c16bff1f2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sat, 30 May 2026 13:35:16 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20=D1=88=D0=B0=D0=B3=201=20=E2=80=94?= =?UTF-8?q?=20MOCK=5FUSERS=20=D0=B8=20backUrl=20=D0=B2=D1=8B=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D0=B5=D0=BD=D1=8B=20=D0=B2=20src/config.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 22 ++------------- src/config.js | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 src/config.js diff --git a/server.js b/server.js index 4f43684..b222f8e 100644 --- a/server.js +++ b/server.js @@ -9,6 +9,8 @@ const { checkConnection } = require('./src/db'); const { initAuth, requireAdmin } = require('./src/auth'); const { aggregateCIDRs } = require('./src/validators'); const q = require('./src/queries'); +// config.js: MOCK_USERS (мок-пользователи для dev) и backUrl (хелпер редиректа) +const { MOCK_USERS, backUrl } = require('./src/config'); const app = express(); const PORT = process.env.PORT || 3000; @@ -45,26 +47,6 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use(express.urlencoded({ extended: true, limit: '32kb' })); app.use(cookieParser()); -// ── Мок-пользователи для dev/staging ────────────────────────────────────────── -// В продакшене удаляются — вход через Keycloak, clientId берётся из токена. -const MOCK_USERS = [ - { id: 'admin', label: 'Администратор (WZ01112)', role: 'admin', clientId: 'WZ01112', companyId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', companyName: 'Nubes Admin', email: 'admin@nubes.ru' }, - { id: 'test', label: 'Тест (WZ01325)', role: 'user', clientId: 'WZ01325', companyId: '3e64aac6-dcfc-4082-88dc-da19c86555a5', companyName: 'Тест', email: 'tazet@narod.ru' }, - { id: 'client2', label: 'Компания 2 (WZ02001)', role: 'user', clientId: 'WZ02001', companyId: '11111111-2222-3333-4444-555555555555', companyName: 'Вторая Компания', email: 'user2@example.com' }, -]; - -// ── Вспомогательная функция редиректа ───────────────────────────────────────── -// Строит URL для возврата на главную страницу с учётом контекста: -// admin возвращается к выбранной компании (/?company=X), -// обычный пользователь — просто на /. -function backUrl(isAdmin, companyId, extra = {}) { - const qs = new URLSearchParams(); - if (isAdmin && companyId) qs.set('company', companyId); - for (const [k, v] of Object.entries(extra)) qs.set(k, String(v)); - const str = qs.toString(); - return str ? '/?' + str : '/'; -} - async function start() { const auth = await initAuth(); diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..977b9c6 --- /dev/null +++ b/src/config.js @@ -0,0 +1,74 @@ +/** + * src/config.js — общие константы и утилиты приложения. + * + * Вынесено из server.js чтобы: + * 1. Роуты могли импортировать MOCK_USERS и backUrl без циклических зависимостей. + * 2. Конфигурация была в одном месте — проще менять и тестировать. + * + * Этот файл не зависит ни от Express, ни от БД — чистые данные и функции. + */ + +'use strict'; + +// ── Мок-пользователи (только dev/staging) ───────────────────────────────────── +// В продакшене этот список не используется — вход через Keycloak. +// clientId соответствует WZ-номеру компании в Nubes. +// companyId — UUID клиента (из Keycloak-токена в продакшене). +const MOCK_USERS = [ + { + id: 'admin', + label: 'Администратор (WZ01112)', + role: 'admin', + clientId: 'WZ01112', + companyId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', + companyName: 'Nubes Admin', + email: 'admin@nubes.ru', + }, + { + id: 'test', + label: 'Тест (WZ01325)', + role: 'user', + clientId: 'WZ01325', + companyId: '3e64aac6-dcfc-4082-88dc-da19c86555a5', + companyName: 'Тест', + email: 'tazet@narod.ru', + }, + { + id: 'client2', + label: 'Компания 2 (WZ02001)', + role: 'user', + clientId: 'WZ02001', + companyId: '11111111-2222-3333-4444-555555555555', + companyName: 'Вторая Компания', + email: 'user2@example.com', + }, +]; + +// ── backUrl — строит URL для редиректа после мутирующего действия ────────────── +// +// Логика: +// • admin всегда видит страницу в контексте конкретной компании (?company=). +// Поэтому после POST /add, /edit, /delete редиректим туда же. +// • Обычный пользователь видит только свою страницу — просто /. +// +// extra — дополнительные query-параметры, например { message: 'Добавлено' } +// или { error: 'Лимит исчерпан' }. +// +// Примеры: +// backUrl(true, 42, { message: 'OK' }) → '/?company=42&message=OK' +// backUrl(false, 42, { error: 'Err' }) → '/?error=Err' +// backUrl(false, null, {}) → '/' +function backUrl(isAdmin, companyId, extra = {}) { + const qs = new URLSearchParams(); + + // Добавляем company только для admin и только если companyId задан + if (isAdmin && companyId) qs.set('company', companyId); + + // Добавляем все дополнительные параметры (message, error, wasNormalized и др.) + for (const [k, v] of Object.entries(extra)) qs.set(k, String(v)); + + const str = qs.toString(); + return str ? '/?' + str : '/'; +} + +module.exports = { MOCK_USERS, backUrl };