package api import ( "fmt" "net/http" "dip-ids/internal/analyzer" "dip-ids/internal/api/handlers" "dip-ids/internal/config" "dip-ids/internal/storage" "github.com/gin-gonic/gin" ) type Server struct { cfg config.ServerConfig router *gin.Engine } func New( cfg config.ServerConfig, db *storage.DB, engine *analyzer.Engine, captureCfg config.CaptureConfig, ) *Server { gin.SetMode(gin.ReleaseMode) r := gin.New() r.Use(gin.Recovery()) r.Use(corsMiddleware()) r.Use(gin.LoggerWithConfig(gin.LoggerConfig{ SkipPaths: []string{"/api/capture/status", "/api/health"}, })) alertsH := handlers.NewAlertsHandler(db) statsH := handlers.NewStatsHandler(db) captureH := handlers.NewCaptureHandler(db, engine, captureCfg.DefaultInterface) reportsH := handlers.NewReportsHandler(db) api := r.Group("/api") api.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"ok": true}) }) api.GET("/alerts", alertsH.GetAlerts) api.DELETE("/alerts", alertsH.ClearAlerts) api.DELETE("/alerts/:id", alertsH.DeleteAlert) api.GET("/stats/summary", statsH.GetSummary) api.GET("/stats/timeline", statsH.GetTimeline) api.GET("/stats/top-ips", statsH.GetTopIPs) api.GET("/capture/interfaces", captureH.GetInterfaces) api.GET("/capture/status", captureH.Status) api.GET("/capture/sessions", captureH.GetSessions) api.POST("/capture/start", captureH.StartLive) api.POST("/capture/stop", captureH.Stop) api.POST("/capture/upload", captureH.UploadPCAP) api.GET("/reports/generate", reportsH.Generate) return &Server{cfg: cfg, router: r} } func (s *Server) Run() error { addr := fmt.Sprintf("%s:%d", s.cfg.Host, s.cfg.Port) return s.router.Run(addr) } // corsMiddleware разрешает запросы от Nuxt dev-сервера (localhost:3000) func corsMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS") c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } }