package server import ( "net/http" sentryhttp "github.com/getsentry/sentry-go/http" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" "sneak.berlin/go/pixa/internal/static" ) // SetupRoutes configures all HTTP routes. func (s *Server) SetupRoutes() { s.router = chi.NewRouter() s.router.Use(middleware.Recoverer) s.router.Use(middleware.RequestID) s.router.Use(s.mw.SecurityHeaders()) s.router.Use(s.mw.Logging()) // Add metrics middleware only if credentials are configured if s.config.MetricsUsername != "" { s.router.Use(s.mw.Metrics()) } s.router.Use(s.mw.CORS()) s.router.Use(middleware.Timeout(HTTPWriteTimeout)) if s.sentryEnabled { sentryHandler := sentryhttp.New(sentryhttp.Options{ Repanic: true, }) s.router.Use(sentryHandler.Handle) } // Health check endpoint s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck()) // Robots.txt s.router.Get("/robots.txt", s.h.HandleRobotsTxt()) // Static files (Tailwind CSS, etc.) s.router.Handle("/static/*", http.StripPrefix("/static/", static.Handler())) // Login/generator UI s.router.Get("/", s.h.HandleRoot()) s.router.Post("/", s.h.HandleRoot()) s.router.Get("/logout", s.h.HandleLogout()) s.router.Post("/generate", s.h.HandleGenerateURL()) // Main image proxy route // /v1/image///x. s.router.Get("/v1/image/*", s.h.HandleImage()) s.router.Head("/v1/image/*", s.h.HandleImage()) // Encrypted image URL route // The trailing filename (e.g., /img.jpg) is ignored but helps browsers with content type s.router.Get("/v1/e/{token}/*", s.h.HandleImageEnc()) // Metrics endpoint with auth if s.config.MetricsUsername != "" { s.router.Group(func(r chi.Router) { r.Use(s.mw.MetricsAuth()) r.Get("/metrics", http.HandlerFunc(promhttp.Handler().ServeHTTP)) }) } }