package api import ( "net/http" ) const defaultAllowedOrigin = "http://localhost:5173" // NewRouter builds the HTTP API with setup gating, auth, and network middleware. func NewRouter(configDir string) http.Handler { handler, _ := NewRouterWithApp(configDir) return handler } // NewRouterWithApp builds the router and returns the App for lifecycle control (scheduler stop). func NewRouterWithApp(configDir string) (http.Handler, *App) { app, err := newApp(configDir) if err != nil { // newApp currently always succeeds; keep signature for future. panic(err) } if app.Executor != nil { app.Executor.StartScheduler() } if app.HealthChecker != nil { app.HealthChecker.StartScheduler() } mux := http.NewServeMux() mux.HandleFunc("GET /health", HealthHandler) mux.HandleFunc("GET /api/v1/status", StatusHandler) mux.HandleFunc("GET /api/v1/setup/status", app.setupStatusHandler) mux.HandleFunc("POST /api/v1/setup/totp/begin", app.setupTOTPBeginHandler) mux.HandleFunc("POST /api/v1/setup/totp/verify", app.setupTOTPVerifyHandler) mux.HandleFunc("POST /api/v1/setup/network/preview", app.setupPreviewHandler) mux.HandleFunc("POST /api/v1/setup/complete", app.setupCompleteHandler) mux.HandleFunc("POST /api/v1/auth/login", app.loginHandler) mux.HandleFunc("POST /api/v1/auth/logout", app.logoutHandler) mux.HandleFunc("GET /api/v1/auth/me", app.meHandler) mux.HandleFunc("POST /api/v1/auth/reauth", app.reauthHandler) mux.HandleFunc("PUT /api/v1/me/password", app.mePasswordHandler) mux.HandleFunc("POST /api/v1/me/totp/begin", app.meTOTPBeginHandler) mux.HandleFunc("POST /api/v1/me/totp/confirm", app.meTOTPConfirmHandler) mux.HandleFunc("POST /api/v1/me/totp/disable", app.meTOTPDisableHandler) mux.HandleFunc("GET /api/v1/groups", groupsGetHandler(configDir)) mux.HandleFunc("POST /api/v1/groups", groupsUpsertHandler(configDir)) mux.HandleFunc("DELETE /api/v1/groups", groupsDeleteHandler(configDir)) mux.HandleFunc("GET /api/v1/actions", actionsGetHandler(configDir)) mux.HandleFunc("POST /api/v1/actions", actionsCreateHandler(configDir)) mux.HandleFunc("PATCH /api/v1/actions", actionsPatchHandler(configDir)) mux.HandleFunc("DELETE /api/v1/actions", actionsDeleteHandler(configDir)) mux.HandleFunc("GET /api/v1/security", securityGetHandler(configDir)) mux.HandleFunc("PUT /api/v1/security", securityPutHandler(configDir)) mux.HandleFunc("GET /api/v1/network", networkGetHandler(configDir)) mux.HandleFunc("PUT /api/v1/network", networkPutHandler(configDir)) mux.HandleFunc("GET /api/v1/users", app.usersGetHandler) mux.HandleFunc("POST /api/v1/users", app.usersCreateHandler) mux.HandleFunc("PATCH /api/v1/users", app.usersPatchHandler) mux.HandleFunc("DELETE /api/v1/users", app.usersDeleteHandler) mux.HandleFunc("GET /api/v1/nodes", app.nodesListHandler) mux.HandleFunc("POST /api/v1/nodes", app.nodesCreateHandler) mux.HandleFunc("GET /api/v1/nodes/{id}", app.nodesGetHandler) mux.HandleFunc("PATCH /api/v1/nodes/{id}", app.nodesPatchHandler) mux.HandleFunc("DELETE /api/v1/nodes/{id}", app.nodesDeleteHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/test-ssh", app.nodesTestSSHHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/health-check", app.nodesHealthCheckHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/resolve-commands", app.nodesResolveCommandsHandler) mux.HandleFunc("GET /api/v1/nodes/{id}/action-groups", app.actionGroupsListHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/action-groups", app.actionGroupsCreateHandler) mux.HandleFunc("PATCH /api/v1/nodes/{id}/action-groups/{gid}", app.actionGroupsPatchHandler) mux.HandleFunc("DELETE /api/v1/nodes/{id}/action-groups/{gid}", app.actionGroupsDeleteHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/action-groups/{gid}/items", app.actionGroupItemsCreateHandler) mux.HandleFunc("PATCH /api/v1/nodes/{id}/action-groups/{gid}/items/{iid}", app.actionGroupItemsPatchHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/action-groups/{gid}/items/{iid}/clone", app.actionGroupItemsCloneHandler) mux.HandleFunc("DELETE /api/v1/nodes/{id}/action-groups/{gid}/items/{iid}", app.actionGroupItemsDeleteHandler) mux.HandleFunc("PUT /api/v1/nodes/{id}/action-groups/{gid}/items/order", app.actionGroupItemsOrderHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/action-groups/{gid}/run", app.actionGroupsRunHandler) mux.HandleFunc("POST /api/v1/nodes/{id}/action-groups/{gid}/items/{iid}/run", app.actionGroupItemsRunHandler) mux.HandleFunc("GET /api/v1/nodes/{id}/action-logs", app.actionLogsListHandler) mux.HandleFunc("GET /api/v1/nodes/{id}/action-logs/{filename}", app.actionLogsGetHandler) mux.HandleFunc("GET /api/v1/nodes/{id}/action-widgets", app.actionWidgetsListHandler) mux.HandleFunc("GET /api/v1/action-widgets", app.actionWidgetsListAllHandler) mux.HandleFunc("GET /api/v1/node-logs", app.nodeLogsListHandler) mux.HandleFunc("GET /api/v1/auth-logs", app.authLogsListHandler) return app.withCORS(app.withMiddleware(mux)), app }