Compare commits

..

No commits in common. "0269dc929e392206384d4aa36d297f77c4c2131e" and "a3ec75b86bb84614ed5d00c90f5d4f27271d9490" have entirely different histories.

8 changed files with 42 additions and 57 deletions

View File

@ -37,12 +37,10 @@ export default function Dashboard() {
refetchInterval: 10000, // Refresh every 10s
});
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 { data: recentDetections } = useQuery<Detection[]>({
queryKey: ["/api/detections?limit=100"],
refetchInterval: 5000, // Refresh every 5s
});
const recentDetections = recentDetectionsData?.detections;
const { data: routers } = useQuery<Router[]>({
queryKey: ["/api/routers"],

View File

@ -16,7 +16,6 @@ interface DashboardStats {
attacksByCountry: Record<string, number>;
attacksByType: Record<string, number>;
recentDetections: Detection[];
blockedCount: number;
}
export default function DashboardLive() {
@ -33,7 +32,7 @@ export default function DashboardLive() {
const attackPercentage = totalTraffic > 0 ? ((totalAttacks / totalTraffic) * 100).toFixed(2) : "0";
const detections = stats?.recentDetections || [];
const blockedAttacks = stats?.blockedCount || 0;
const blockedAttacks = detections.filter(d => d.blocked).length;
// Usa dati aggregati già calcolati dal backend
const attacksByCountry = stats?.attacksByCountry || {};

View File

@ -35,7 +35,7 @@ export default function PublicLists() {
const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
const [editingList, setEditingList] = useState<any>(null);
const { data: lists, isLoading } = useQuery<any[]>({
const { data: lists, isLoading } = useQuery({
queryKey: ["/api/public-lists"],
});

View File

@ -47,7 +47,7 @@ export default function Routers() {
defaultValues: {
name: "",
ipAddress: "",
apiPort: 80,
apiPort: 8729,
username: "",
password: "",
enabled: true,
@ -167,7 +167,7 @@ export default function Routers() {
<DialogHeader>
<DialogTitle>Aggiungi Router MikroTik</DialogTitle>
<DialogDescription>
Configura un nuovo router MikroTik per il sistema IDS. Usa la REST API (porta 80 HTTP o 443 HTTPS).
Configura un nuovo router MikroTik per il sistema IDS. Assicurati che l'API RouterOS (porta 8729/8728) sia abilitata.
</DialogDescription>
</DialogHeader>
@ -216,14 +216,14 @@ export default function Routers() {
<FormControl>
<Input
type="number"
placeholder="80"
placeholder="8729"
{...field}
onChange={(e) => field.onChange(parseInt(e.target.value))}
data-testid="input-port"
/>
</FormControl>
<FormDescription>
Porta REST API MikroTik (80 per HTTP, 443 per HTTPS)
Porta RouterOS API MikroTik (8729 per API-SSL, 8728 per API)
</FormDescription>
<FormMessage />
</FormItem>
@ -445,14 +445,14 @@ export default function Routers() {
<FormControl>
<Input
type="number"
placeholder="80"
placeholder="8729"
{...field}
onChange={(e) => field.onChange(parseInt(e.target.value))}
data-testid="input-edit-port"
/>
</FormControl>
<FormDescription>
Porta REST API MikroTik (80 per HTTP, 443 per HTTPS)
Porta RouterOS API MikroTik (8729 per API-SSL, 8728 per API)
</FormDescription>
<FormMessage />
</FormItem>

View File

@ -2,7 +2,7 @@
-- PostgreSQL database dump
--
\restrict dD9aoEfsbejhZrnq39dZalwHgFaXuIKh3obps9QwB0cunaM36PvpYWXEbzkuxIC
\restrict m8BX2OAI4IqpPQYg9LDdkx9gw71E8mW7NhAoc6tFhxIWe7hPFxv4gky0SVxio2N
-- Dumped from database version 16.11 (df20cf9)
-- Dumped by pg_dump version 16.10
@ -387,5 +387,5 @@ ALTER TABLE ONLY public.public_blacklist_ips
-- PostgreSQL database dump complete
--
\unrestrict dD9aoEfsbejhZrnq39dZalwHgFaXuIKh3obps9QwB0cunaM36PvpYWXEbzkuxIC
\unrestrict m8BX2OAI4IqpPQYg9LDdkx9gw71E8mW7NhAoc6tFhxIWe7hPFxv4gky0SVxio2N

View File

@ -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, detections, networkLogs } from "@shared/schema";
import { insertRouterSchema, insertDetectionSchema, insertWhitelistSchema, insertPublicListSchema, networkAnalytics, routers } from "@shared/schema";
import { db } from "./db";
import { desc, eq, gte, sql } from "drizzle-orm";
import { desc, eq } from "drizzle-orm";
export async function registerRoutes(app: Express): Promise<Server> {
// Routers
@ -310,7 +310,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
const text = await response.text();
// Parse IPs based on content type
let ips: Array<{ip: string, cidr: string | null}> = [];
let ips: Array<{ip: string, cidr?: string}> = [];
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<Server> {
const [ip] = entry.cidr.split('/');
ips.push({ ip, cidr: entry.cidr });
} else if (entry.ip) {
ips.push({ ip: entry.ip, cidr: null });
ips.push({ ip: entry.ip, cidr: null as any });
}
}
}
@ -342,7 +342,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
if (match) {
const ip = match[1];
const cidr = match[2] ? `${match[1]}${match[2]}` : null;
ips.push({ ip, cidr });
ips.push({ ip, cidr: cidr as any });
}
}
}
@ -481,35 +481,30 @@ export async function registerRoutes(app: Express): Promise<Server> {
// Stats
app.get("/api/stats", async (req, res) => {
try {
const routersList = await storage.getAllRouters();
const routers = await storage.getAllRouters();
const detectionsResult = await storage.getAllDetections({ limit: 1000 });
const recentLogs = await storage.getRecentLogs(1000);
const whitelistResult = await storage.getAllWhitelist({ limit: 1 });
const latestTraining = await storage.getLatestTraining();
const detectionStats = await db.select({
total: sql<number>`count(*)::int`,
blocked: sql<number>`count(*) filter (where blocked = true)::int`,
critical: sql<number>`count(*) filter (where ${detections.riskScore}::numeric >= 85)::int`,
high: sql<number>`count(*) filter (where ${detections.riskScore}::numeric >= 70 and ${detections.riskScore}::numeric < 85)::int`,
}).from(detections);
const logStats = await db.select({
count: sql<number>`count(*)::int`,
}).from(networkLogs)
.where(gte(networkLogs.timestamp, new Date(Date.now() - 24 * 60 * 60 * 1000)));
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;
res.json({
routers: {
total: routersList.length,
enabled: routersList.filter(r => r.enabled).length
total: routers.length,
enabled: routers.filter(r => r.enabled).length
},
detections: {
total: detectionStats[0]?.total || 0,
blocked: detectionStats[0]?.blocked || 0,
critical: detectionStats[0]?.critical || 0,
high: detectionStats[0]?.high || 0
total: detectionsResult.total,
blocked: blockedCount,
critical: criticalCount,
high: highCount
},
logs: {
recent: logStats[0]?.count || 0
recent: recentLogs.length
},
whitelist: {
total: whitelistResult.total

View File

@ -80,14 +80,13 @@ export interface IStorage {
attacksByCountry: Record<string, number>;
attacksByType: Record<string, number>;
recentDetections: Detection[];
blockedCount: number;
}>;
// Public Lists
getAllPublicLists(): Promise<PublicList[]>;
getPublicListById(id: string): Promise<PublicList | undefined>;
createPublicList(list: InsertPublicList): Promise<PublicList>;
updatePublicList(id: string, list: Partial<InsertPublicList> & { lastFetch?: Date | null; lastSuccess?: Date | null }): Promise<PublicList | undefined>;
updatePublicList(id: string, list: Partial<InsertPublicList>): Promise<PublicList | undefined>;
deletePublicList(id: string): Promise<boolean>;
// Public Blacklist IPs
@ -454,11 +453,6 @@ export class DatabaseStorage implements IStorage {
.orderBy(desc(detections.detectedAt))
.limit(100);
const [blockedResult] = await db
.select({ count: sql<number>`count(*)::int` })
.from(detections)
.where(eq(detections.blocked, true));
return {
totalPackets,
attackPackets,
@ -468,7 +462,6 @@ export class DatabaseStorage implements IStorage {
attacksByCountry,
attacksByType,
recentDetections,
blockedCount: blockedResult?.count || 0,
};
}
@ -487,7 +480,7 @@ export class DatabaseStorage implements IStorage {
return list;
}
async updatePublicList(id: string, updateData: Partial<InsertPublicList> & { lastFetch?: Date | null; lastSuccess?: Date | null }): Promise<PublicList | undefined> {
async updatePublicList(id: string, updateData: Partial<InsertPublicList>): Promise<PublicList | undefined> {
const [list] = await db
.update(publicLists)
.set(updateData)

View File

@ -1,13 +1,7 @@
{
"version": "1.0.110",
"lastUpdate": "2026-02-16T10:36:31.538Z",
"version": "1.0.109",
"lastUpdate": "2026-02-16T07:50:06.148Z",
"changelog": [
{
"version": "1.0.110",
"date": "2026-02-16",
"type": "patch",
"description": "Deployment automatico v1.0.110"
},
{
"version": "1.0.109",
"date": "2026-02-16",
@ -301,6 +295,12 @@
"date": "2025-11-24",
"type": "patch",
"description": "Deployment automatico v1.0.61"
},
{
"version": "1.0.60",
"date": "2025-11-24",
"type": "patch",
"description": "Deployment automatico v1.0.60"
}
]
}