Files
Deep-Package-Inspection/backend/routes/dashboard/helpers.js
T

130 lines
4.6 KiB
JavaScript

const { CustomDeviceLabel, Flow } = require('../../models/Schemas');
// Valid tenant site UUIDs (from env). A global user requesting a site that is not
// in this list (e.g. a stale 'test-site' from the account's site_uuid column) must
// NOT silently filter everything out — treat it as "all sites" instead.
const KNOWN_SITES = (process.env.BACKONE_SITE_UUIDS || process.env.BACKONE_SITE_UUID || '')
.split(',')
.map(s => s.trim())
.filter(Boolean);
function isKnownSite(siteUuid) {
// Empty env => no known-site list configured, keep legacy behavior (filter anything).
return KNOWN_SITES.length === 0 || KNOWN_SITES.includes(siteUuid);
}
function getTimeFilter(req) {
// Explicit calendar date range (from the per-page date picker) takes priority
// over the global sidebar time range. Both dates are interpreted as WIB (UTC+7)
// to match the dashboard's display timezone (Rule 20).
const dateFrom = req.query.date_from;
const dateTo = req.query.date_to;
if (dateFrom || dateTo) {
const filter = {};
if (dateFrom) filter.$gte = new Date(`${dateFrom}T00:00:00.000+07:00`);
if (dateTo) filter.$lte = new Date(`${dateTo}T23:59:59.999+07:00`);
return filter;
}
// Fall back to sidebar global time range
const range = req.query.timeRange || '1d';
if (range === 'all') return null;
const now = new Date();
const ms = {
'5m': 5 * 60000,
'30m': 30 * 60000,
'1h': 1 * 3600000,
'1d': 24 * 3600000,
'7d': 7 * 24 * 3600000,
'30d': 30 * 24 * 3600000,
};
const delta = ms[range] ?? ms['1d'];
return { $gte: new Date(now.getTime() - delta) };
}
function getBaseFilter(req, timeFilter = null) {
const filter = {};
if (timeFilter) filter.timestamp = timeFilter;
const requestedSiteUuid = req.headers['x-backone-site-uuid'];
const isGlobalUser = req.user?.role === 'SUPER_ADMIN' ||
req.user?.role === 'EXECUTIVE' ||
((!req.user?.site_uuid || req.user?.site_uuid === 'default') && ['SOC_ANALYST', 'ENGINEER'].includes(req.user?.role));
if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) {
filter.site_uuid = { $in: [requestedSiteUuid, 'global'] };
} else if (isGlobalUser && KNOWN_SITES.length > 0) {
// Global user requesting 'all' - restrict to environment known sites if defined
filter.site_uuid = { $in: [...KNOWN_SITES, 'global'] };
} else if (!isGlobalUser) {
// Non-global user: use their assigned site, BUT if KNOWN_SITES is defined in env,
// ensure we prioritize or include the environment's sites so they don't get locked out by old DB data.
const userSite = req.user?.site_uuid;
if (KNOWN_SITES.length > 0) {
filter.site_uuid = { $in: [...KNOWN_SITES, userSite, 'global'].filter(Boolean) };
} else if (userSite) {
filter.site_uuid = { $in: [userSite, 'global'] };
}
}
// Restrict agent based on role and explicit query
if (req.user?.role && ['COMPANY_ADMIN', 'COMPANY_OPERATOR', 'COMPANY_VIEWER'].includes(req.user.role)) {
if (req.query?.agent_uuid && (req.user.agent_uuids || []).includes(req.query.agent_uuid)) {
filter.agent_uuid = req.query.agent_uuid;
} else {
filter.agent_uuid = { $in: req.user.agent_uuids || [] };
}
} else if (req.user?.role === 'AGENT_VIEWER' && req.user?.agent_uuid) {
// AGENT_VIEWER is strictly limited to their own agent
filter.agent_uuid = req.user.agent_uuid;
} else if (req.query?.agent_uuid) {
// SUPER_ADMIN and other global roles can query any agent
filter.agent_uuid = req.query.agent_uuid;
}
console.log('[DEBUG getBaseFilter]', { headers: req.headers, filter });
return filter;
}
async function getCustomLabelsMap() {
try {
const list = await CustomDeviceLabel.find().lean();
const map = {};
list.forEach(c => {
map[c.mac_address] = c.device_label;
});
return map;
} catch (err) {
console.error('[getCustomLabelsMap] failed:', err.message);
return {};
}
}
async function topFlowField(fieldName, req, limit = 20) {
const timeFilter = getTimeFilter(req);
const matchBase = getBaseFilter(req, timeFilter);
return Flow.aggregate([
{ $match: { ...matchBase, [fieldName]: { $ne: null, $ne: '' } } },
{ $group: {
_id: `$${fieldName}`,
download: { $sum: '$download' },
upload: { $sum: '$upload' },
count: { $sum: 1 },
}},
{ $project: { label: '$_id', download: 1, upload: 1, count: 1, _id: 0 } },
{ $sort: { download: -1 } },
{ $limit: limit },
]);
}
module.exports = {
getTimeFilter,
getBaseFilter,
getCustomLabelsMap,
topFlowField,
isKnownSite
};