From 856acdb6da21b92d796fd2ec9f61cb51851c69c3 Mon Sep 17 00:00:00 2001 From: ypratama Date: Wed, 2 Sep 2026 09:23:38 +0700 Subject: [PATCH] Fix: Unknown site_uuid no longer filters all data out, so overview dashboard always shows charts --- backend/routes/dashboard/agents.js | 10 +++++----- backend/routes/dashboard/helpers.js | 18 ++++++++++++++++-- src/components/layout/Sidebar.tsx | 8 ++++---- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/backend/routes/dashboard/agents.js b/backend/routes/dashboard/agents.js index 0cb60e0..af842a3 100644 --- a/backend/routes/dashboard/agents.js +++ b/backend/routes/dashboard/agents.js @@ -7,7 +7,7 @@ const express = require('express'); const router = express.Router(); const mongoose = require('mongoose'); const { Summary } = require('../../models/Schemas'); -const { getTimeFilter } = require('./helpers'); +const { getTimeFilter, isKnownSite } = require('./helpers'); // GET /api/dashboard/agents/uptime router.get('/agents/uptime', async (req, res) => { @@ -35,7 +35,7 @@ router.get('/agents/uptime', async (req, res) => { 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') { + if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) { query.site_uuid = { $in: [requestedSiteUuid, 'global'] }; } else if (!isGlobalUser && req.user?.site_uuid) { query.site_uuid = { $in: [req.user.site_uuid, 'global'] }; @@ -80,7 +80,7 @@ router.get('/agents', async (req, res) => { const isGlobalUser = effectiveRole === 'SUPER_ADMIN' || effectiveRole === 'EXECUTIVE'; const requestedSiteUuid = req.headers['x-backone-site-uuid']; - if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all') { + if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) { query.site_uuid = { $in: [requestedSiteUuid, 'global'] }; } else if (effectiveRole === 'TENANT_ADMIN') { query.site_uuid = { $in: [req.user.site_uuid, 'global'] }; @@ -117,7 +117,7 @@ router.get('/agents/storage', async (req, res) => { ((!req.user?.site_uuid || req.user?.site_uuid === 'default') && ['SOC_ANALYST', 'ENGINEER'].includes(req.user?.role)); let siteUuid = null; - if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all') { + if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) { siteUuid = requestedSiteUuid; } else if (!isGlobalUser && req.user?.site_uuid) { siteUuid = req.user.site_uuid; @@ -181,7 +181,7 @@ router.get('/agents/list', async (req, res) => { const effectiveRole = user?._originalRole || user?.role; const isGlobalUser = effectiveRole === 'SUPER_ADMIN' || effectiveRole === 'EXECUTIVE'; - if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all') { + if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) { filter.site_uuid = { $in: [requestedSiteUuid, 'global'] }; } else if (user?.site_uuid) { filter.site_uuid = { $in: [user.site_uuid, 'global'] }; diff --git a/backend/routes/dashboard/helpers.js b/backend/routes/dashboard/helpers.js index 156ce22..e3369f5 100644 --- a/backend/routes/dashboard/helpers.js +++ b/backend/routes/dashboard/helpers.js @@ -1,5 +1,18 @@ 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 || '') + .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) @@ -40,7 +53,7 @@ function getBaseFilter(req, timeFilter = null) { 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') { + if (isGlobalUser && requestedSiteUuid && requestedSiteUuid !== 'all' && isKnownSite(requestedSiteUuid)) { filter.site_uuid = { $in: [requestedSiteUuid, 'global'] }; } else if (!isGlobalUser && req.user?.site_uuid) { filter.site_uuid = { $in: [req.user.site_uuid, 'global'] }; @@ -99,5 +112,6 @@ module.exports = { getTimeFilter, getBaseFilter, getCustomLabelsMap, - topFlowField + topFlowField, + isKnownSite }; diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 7fb9e17..e99b31c 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -45,8 +45,9 @@ export function Sidebar({ isMobile = false, onClose }: SidebarProps) { // Role-aware site UUID logic: // - Global roles (SUPER_ADMIN, EXECUTIVE, SOC_ANALYST, ENGINEER): // Prioritaskan pilihan yang TERSIMPAN di localStorage. - // Hanya set dari DB jika belum ada pilihan tersimpan. - // Ini agar site switcher tidak reset ke SIAB setiap page reload. + // Jangan pakai site_uuid dari DB — untuk role global nilainya bisa + // placeholder (mis. 'test-site') yang bukan site asli, sehingga + // dashboard ikut terfilter kosong. Default yang aman adalah 'all'. // - Restricted roles (TENANT_ADMIN, AGENT_VIEWER, COMPANY_*): // Selalu pakai site_uuid dari DB (mereka tidak bisa ganti site). const globalRoles = ['SUPER_ADMIN', 'EXECUTIVE', 'SOC_ANALYST', 'ENGINEER']; @@ -54,8 +55,7 @@ export function Sidebar({ isMobile = false, onClose }: SidebarProps) { const storedSiteUuid = localStorage.getItem('backone_site_uuid'); if (isGlobalRole) { - // Pakai localStorage jika sudah ada, fallback ke DB, fallback ke SIAB default - const siteToUse = storedSiteUuid || data.user.site_uuid || 'all'; + const siteToUse = storedSiteUuid || 'all'; localStorage.setItem('backone_site_uuid', siteToUse); setSelectedSite(siteToUse); } else if (data.user.site_uuid) {