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 };