From 2db5020047640361066510f29f908ca9fd1c99aa Mon Sep 17 00:00:00 2001 From: Doot Agent Date: Wed, 25 Mar 2026 04:03:13 +0000 Subject: feat: gate Claudomator UI behind Doot session auth via reverse proxy Co-Authored-By: Claude Sonnet 4.6 --- cmd/dashboard/main.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'cmd/dashboard') diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index 68d3484..437420d 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -156,8 +156,10 @@ func main() { r.Use(middleware.Recoverer) r.Use(middleware.Timeout(config.RequestTimeout)) r.Use(appmiddleware.SecurityHeaders(cfg.Debug)) // Security headers - r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally - r.Use(authHandlers.Middleware().CSRFProtect) // CSRF protection + r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally + + // Initialize Claudomator reverse proxy + claudomatorProxy := handlers.NewClaudomatorProxy(cfg.ClaudomatorURL) // Rate limiter for auth endpoints authRateLimiter := appmiddleware.NewRateLimiter(config.AuthRateLimitRequests, config.AuthRateLimitWindow) @@ -218,8 +220,24 @@ func main() { }) }) + // Claudomator proxy routes + // /claudomator (no trailing slash) -> 301 redirect + r.Get("/claudomator", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/claudomator/", http.StatusMovedPermanently) + }) + + // GitHub webhook: no auth (GitHub POSTs with HMAC, no session) + r.Post("/claudomator/api/webhooks/github", claudomatorProxy.ServeHTTP) + + // All other Claudomator routes: RequireAuth only, no CSRF + r.Group(func(r chi.Router) { + r.Use(authHandlers.Middleware().RequireAuth) + r.Handle("/claudomator/*", claudomatorProxy) + }) + // Protected routes (auth required) r.Group(func(r chi.Router) { + r.Use(authHandlers.Middleware().CSRFProtect) r.Use(authHandlers.Middleware().RequireAuth) // Dashboard -- cgit v1.2.3