package router import ( "io/fs" "net/http" "crowdsec-dashy/internal/config" "crowdsec-dashy/internal/crowdsec" "crowdsec-dashy/internal/handlers" "crowdsec-dashy/internal/middleware" ) // New constructs the full HTTP handler: renderer, deps, routes, and middleware chain. func New(cfg *config.Config, lapi *crowdsec.LAPIClient, webFS fs.FS) (http.Handler, error) { renderer, err := handlers.NewRenderer(webFS) if err != nil { return nil, err } deps := handlers.Deps{ Renderer: renderer, LAPI: lapi, CLI: crowdsec.NewCLIClient(cfg.CscliPath), CLIAvailable: cfg.CscliAvailable(), PollInterval: cfg.PollIntervalSec, } mux := http.NewServeMux() // Static files served from embedded FS sub-tree. staticFS, err := fs.Sub(webFS, "static") if err != nil { return nil, err } mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticFS)))) // Auth (exempt from session check — SessionAuth skips /login internally) auth := handlers.NewAuthHandler(renderer, cfg.UISessionSecret, cfg.UIUsername, cfg.VerifyUIPassword) mux.HandleFunc("GET /login", auth.Login) mux.HandleFunc("POST /login", auth.Login) mux.HandleFunc("POST /logout", auth.Logout) // Dashboard dash := handlers.NewDashboardHandler(deps) mux.HandleFunc("GET /{$}", dash.ServeHTTP) // Decisions dec := handlers.NewDecisionsHandler(deps) mux.HandleFunc("GET /decisions", dec.List) mux.HandleFunc("POST /decisions/add", dec.Add) mux.HandleFunc("POST /decisions/delete", dec.Delete) // Alerts alrt := handlers.NewAlertsHandler(deps) mux.HandleFunc("GET /alerts", alrt.List) mux.HandleFunc("POST /alerts/delete", alrt.Delete) // Bouncers bnc := handlers.NewBouncersHandler(deps) mux.HandleFunc("GET /bouncers", bnc.List) mux.HandleFunc("POST /bouncers/add", bnc.Add) mux.HandleFunc("POST /bouncers/delete", bnc.Delete) // Machines mch := handlers.NewMachinesHandler(deps) mux.HandleFunc("GET /machines", mch.List) mux.HandleFunc("POST /machines/delete", mch.Delete) mux.HandleFunc("POST /machines/validate", mch.Validate) // Hub hub := handlers.NewHubHandler(deps) mux.HandleFunc("GET /hub", hub.List) mux.HandleFunc("POST /hub/install", hub.Install) mux.HandleFunc("POST /hub/remove", hub.Remove) mux.HandleFunc("POST /hub/update", hub.Update) // Metrics met := handlers.NewMetricsHandler(deps) mux.HandleFunc("GET /metrics-ui", met.ServeHTTP) // Internal JSON API api := handlers.NewAPIHandler(deps) mux.HandleFunc("GET /api/v1/stats", api.Stats) mux.HandleFunc("GET /api/v1/health", api.Health) chain := middleware.Chain( middleware.SessionAuth(cfg.UISessionSecret), middleware.Logger(), middleware.SecureHeaders(), middleware.Recovery(), ) return chain(mux), nil }