refactor: entries.js — remove 'own' hack, clean admin company routing + bump 0.4.7

This commit is contained in:
2026-05-31 07:25:42 +03:00
parent a355b34e4a
commit 5c286af43b
2 changed files with 38 additions and 41 deletions
+1 -1
View File
@@ -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": {
+28 -31
View File
@@ -4,8 +4,12 @@
* ui/routes/entries.js — главная страница: список записей + CRUD.
*
* Данные из /api/v1/entries (Bearer token из сессии).
* Admin: поддержка ?company=<id> (числовой PK) для управления другой компанией.
* Формы с company_id скрытым полем → передаётся в API как ?company=<id>.
* Admin: ?company=<id> (числовой 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=<id> для вызовов API
// 'own' = компания admin без ?company — API использует getOrCreateCompany
// Суффикс ?company=<id> для 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;
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 || selectedCompany.custom_limit || selectedCompany.default_limit || 15;
}
limit = er.data.limit || 15;
}
} else {
const er = await api.get('/api/v1/entries', token);
@@ -86,7 +83,7 @@ function createRouter() {
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));
}