Шаг 1: /toggle-admin роут в ui/routes/auth.js - переключает req.session.adminMode - canAdmin = isAdmin || clientId === WZ01112 (временно) Шаг 2: resolveUser в ui/index.js - req.user.adminMode из req.session.adminMode - isAdmin = IAM.isAdmin || clientId === WZ01112 (временно) Шаг 3: adminMode вместо isAdmin в интерфейсе - ui/routes/entries.js: adminMode решает админский view - ui/routes/admin.js: requireAdmin проверяет adminMode Шаг 4: views/index.ejs - чек-бокс «Администратор» (виден только если isAdmin) - ссылки Аудит/Лимиты видны только при adminMode - селектор компаний — при adminMode
93 lines
3.1 KiB
JavaScript
93 lines
3.1 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* ui/routes/admin.js — /admin, /audit (только для администратора).
|
|
* /export — доступен всем аутентифицированным (смотри ui/routes/export.js).
|
|
*
|
|
* Данные из:
|
|
* GET /api/v1/companies
|
|
* PATCH /api/v1/companies/:id/limit
|
|
* GET /api/v1/audit
|
|
*/
|
|
|
|
const { Router } = require('express');
|
|
const api = require('../api-client');
|
|
|
|
function requireAdmin(req, res, next) {
|
|
if (!req.user || !req.user.adminMode) {
|
|
return res.status(403).render('error', {
|
|
status: 403,
|
|
message: 'Доступ запрещён — требуются права администратора.',
|
|
});
|
|
}
|
|
next();
|
|
}
|
|
|
|
function createRouter() {
|
|
const router = Router();
|
|
router.use(requireAdmin);
|
|
|
|
// GET /admin — список компаний с лимитами
|
|
router.get('/admin', async (req, res) => {
|
|
const token = api.token(req);
|
|
try {
|
|
const r = await api.get('/api/v1/companies', token);
|
|
const companies = r.data.companies || [];
|
|
const defaultLimit = parseInt(process.env.DEFAULT_LIMIT, 10) || 15;
|
|
res.render('admin', {
|
|
user: req.user,
|
|
companies,
|
|
defaultLimit,
|
|
error: req.query.error || null,
|
|
success: req.query.success || null,
|
|
csrfToken: '',
|
|
});
|
|
} catch (e) {
|
|
const defaultLimit = parseInt(process.env.DEFAULT_LIMIT, 10) || 15;
|
|
res.render('admin', {
|
|
user: req.user, companies: [], defaultLimit,
|
|
error: 'Ошибка загрузки: ' + e.message, success: null, csrfToken: '',
|
|
});
|
|
}
|
|
});
|
|
|
|
// POST /admin/limit/:id — установить лимит компании
|
|
router.post('/admin/limit/:id', async (req, res) => {
|
|
const token = api.token(req);
|
|
const rawLimit = req.body.limit;
|
|
const limit = (rawLimit === '' || rawLimit == null) ? null : parseInt(rawLimit, 10);
|
|
try {
|
|
const r = await api.patch('/api/v1/companies/' + req.params.id + '/limit', token, { limit });
|
|
if (r.status === 200) return res.redirect('/admin?success=' + encodeURIComponent('Лимит обновлён'));
|
|
res.redirect('/admin?error=' + encodeURIComponent(r.data.error || 'Ошибка'));
|
|
} catch (e) {
|
|
res.redirect('/admin?error=' + encodeURIComponent(e.message));
|
|
}
|
|
});
|
|
|
|
// GET /audit — журнал действий
|
|
router.get('/audit', async (req, res) => {
|
|
const token = api.token(req);
|
|
const companyId = req.query.company ? parseInt(req.query.company, 10) : null;
|
|
try {
|
|
const r = await api.get('/api/v1/audit' + (companyId ? '?company=' + companyId : ''), token);
|
|
res.render('audit', {
|
|
user: req.user,
|
|
rows: r.data.rows || [],
|
|
companies: r.data.companies || [],
|
|
selectedCompanyId: companyId,
|
|
error: null,
|
|
});
|
|
} catch (e) {
|
|
res.render('audit', {
|
|
user: req.user, rows: [], companies: [],
|
|
selectedCompanyId: null, error: 'Ошибка загрузки: ' + e.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
return router;
|
|
}
|
|
|
|
module.exports = { createRouter };
|