From 4229c54d6261f10705a7e0a312a0b9beb92975ee Mon Sep 17 00:00:00 2001 From: marco370 <48531002-marco370@users.noreply.replit.com> Date: Mon, 16 Feb 2026 08:14:39 +0000 Subject: [PATCH] Improve system accuracy and router configuration for security monitoring Fixes type mismatches in API responses, updates router configuration to use correct REST API ports, and refactors statistics calculation for improved accuracy. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 2601dca2-8641-4d91-9722-c30ebbbf23af Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/5aJYCET --- client/src/pages/Dashboard.tsx | 8 +++--- client/src/pages/DashboardLive.tsx | 3 ++- client/src/pages/PublicLists.tsx | 2 +- client/src/pages/Routers.tsx | 12 ++++----- server/routes.ts | 43 +++++++++++++++++------------- server/storage.ts | 11 ++++++-- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/client/src/pages/Dashboard.tsx b/client/src/pages/Dashboard.tsx index 375b9fd..717e905 100644 --- a/client/src/pages/Dashboard.tsx +++ b/client/src/pages/Dashboard.tsx @@ -37,10 +37,12 @@ export default function Dashboard() { refetchInterval: 10000, // Refresh every 10s }); - const { data: recentDetections } = useQuery({ - queryKey: ["/api/detections?limit=100"], - refetchInterval: 5000, // Refresh every 5s + const { data: recentDetectionsData } = useQuery<{ detections: Detection[]; total: number }>({ + queryKey: ["/api/detections", { limit: 100 }], + queryFn: () => fetch("/api/detections?limit=100").then(r => r.json()), + refetchInterval: 5000, }); + const recentDetections = recentDetectionsData?.detections; const { data: routers } = useQuery({ queryKey: ["/api/routers"], diff --git a/client/src/pages/DashboardLive.tsx b/client/src/pages/DashboardLive.tsx index 270d064..d85a365 100644 --- a/client/src/pages/DashboardLive.tsx +++ b/client/src/pages/DashboardLive.tsx @@ -16,6 +16,7 @@ interface DashboardStats { attacksByCountry: Record; attacksByType: Record; recentDetections: Detection[]; + blockedCount: number; } export default function DashboardLive() { @@ -32,7 +33,7 @@ export default function DashboardLive() { const attackPercentage = totalTraffic > 0 ? ((totalAttacks / totalTraffic) * 100).toFixed(2) : "0"; const detections = stats?.recentDetections || []; - const blockedAttacks = detections.filter(d => d.blocked).length; + const blockedAttacks = stats?.blockedCount || 0; // Usa dati aggregati giĆ  calcolati dal backend const attacksByCountry = stats?.attacksByCountry || {}; diff --git a/client/src/pages/PublicLists.tsx b/client/src/pages/PublicLists.tsx index 5f2316e..1384d0d 100644 --- a/client/src/pages/PublicLists.tsx +++ b/client/src/pages/PublicLists.tsx @@ -35,7 +35,7 @@ export default function PublicLists() { const [isAddDialogOpen, setIsAddDialogOpen] = useState(false); const [editingList, setEditingList] = useState(null); - const { data: lists, isLoading } = useQuery({ + const { data: lists, isLoading } = useQuery({ queryKey: ["/api/public-lists"], }); diff --git a/client/src/pages/Routers.tsx b/client/src/pages/Routers.tsx index 0e0b493..b72b3c6 100644 --- a/client/src/pages/Routers.tsx +++ b/client/src/pages/Routers.tsx @@ -47,7 +47,7 @@ export default function Routers() { defaultValues: { name: "", ipAddress: "", - apiPort: 8729, + apiPort: 80, username: "", password: "", enabled: true, @@ -167,7 +167,7 @@ export default function Routers() { Aggiungi Router MikroTik - Configura un nuovo router MikroTik per il sistema IDS. Assicurati che l'API RouterOS (porta 8729/8728) sia abilitata. + Configura un nuovo router MikroTik per il sistema IDS. Usa la REST API (porta 80 HTTP o 443 HTTPS). @@ -216,14 +216,14 @@ export default function Routers() { field.onChange(parseInt(e.target.value))} data-testid="input-port" /> - Porta RouterOS API MikroTik (8729 per API-SSL, 8728 per API) + Porta REST API MikroTik (80 per HTTP, 443 per HTTPS) @@ -445,14 +445,14 @@ export default function Routers() { field.onChange(parseInt(e.target.value))} data-testid="input-edit-port" /> - Porta RouterOS API MikroTik (8729 per API-SSL, 8728 per API) + Porta REST API MikroTik (80 per HTTP, 443 per HTTPS) diff --git a/server/routes.ts b/server/routes.ts index 5839b43..e226486 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -1,9 +1,9 @@ import type { Express } from "express"; import { createServer, type Server } from "http"; import { storage } from "./storage"; -import { insertRouterSchema, insertDetectionSchema, insertWhitelistSchema, insertPublicListSchema, networkAnalytics, routers } from "@shared/schema"; +import { insertRouterSchema, insertDetectionSchema, insertWhitelistSchema, insertPublicListSchema, networkAnalytics, routers, detections, networkLogs } from "@shared/schema"; import { db } from "./db"; -import { desc, eq } from "drizzle-orm"; +import { desc, eq, gte, sql } from "drizzle-orm"; export async function registerRoutes(app: Express): Promise { // Routers @@ -310,7 +310,7 @@ export async function registerRoutes(app: Express): Promise { const text = await response.text(); // Parse IPs based on content type - let ips: Array<{ip: string, cidr?: string}> = []; + let ips: Array<{ip: string, cidr: string | null}> = []; if (contentType.includes('json') || list.url.endsWith('.json')) { // JSON format (Spamhaus DROP v4 JSON) @@ -322,7 +322,7 @@ export async function registerRoutes(app: Express): Promise { const [ip] = entry.cidr.split('/'); ips.push({ ip, cidr: entry.cidr }); } else if (entry.ip) { - ips.push({ ip: entry.ip, cidr: null as any }); + ips.push({ ip: entry.ip, cidr: null }); } } } @@ -342,7 +342,7 @@ export async function registerRoutes(app: Express): Promise { if (match) { const ip = match[1]; const cidr = match[2] ? `${match[1]}${match[2]}` : null; - ips.push({ ip, cidr: cidr as any }); + ips.push({ ip, cidr }); } } } @@ -481,30 +481,35 @@ export async function registerRoutes(app: Express): Promise { // Stats app.get("/api/stats", async (req, res) => { try { - const routers = await storage.getAllRouters(); - const detectionsResult = await storage.getAllDetections({ limit: 1000 }); - const recentLogs = await storage.getRecentLogs(1000); + const routersList = await storage.getAllRouters(); const whitelistResult = await storage.getAllWhitelist({ limit: 1 }); const latestTraining = await storage.getLatestTraining(); - const detectionsList = detectionsResult.detections; - const blockedCount = detectionsList.filter(d => d.blocked).length; - const criticalCount = detectionsList.filter(d => parseFloat(d.riskScore) >= 85).length; - const highCount = detectionsList.filter(d => parseFloat(d.riskScore) >= 70 && parseFloat(d.riskScore) < 85).length; + const detectionStats = await db.select({ + total: sql`count(*)::int`, + blocked: sql`count(*) filter (where blocked = true)::int`, + critical: sql`count(*) filter (where ${detections.riskScore}::numeric >= 85)::int`, + high: sql`count(*) filter (where ${detections.riskScore}::numeric >= 70 and ${detections.riskScore}::numeric < 85)::int`, + }).from(detections); + + const logStats = await db.select({ + count: sql`count(*)::int`, + }).from(networkLogs) + .where(gte(networkLogs.timestamp, new Date(Date.now() - 24 * 60 * 60 * 1000))); res.json({ routers: { - total: routers.length, - enabled: routers.filter(r => r.enabled).length + total: routersList.length, + enabled: routersList.filter(r => r.enabled).length }, detections: { - total: detectionsResult.total, - blocked: blockedCount, - critical: criticalCount, - high: highCount + total: detectionStats[0]?.total || 0, + blocked: detectionStats[0]?.blocked || 0, + critical: detectionStats[0]?.critical || 0, + high: detectionStats[0]?.high || 0 }, logs: { - recent: recentLogs.length + recent: logStats[0]?.count || 0 }, whitelist: { total: whitelistResult.total diff --git a/server/storage.ts b/server/storage.ts index 54520b8..53b6752 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -80,13 +80,14 @@ export interface IStorage { attacksByCountry: Record; attacksByType: Record; recentDetections: Detection[]; + blockedCount: number; }>; // Public Lists getAllPublicLists(): Promise; getPublicListById(id: string): Promise; createPublicList(list: InsertPublicList): Promise; - updatePublicList(id: string, list: Partial): Promise; + updatePublicList(id: string, list: Partial & { lastFetch?: Date | null; lastSuccess?: Date | null }): Promise; deletePublicList(id: string): Promise; // Public Blacklist IPs @@ -453,6 +454,11 @@ export class DatabaseStorage implements IStorage { .orderBy(desc(detections.detectedAt)) .limit(100); + const [blockedResult] = await db + .select({ count: sql`count(*)::int` }) + .from(detections) + .where(eq(detections.blocked, true)); + return { totalPackets, attackPackets, @@ -462,6 +468,7 @@ export class DatabaseStorage implements IStorage { attacksByCountry, attacksByType, recentDetections, + blockedCount: blockedResult?.count || 0, }; } @@ -480,7 +487,7 @@ export class DatabaseStorage implements IStorage { return list; } - async updatePublicList(id: string, updateData: Partial): Promise { + async updatePublicList(id: string, updateData: Partial & { lastFetch?: Date | null; lastSuccess?: Date | null }): Promise { const [list] = await db .update(publicLists) .set(updateData)