From 5c286af43b079bb5bc1fbe89a93c2c01542abc8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sun, 31 May 2026 07:25:42 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20entries.js=20=E2=80=94=20remove=20'?= =?UTF-8?q?own'=20hack,=20clean=20admin=20company=20routing=20+=20bump=200?= =?UTF-8?q?.4.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- ui/routes/entries.js | 77 +++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 869dcc0..48bce8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.4.6", + "version": "0.4.7", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/ui/routes/entries.js b/ui/routes/entries.js index 95e9380..4bf50f5 100644 --- a/ui/routes/entries.js +++ b/ui/routes/entries.js @@ -4,8 +4,12 @@ * ui/routes/entries.js — главная страница: список записей + CRUD. * * Данные из /api/v1/entries (Bearer token из сессии). - * Admin: поддержка ?company= (числовой PK) для управления другой компанией. - * Формы с company_id скрытым полем → передаётся в API как ?company=. + * Admin: ?company= (числовой PK) для управления конкретной компанией. + * - Без параметра: ищем компанию admin в списке по clientId. + * Если не найдена (первый вход) — один GET /api/v1/entries создаёт её, + * потом редирект на числовой ID. + * - С параметром: грузим записи этой компании через admin-ветку API. + * User: без параметра, API сам определяет компанию по clientId из токена. */ const { Router } = require('express'); @@ -14,19 +18,16 @@ const api = require('../api-client'); function createRouter() { const router = Router(); - // Вычислить URL для возврата (с учётом выбранной компании) + // URL для возврата после CRUD — всегда с числовым company ID function backUrl(req) { - const companyId = req.query.company || (req.body && req.body.company_id); - if (!companyId || companyId === 'own') return '/?company=own'; - return '/?company=' + companyId; + const id = req.query.company || (req.body && req.body.company_id); + return id ? '/?company=' + id : '/'; } - // Суффикс ?company= для вызовов API - // 'own' = компания admin без ?company — API использует getOrCreateCompany + // Суффикс ?company= для API — только числовой ID или пусто function companyQuery(req) { - const companyId = req.query.company || (req.body && req.body.company_id); - if (!companyId || companyId === 'own') return ''; - return '?company=' + companyId; + const id = req.query.company || (req.body && req.body.company_id); + return id ? '?company=' + id : ''; } // GET / — список записей @@ -39,29 +40,25 @@ function createRouter() { const cr = await api.get('/api/v1/companies', token); companies = cr.data.companies || []; - const companyParam = req.query.company || ''; - const companyId = companyParam && companyParam !== 'own' ? parseInt(companyParam, 10) : null; + const companyId = req.query.company ? parseInt(req.query.company, 10) : null; - // Без параметра — редирект на свою компанию - if (!companyParam) { - return res.redirect('/?company=own'); + if (!companyId) { + // Найти свою компанию admin по clientId + let ownCo = companies.find(c => c.client_id === req.user.clientId) || null; + if (!ownCo) { + // Компании нет — создаём через первый GET /entries (getOrCreateCompany внутри) + await api.get('/api/v1/entries', token); + const cr2 = await api.get('/api/v1/companies', token); + ownCo = (cr2.data.companies || []).find(c => c.client_id === req.user.clientId) || null; + } + return res.redirect('/?company=' + (ownCo ? ownCo.id : '')); } - if (companyParam === 'own') { - // Создаём/получаем компанию admin через API (getOrCreateCompany) - await api.get('/api/v1/entries', token); - // Перезагружаем список — теперь компания admin точно есть - const cr2 = await api.get('/api/v1/companies', token); - const adminCo = (cr2.data.companies || []).find(c => c.client_id === req.user.clientId); - return res.redirect('/?company=' + (adminCo ? adminCo.id : '')); - } else { - selectedCompany = companyId ? companies.find(c => c.id === companyId) || null : null; - - if (selectedCompany) { - const er = await api.get('/api/v1/entries?company=' + companyId, token); - entries = er.data.entries || []; - limit = er.data.limit || selectedCompany.custom_limit || selectedCompany.default_limit || 15; - } + selectedCompany = companies.find(c => c.id === companyId) || null; + if (selectedCompany) { + const er = await api.get('/api/v1/entries?company=' + companyId, token); + entries = er.data.entries || []; + limit = er.data.limit || 15; } } else { const er = await api.get('/api/v1/entries', token); @@ -72,21 +69,21 @@ function createRouter() { res.render('index', { entries, limit, - used: entries.length, - user: req.user, - isAdmin: req.user.isAdmin, + used: entries.length, + user: req.user, + isAdmin: req.user.isAdmin, companies, selectedCompany, - error: req.query.error || null, - success: req.query.success || null, - csrfToken: '', + error: req.query.error || null, + success: req.query.success || null, + csrfToken: '', }); } catch (e) { res.render('index', { entries: [], limit: 15, used: 0, user: req.user, isAdmin: req.user.isAdmin, companies: [], selectedCompany: null, - error: 'Ошибка загрузки данных: ' + e.message, + error: 'Ошибка загрузки: ' + e.message, success: null, csrfToken: '', }); } @@ -106,7 +103,7 @@ function createRouter() { : 'Запись добавлена'; return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent(msg)); } - res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(r.data.error || 'Ошибка')); + res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent((r.data && r.data.error) || 'Ошибка')); } catch (e) { res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message)); } @@ -123,7 +120,7 @@ function createRouter() { if (r.status === 200) { return res.redirect(back + (back.includes('?') ? '&' : '?') + 'success=' + encodeURIComponent('Запись обновлена')); } - res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(r.data.error || 'Ошибка')); + res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent((r.data && r.data.error) || 'Ошибка')); } catch (e) { res.redirect(back + (back.includes('?') ? '&' : '?') + 'error=' + encodeURIComponent(e.message)); }