ui

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package ui is mailctl's local admin page: server-rendered inside the shared toolshell (github.com/zoolcoder/toolshell), reachable from this machine only, and every provider call made through the engine. Duplicating the engine's ordering and safety logic behind an HTTP handler is how the two would come to disagree, so the package holds no reconciliation logic of its own — it asks the Planner and shows the answer.

Files: server.go is the shell (deps, routes, chrome, helpers); results.go remembers the last plan and audit for the life of the process; pages_*.go are the sections.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(deps Deps) (http.Handler, error)

New wires the routes and returns the guarded handler. It validates deps itself so a caller-supplied Deps fails with an error, not a crash.

Types

type Auditor

type Auditor func(ctx context.Context, d config.Domain, desired []dns.Record) audit.Report

Auditor runs one domain's audit. Injected so tests do not perform DNS lookups.

type Deps

type Deps struct {
	Planner Planner
	Audit   Auditor
	// Activity records what the page did; nil records nothing.
	Activity *activity.Log
	// ConfigPath and DataDir are shown on Settings; neither is read here.
	ConfigPath string
	DataDir    string
	// Host is the address the page is served on. When set, a browser must
	// address the page by it or by a loopback name; see guard.HostAllowed. Empty
	// skips the Host check, which only a test should want; the cross-origin
	// check runs either way.
	Host string
	// Getenv answers whether a provider credential is present. nil means
	// os.Getenv. Values are never rendered, only their presence.
	Getenv func(string) string
	// Now is swapped in tests.
	Now func() time.Time
}

Deps is everything the page needs from the command that starts it.

type DomainPlanner

type DomainPlanner interface {
	PlanDomain(ctx context.Context, d config.Domain) (plan.Plan, error)
}

DomainPlanner is the optional narrower run: a Planner that can plan one domain without reading every other domain's live state. The engine implements it; a Planner that does not falls back to a full Plan filtered afterwards.

type Planner

type Planner interface {
	Domains() ([]config.Domain, error)
	Plan(ctx context.Context) (plan.Plan, error)
	Desired(ctx context.Context, d config.Domain) ([]dns.Record, error)
}

Planner is the slice of the engine this server needs. It is an interface so handler tests need neither a provider nor a network.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the handler's state.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP stands in for a login: the page listens on loopback only, so it refuses a Host that is not this page's (DNS rebinding) and any write another site starts (CSRF).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL