Adds new frontend pages for ML training and IP whitelisting, along with backend API endpoints to trigger ML actions and manage the whitelist. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: d6b17610-31b4-4ed0-a52a-66659e36d756 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/Aqah4U9
230 lines
6.9 KiB
TypeScript
230 lines
6.9 KiB
TypeScript
import type { Express } from "express";
|
|
import { createServer, type Server } from "http";
|
|
import { storage } from "./storage";
|
|
import { insertRouterSchema, insertDetectionSchema, insertWhitelistSchema } from "@shared/schema";
|
|
|
|
export async function registerRoutes(app: Express): Promise<Server> {
|
|
// Routers
|
|
app.get("/api/routers", async (req, res) => {
|
|
try {
|
|
const routers = await storage.getAllRouters();
|
|
res.json(routers);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch routers" });
|
|
}
|
|
});
|
|
|
|
app.post("/api/routers", async (req, res) => {
|
|
try {
|
|
const validatedData = insertRouterSchema.parse(req.body);
|
|
const router = await storage.createRouter(validatedData);
|
|
res.json(router);
|
|
} catch (error) {
|
|
res.status(400).json({ error: "Invalid router data" });
|
|
}
|
|
});
|
|
|
|
app.delete("/api/routers/:id", async (req, res) => {
|
|
try {
|
|
const success = await storage.deleteRouter(req.params.id);
|
|
if (!success) {
|
|
return res.status(404).json({ error: "Router not found" });
|
|
}
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to delete router" });
|
|
}
|
|
});
|
|
|
|
// Network Logs
|
|
app.get("/api/logs", async (req, res) => {
|
|
try {
|
|
const limit = parseInt(req.query.limit as string) || 100;
|
|
const logs = await storage.getRecentLogs(limit);
|
|
res.json(logs);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch logs" });
|
|
}
|
|
});
|
|
|
|
app.get("/api/logs/ip/:ip", async (req, res) => {
|
|
try {
|
|
const limit = parseInt(req.query.limit as string) || 50;
|
|
const logs = await storage.getLogsByIp(req.params.ip, limit);
|
|
res.json(logs);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch logs for IP" });
|
|
}
|
|
});
|
|
|
|
// Detections
|
|
app.get("/api/detections", async (req, res) => {
|
|
try {
|
|
const limit = parseInt(req.query.limit as string) || 100;
|
|
const detections = await storage.getAllDetections(limit);
|
|
res.json(detections);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch detections" });
|
|
}
|
|
});
|
|
|
|
app.get("/api/detections/unblocked", async (req, res) => {
|
|
try {
|
|
const detections = await storage.getUnblockedDetections();
|
|
res.json(detections);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch unblocked detections" });
|
|
}
|
|
});
|
|
|
|
// Whitelist
|
|
app.get("/api/whitelist", async (req, res) => {
|
|
try {
|
|
const whitelist = await storage.getAllWhitelist();
|
|
res.json(whitelist);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch whitelist" });
|
|
}
|
|
});
|
|
|
|
app.post("/api/whitelist", async (req, res) => {
|
|
try {
|
|
const validatedData = insertWhitelistSchema.parse(req.body);
|
|
const item = await storage.createWhitelist(validatedData);
|
|
res.json(item);
|
|
} catch (error) {
|
|
res.status(400).json({ error: "Invalid whitelist data" });
|
|
}
|
|
});
|
|
|
|
app.delete("/api/whitelist/:id", async (req, res) => {
|
|
try {
|
|
const success = await storage.deleteWhitelist(req.params.id);
|
|
if (!success) {
|
|
return res.status(404).json({ error: "Whitelist entry not found" });
|
|
}
|
|
res.json({ success: true });
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to delete whitelist entry" });
|
|
}
|
|
});
|
|
|
|
// Training History
|
|
app.get("/api/training-history", async (req, res) => {
|
|
try {
|
|
const limit = parseInt(req.query.limit as string) || 10;
|
|
const history = await storage.getTrainingHistory(limit);
|
|
res.json(history);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch training history" });
|
|
}
|
|
});
|
|
|
|
app.get("/api/training-history/latest", async (req, res) => {
|
|
try {
|
|
const latest = await storage.getLatestTraining();
|
|
res.json(latest || null);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch latest training" });
|
|
}
|
|
});
|
|
|
|
// Stats
|
|
app.get("/api/stats", async (req, res) => {
|
|
try {
|
|
const routers = await storage.getAllRouters();
|
|
const detections = await storage.getAllDetections(1000);
|
|
const recentLogs = await storage.getRecentLogs(1000);
|
|
const whitelist = await storage.getAllWhitelist();
|
|
const latestTraining = await storage.getLatestTraining();
|
|
|
|
const blockedCount = detections.filter(d => d.blocked).length;
|
|
const criticalCount = detections.filter(d => parseFloat(d.riskScore) >= 85).length;
|
|
const highCount = detections.filter(d => parseFloat(d.riskScore) >= 70 && parseFloat(d.riskScore) < 85).length;
|
|
|
|
res.json({
|
|
routers: {
|
|
total: routers.length,
|
|
enabled: routers.filter(r => r.enabled).length
|
|
},
|
|
detections: {
|
|
total: detections.length,
|
|
blocked: blockedCount,
|
|
critical: criticalCount,
|
|
high: highCount
|
|
},
|
|
logs: {
|
|
recent: recentLogs.length
|
|
},
|
|
whitelist: {
|
|
total: whitelist.length
|
|
},
|
|
latestTraining: latestTraining
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch stats" });
|
|
}
|
|
});
|
|
|
|
// ML Actions - Trigger training/detection on Python backend
|
|
app.post("/api/ml/train", async (req, res) => {
|
|
try {
|
|
const { max_records = 100000, hours_back = 24 } = req.body;
|
|
|
|
const response = await fetch("http://localhost:8000/train", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ max_records, hours_back }),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Python backend training failed");
|
|
}
|
|
|
|
const data = await response.json();
|
|
res.json(data);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to trigger training" });
|
|
}
|
|
});
|
|
|
|
app.post("/api/ml/detect", async (req, res) => {
|
|
try {
|
|
const { max_records = 50000, hours_back = 1, risk_threshold = 75, auto_block = false } = req.body;
|
|
|
|
const response = await fetch("http://localhost:8000/detect", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ max_records, hours_back, risk_threshold, auto_block }),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Python backend detection failed");
|
|
}
|
|
|
|
const data = await response.json();
|
|
res.json(data);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to trigger detection" });
|
|
}
|
|
});
|
|
|
|
app.get("/api/ml/stats", async (req, res) => {
|
|
try {
|
|
const response = await fetch("http://localhost:8000/stats");
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Python backend stats failed");
|
|
}
|
|
|
|
const data = await response.json();
|
|
res.json(data);
|
|
} catch (error) {
|
|
res.status(500).json({ error: "Failed to fetch ML stats" });
|
|
}
|
|
});
|
|
|
|
const httpServer = createServer(app);
|
|
return httpServer;
|
|
}
|