NextMyDay/internal/core/server/setupflow.go
Claus Lohmar d11e14295b feat(core): add the store, identity plumbing and the door (SPEC-003/004)
- store: SQLite (WAL, foreign keys ON, CGO-free driver) + the embedded
  migration runner; each module's migrations are name-prefixed (D-012)
- audit: the append-only audit log; the actor threads via context (R-1)
- users: the user_id/GUID/email anchors (D-013)
- config: the YAML settings file (D-035) + validation
- httpx: cookies · loopback detection · trusted-proxy XFF · CSRF · security
  headers · redaction
- middleware: correlation id · audit · rate limiting
- mail: the invite/recovery mailer seam
- server: the core DOOR — the resolution switch, the dispatch registry
  (RegisterModule), the role gates, /setup · enroll/login · recovery flows,
  the reserved `static` workflow, and the loopback-only bootstrap (D-025)
2026-10-14 10:53:51 +00:00

38 lines
1.5 KiB
Go

package server
import (
"net/http"
"git.lohmar.co.uk/cclohmar/NextMyDay/internal/core/setup"
)
// setupModule is the `do` module name for the SPEC-005 wizard steps. The
// wizard is a reserved level-1 workflow (`/setup`) whose steps are actions.
const setupModule = "setup"
// RegisterSetupFlow registers the SPEC-005 `/setup` wizard: the page (the core
// `setup` workflow) and the action module (domain.save · admin.create ·
// admin.enroll.* · admin.totp.* · finish). The door gates them to setup mode
// and verifies the pre-session CSRF token (A15) before dispatch.
func RegisterSetupFlow(reg *MapRegistry, a *setup.Actions) {
reg.RegisterCore("setup", adaptSetup(a.Page))
reg.RegisterModule(NewModule(setupModule).
AddAction("domain.save", "domain.save", adaptSetup(a.DomainSave)).
AddAction("admin.create", "admin.create", adaptSetup(a.AdminCreate)).
// Step 2 is TOTP only (D-041) — there is no admin.enroll.* action.
AddAction("admin.totp.begin", "admin.totp.begin", adaptSetup(a.TOTPBegin)).
AddAction("admin.totp.verify", "admin.totp.verify", adaptSetup(a.TOTPVerify)).
AddAction("finish", "finish", adaptSetup(a.Finish)))
}
// setupFunc is a wizard handler. The door resolves the workflow; the wizard
// never parses a raw path.
type setupFunc func(w http.ResponseWriter, r *http.Request) error
// adaptSetup adapts a wizard handler to the door's Handler signature.
func adaptSetup(f setupFunc) Handler {
return func(w http.ResponseWriter, r *http.Request, _ *RequestContext) error {
return f(w, r)
}
}