diff --git a/server/db-schema-check.js b/server/db-schema-check.js index c30a2ea..5218975 100644 --- a/server/db-schema-check.js +++ b/server/db-schema-check.js @@ -69,7 +69,6 @@ const SCHEMA = { latency_target VARCHAR(255), icp_filing VARCHAR(255), ps_filing VARCHAR(255), - network_data_sources TEXT, show_server_ip TINYINT(1) DEFAULT 0, ip_metric_name VARCHAR(100) DEFAULT NULL, ip_label_name VARCHAR(100) DEFAULT 'address', @@ -101,8 +100,7 @@ const SCHEMA = { { name: 'latency_target', sql: "ALTER TABLE site_settings ADD COLUMN latency_target VARCHAR(255) AFTER latency_dest" }, { name: 'icp_filing', sql: "ALTER TABLE site_settings ADD COLUMN icp_filing VARCHAR(255) AFTER latency_target" }, { name: 'ps_filing', sql: "ALTER TABLE site_settings ADD COLUMN ps_filing VARCHAR(255) AFTER icp_filing" }, - { name: 'network_data_sources', sql: "ALTER TABLE site_settings ADD COLUMN network_data_sources TEXT AFTER ps_filing" }, - { name: 'show_server_ip', sql: "ALTER TABLE site_settings ADD COLUMN show_server_ip TINYINT(1) DEFAULT 0 AFTER network_data_sources" }, + { name: 'show_server_ip', sql: "ALTER TABLE site_settings ADD COLUMN show_server_ip TINYINT(1) DEFAULT 0 AFTER ps_filing" }, { name: 'ip_metric_name', sql: "ALTER TABLE site_settings ADD COLUMN ip_metric_name VARCHAR(100) DEFAULT NULL AFTER show_server_ip" }, { name: 'ip_label_name', sql: "ALTER TABLE site_settings ADD COLUMN ip_label_name VARCHAR(100) DEFAULT 'address' AFTER ip_metric_name" }, { name: 'custom_metrics', sql: "ALTER TABLE site_settings ADD COLUMN custom_metrics JSON DEFAULT NULL AFTER ip_label_name" } diff --git a/server/index.js b/server/index.js index acef9c3..5624b65 100644 --- a/server/index.js +++ b/server/index.js @@ -164,6 +164,16 @@ async function requireServerDetailsAccess(req, res, next) { const settings = await getSiteSettingsRow(); req.siteSettings = settings; // Store for later use (e.g. IP stripping) + // 1. Mandatory source validation for detail access + const sourceName = req.query.source; + if (sourceName) { + const [sources] = await db.query('SELECT is_detail_source FROM prometheus_sources WHERE name = ?', [sourceName]); + if (sources.length === 0 || !sources[0].is_detail_source) { + return res.status(403).json({ error: '该数据源已禁用详情查看权限' }); + } + } + + // 2. Global login requirement check const requiresLogin = settings.require_login_for_server_details !== undefined ? !!settings.require_login_for_server_details : true; @@ -175,7 +185,7 @@ async function requireServerDetailsAccess(req, res, next) { return requireAuth(req, res, next); } catch (err) { console.error('Server details access check failed:', err); - return res.status(500).json({ error: 'Failed to verify detail access' }); + return res.status(500).json({ error: '权限验证失败' }); } } @@ -932,7 +942,7 @@ app.post('/api/settings', requireAuth, async (req, res) => { const { page_name, show_page_name, title, logo_url, logo_url_dark, favicon_url, default_theme, show_95_bandwidth, p95_type, require_login_for_server_details, - icp_filing, ps_filing, network_data_sources, show_server_ip, ip_metric_name, ip_label_name, custom_metrics + icp_filing, ps_filing, show_server_ip, ip_metric_name, ip_label_name, custom_metrics } = req.body; // 3. Prepare parameters, prioritizing body but falling back to current @@ -966,9 +976,9 @@ app.post('/api/settings', requireAuth, async (req, res) => { id, page_name, show_page_name, title, logo_url, logo_url_dark, favicon_url, default_theme, show_95_bandwidth, p95_type, require_login_for_server_details, blackbox_source_id, latency_source, latency_dest, latency_target, - icp_filing, ps_filing, network_data_sources, show_server_ip, ip_metric_name, ip_label_name, + icp_filing, ps_filing, show_server_ip, ip_metric_name, ip_label_name, custom_metrics - ) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE page_name = VALUES(page_name), show_page_name = VALUES(show_page_name), @@ -986,7 +996,6 @@ app.post('/api/settings', requireAuth, async (req, res) => { latency_target = VALUES(latency_target), icp_filing = VALUES(icp_filing), ps_filing = VALUES(ps_filing), - network_data_sources = VALUES(network_data_sources), show_server_ip = VALUES(show_server_ip), ip_metric_name = VALUES(ip_metric_name), ip_label_name = VALUES(ip_label_name),