fix(audit): убрано ограничение по дате — по умолчанию ВСЕ записи
- getAudit(): days=null → без фильтра WHERE по дате - days передаётся только если явно выбран фильтр 30/90/365 - admin-audit.ejs: кнопка «Всё» (активна по умолчанию), заголовок «(всё время)» v0.1.9 → v0.1.10
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipwhitelist",
|
"name": "ipwhitelist",
|
||||||
"version": "0.1.9",
|
"version": "0.1.10",
|
||||||
"description": "IP WhiteList microservice for cloud provider",
|
"description": "IP WhiteList microservice for cloud provider",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ function createAdminRouter({ generateCsrfToken } = {}) {
|
|||||||
router.get('/audit', async (req, res) => {
|
router.get('/audit', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const companyId = req.query.companyId ? parseInt(req.query.companyId) : null;
|
const companyId = req.query.companyId ? parseInt(req.query.companyId) : null;
|
||||||
const days = Math.min(Math.max(parseInt(req.query.days) || 365, 1), 365);
|
// days=null → все записи (без фильтра по дате)
|
||||||
|
const days = req.query.days ? Math.min(Math.max(parseInt(req.query.days), 1), 365) : null;
|
||||||
const page = Math.max(parseInt(req.query.page) || 1, 1);
|
const page = Math.max(parseInt(req.query.page) || 1, 1);
|
||||||
const perPage = 100;
|
const perPage = 100;
|
||||||
const result = await q.getAudit({ companyId, days, page, limit: perPage });
|
const result = await q.getAudit({ companyId, days, page, limit: perPage });
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '0.1.9',
|
version: '0.1.10',
|
||||||
|
|
||||||
// ── IAM ──────────────────────────────────────────────────────────────────
|
// ── IAM ──────────────────────────────────────────────────────────────────
|
||||||
iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user',
|
iamUrl: process.env.V2_IAM_URL || 'https://auth-api.ngcloud.ru/api/v1/auth/user',
|
||||||
|
|||||||
@@ -266,15 +266,15 @@ async function logAudit(userEmail, companyId, action, oldValue, newValue, entryI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Журнал операций с фильтром по дате и пагинацией.
|
* Журнал операций с пагинацией и опциональным фильтром по дате.
|
||||||
* @param {Object} opts
|
* @param {Object} opts
|
||||||
* @param {number|null} opts.companyId — фильтр по компании (null = все)
|
* @param {number|null} opts.companyId — фильтр по компании (null = все)
|
||||||
* @param {number} opts.days — глубина в днях (по умолчанию 365)
|
* @param {number|null} opts.days — глубина в днях (null = без ограничения)
|
||||||
* @param {number} opts.page — страница (с 1)
|
* @param {number} opts.page — страница (с 1)
|
||||||
* @param {number} opts.limit — записей на странице
|
* @param {number} opts.limit — записей на странице
|
||||||
* @returns {{ rows: Array, total: number }}
|
* @returns {{ rows: Array, total: number }}
|
||||||
*/
|
*/
|
||||||
async function getAudit({ companyId = null, days = 365, page = 1, limit = 100 } = {}) {
|
async function getAudit({ companyId = null, days = null, page = 1, limit = 100 } = {}) {
|
||||||
const offset = (page - 1) * limit;
|
const offset = (page - 1) * limit;
|
||||||
const params = [];
|
const params = [];
|
||||||
|
|
||||||
@@ -283,9 +283,11 @@ async function getAudit({ companyId = null, days = 365, page = 1, limit = 100 }
|
|||||||
where += ' WHERE a.company_id = $' + (params.length + 1);
|
where += ' WHERE a.company_id = $' + (params.length + 1);
|
||||||
params.push(companyId);
|
params.push(companyId);
|
||||||
}
|
}
|
||||||
|
if (days) {
|
||||||
const dayParam = '$' + (params.length + 1);
|
const dayParam = '$' + (params.length + 1);
|
||||||
where += (where ? ' AND' : ' WHERE') + ' a.created_at > NOW() - (' + dayParam + ' || \' days\')::INTERVAL';
|
where += (where ? ' AND' : ' WHERE') + ' a.created_at > NOW() - (' + dayParam + ' || \' days\')::INTERVAL';
|
||||||
params.push(String(days));
|
params.push(String(days));
|
||||||
|
}
|
||||||
|
|
||||||
const limitIdx = params.length + 1;
|
const limitIdx = params.length + 1;
|
||||||
const offsetIdx = params.length + 2;
|
const offsetIdx = params.length + 2;
|
||||||
|
|||||||
@@ -76,9 +76,12 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
Журнал операций
|
Журнал операций
|
||||||
<span style="font-weight:400;font-size:.82rem;color:var(--muted);">
|
<span style="font-weight:400;font-size:.82rem;color:var(--muted);">
|
||||||
(<%= total %> записей за <%= days %> дн.)
|
(<%= total %> записей<%= days ? ' за ' + days + ' дн.' : ' (всё время)' %>)
|
||||||
</span>
|
</span>
|
||||||
<span style="float:right;display:flex;gap:.3rem;">
|
<span style="float:right;display:flex;gap:.3rem;">
|
||||||
|
<a href="?<%= company ? 'companyId=' + company.id : '' %>"
|
||||||
|
class="btn btn-sm<%= !days ? ' btn-primary' : '' %>"
|
||||||
|
style="padding:.2rem .5rem;font-size:.75rem;">Всё</a>
|
||||||
<% [30, 90, 365].forEach(function(d) { %>
|
<% [30, 90, 365].forEach(function(d) { %>
|
||||||
<a href="?<%= company ? 'companyId=' + company.id + '&' : '' %>days=<%= d %>"
|
<a href="?<%= company ? 'companyId=' + company.id + '&' : '' %>days=<%= d %>"
|
||||||
class="btn btn-sm<%= days === d ? ' btn-primary' : '' %>"
|
class="btn btn-sm<%= days === d ? ' btn-primary' : '' %>"
|
||||||
|
|||||||
Reference in New Issue
Block a user