summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/dashboard/main.go59
1 files changed, 44 insertions, 15 deletions
diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go
index c648ede..596932a 100644
--- a/cmd/dashboard/main.go
+++ b/cmd/dashboard/main.go
@@ -163,8 +163,29 @@ func main() {
r.Use(appmiddleware.SecurityHeaders(cfg.Debug)) // Security headers
r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally
- // Initialize Claudomator reverse proxy
- claudomatorProxy := handlers.NewClaudomatorProxy(cfg.ClaudomatorURL, cfg.WebAuthnOrigin)
+ // Service gateway — upstream services proxied through doot's auth + SSL layer.
+ // Each mount registers a path prefix, upstream URL, and any public webhook paths.
+ type serviceMount struct {
+ name string
+ upstream string
+ prefix string
+ webhookPaths []string // POST paths that bypass session auth (e.g. HMAC-signed webhooks)
+ }
+ mounts := []serviceMount{
+ {
+ name: "claudomator",
+ upstream: cfg.ClaudomatorURL,
+ prefix: "/claudomator",
+ webhookPaths: []string{"/claudomator/api/webhooks/github"},
+ },
+ }
+ if cfg.PlaygroundURL != "" {
+ mounts = append(mounts, serviceMount{
+ name: "playground",
+ upstream: cfg.PlaygroundURL,
+ prefix: "/playground",
+ })
+ }
// Rate limiter for auth endpoints
authRateLimiter := appmiddleware.NewRateLimiter(config.AuthRateLimitRequests, config.AuthRateLimitWindow)
@@ -225,21 +246,29 @@ 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)
- })
+ // Register service gateway mounts — each upstream proxied behind doot's auth layer.
+ for _, m := range mounts {
+ proxy := handlers.NewServiceProxy(m.upstream, cfg.WebAuthnOrigin, m.prefix)
- // GitHub webhook: no auth (GitHub POSTs with HMAC, no session)
- r.Post("/claudomator/api/webhooks/github", claudomatorProxy.ServeHTTP)
+ // Bare prefix → redirect to prefix/
+ prefix := m.prefix
+ r.Get(prefix, func(w http.ResponseWriter, r *http.Request) {
+ http.Redirect(w, r, prefix+"/", http.StatusMovedPermanently)
+ })
+
+ // Public webhook paths bypass session auth (rely on service-level HMAC/token)
+ for _, wp := range m.webhookPaths {
+ r.Post(wp, proxy.ServeHTTP)
+ }
+
+ // All other routes require auth + origin check (CSRF protection for proxy)
+ r.Group(func(r chi.Router) {
+ r.Use(authHandlers.Middleware().RequireAuth)
+ r.Use(auth.OriginCheck(cfg.WebAuthnOrigin))
+ r.Handle(prefix+"/*", proxy)
+ })
+ }
- // All other Claudomator routes: RequireAuth + origin check (CSRF protection for proxy)
- r.Group(func(r chi.Router) {
- r.Use(authHandlers.Middleware().RequireAuth)
- r.Use(auth.OriginCheck(cfg.WebAuthnOrigin))
- r.Handle("/claudomator/*", claudomatorProxy)
- })
// Protected routes (auth required)
r.Group(func(r chi.Router) {