Integrates IP geolocation and Autonomous System (AS) information into detection records by modifying the frontend to display this data and updating the backend to perform asynchronous batch lookups for efficiency. This enhancement includes database schema updates and the creation of a new IP geolocation service. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: e81fd4a1-b7b0-48d2-ae38-f5905e278343 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/SXFWABi
156 lines
5.6 KiB
TypeScript
156 lines
5.6 KiB
TypeScript
import { sql, relations } from "drizzle-orm";
|
|
import { pgTable, text, varchar, integer, timestamp, decimal, boolean, index } from "drizzle-orm/pg-core";
|
|
import { createInsertSchema } from "drizzle-zod";
|
|
import { z } from "zod";
|
|
|
|
// Router MikroTik configuration
|
|
export const routers = pgTable("routers", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
name: text("name").notNull(),
|
|
ipAddress: text("ip_address").notNull().unique(),
|
|
apiPort: integer("api_port").notNull().default(8728),
|
|
username: text("username").notNull(),
|
|
password: text("password").notNull(),
|
|
enabled: boolean("enabled").notNull().default(true),
|
|
lastSync: timestamp("last_sync"),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
});
|
|
|
|
// Network logs from MikroTik (syslog)
|
|
export const networkLogs = pgTable("network_logs", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
routerName: text("router_name").notNull(), // Hostname dal syslog
|
|
timestamp: timestamp("timestamp").notNull(),
|
|
sourceIp: text("source_ip").notNull(),
|
|
sourcePort: integer("source_port"),
|
|
destinationIp: text("destination_ip"),
|
|
destinationPort: integer("destination_port"),
|
|
protocol: text("protocol"),
|
|
action: text("action"),
|
|
packetLength: integer("packet_length"),
|
|
rawMessage: text("raw_message"),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
}, (table) => ({
|
|
sourceIpIdx: index("source_ip_idx").on(table.sourceIp),
|
|
timestampIdx: index("timestamp_idx").on(table.timestamp),
|
|
routerNameIdx: index("router_name_idx").on(table.routerName),
|
|
}));
|
|
|
|
// Detected threats/anomalies
|
|
export const detections = pgTable("detections", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
sourceIp: text("source_ip").notNull(),
|
|
riskScore: decimal("risk_score", { precision: 5, scale: 2 }).notNull(),
|
|
confidence: decimal("confidence", { precision: 5, scale: 2 }).notNull(),
|
|
anomalyType: text("anomaly_type").notNull(),
|
|
reason: text("reason"),
|
|
logCount: integer("log_count").notNull(),
|
|
firstSeen: timestamp("first_seen").notNull(),
|
|
lastSeen: timestamp("last_seen").notNull(),
|
|
blocked: boolean("blocked").notNull().default(false),
|
|
blockedAt: timestamp("blocked_at"),
|
|
detectedAt: timestamp("detected_at").defaultNow().notNull(),
|
|
// Geolocation & AS info
|
|
country: text("country"),
|
|
countryCode: text("country_code"),
|
|
city: text("city"),
|
|
organization: text("organization"),
|
|
asNumber: text("as_number"),
|
|
asName: text("as_name"),
|
|
isp: text("isp"),
|
|
}, (table) => ({
|
|
sourceIpIdx: index("detection_source_ip_idx").on(table.sourceIp),
|
|
riskScoreIdx: index("risk_score_idx").on(table.riskScore),
|
|
detectedAtIdx: index("detected_at_idx").on(table.detectedAt),
|
|
countryIdx: index("country_idx").on(table.country),
|
|
}));
|
|
|
|
// Whitelist per IP fidati
|
|
export const whitelist = pgTable("whitelist", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
ipAddress: text("ip_address").notNull().unique(),
|
|
comment: text("comment"),
|
|
reason: text("reason"),
|
|
createdBy: text("created_by"),
|
|
active: boolean("active").notNull().default(true),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
});
|
|
|
|
// ML Training history
|
|
export const trainingHistory = pgTable("training_history", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
modelVersion: text("model_version").notNull(),
|
|
recordsProcessed: integer("records_processed").notNull(),
|
|
featuresCount: integer("features_count").notNull(),
|
|
accuracy: decimal("accuracy", { precision: 5, scale: 2 }),
|
|
trainingDuration: integer("training_duration"),
|
|
status: text("status").notNull(),
|
|
notes: text("notes"),
|
|
trainedAt: timestamp("trained_at").defaultNow().notNull(),
|
|
});
|
|
|
|
// Schema version tracking for database migrations
|
|
export const schemaVersion = pgTable("schema_version", {
|
|
id: integer("id").primaryKey().default(1),
|
|
version: integer("version").notNull().default(0),
|
|
appliedAt: timestamp("applied_at").defaultNow().notNull(),
|
|
description: text("description"),
|
|
});
|
|
|
|
// Relations
|
|
export const routersRelations = relations(routers, ({ many }) => ({
|
|
logs: many(networkLogs),
|
|
}));
|
|
|
|
// Rimossa relazione router (non più FK)
|
|
|
|
// Insert schemas
|
|
export const insertRouterSchema = createInsertSchema(routers).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
lastSync: true,
|
|
});
|
|
|
|
export const insertNetworkLogSchema = createInsertSchema(networkLogs).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertDetectionSchema = createInsertSchema(detections).omit({
|
|
id: true,
|
|
detectedAt: true,
|
|
});
|
|
|
|
export const insertWhitelistSchema = createInsertSchema(whitelist).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertTrainingHistorySchema = createInsertSchema(trainingHistory).omit({
|
|
id: true,
|
|
trainedAt: true,
|
|
});
|
|
|
|
export const insertSchemaVersionSchema = createInsertSchema(schemaVersion).omit({
|
|
appliedAt: true,
|
|
});
|
|
|
|
// Types
|
|
export type Router = typeof routers.$inferSelect;
|
|
export type InsertRouter = z.infer<typeof insertRouterSchema>;
|
|
|
|
export type NetworkLog = typeof networkLogs.$inferSelect;
|
|
export type InsertNetworkLog = z.infer<typeof insertNetworkLogSchema>;
|
|
|
|
export type Detection = typeof detections.$inferSelect;
|
|
export type InsertDetection = z.infer<typeof insertDetectionSchema>;
|
|
|
|
export type Whitelist = typeof whitelist.$inferSelect;
|
|
export type InsertWhitelist = z.infer<typeof insertWhitelistSchema>;
|
|
|
|
export type TrainingHistory = typeof trainingHistory.$inferSelect;
|
|
export type InsertTrainingHistory = z.infer<typeof insertTrainingHistorySchema>;
|
|
|
|
export type SchemaVersion = typeof schemaVersion.$inferSelect;
|
|
export type InsertSchemaVersion = z.infer<typeof insertSchemaVersionSchema>;
|