Make delivery and integration failures explicit
Persist reminder presentations and retry state, atomically complete collapsed deliveries, fall back across away reaches, and block permanent failures visibly (V-715, V-678). Fail closed when enabled integrations lack credentials and keep remote arms explicitly dark (V-691). Give mavweb one sanitized, request-correlated error contract (V-689). Owner explicitly requested direct commits to master.
This commit is contained in:
+18
-6
@@ -48,9 +48,14 @@ func main() {
|
||||
hexisURL := flag.String("hexis", "", "Hexis base URL for the /ecosystem panel (empty = not configured)")
|
||||
// Shared secret for POST /api/ambient, the notification-relay ingest that
|
||||
// reads the work calendar as a signal instead of holding a work credential
|
||||
// (see ambient.go). Empty ⇒ the route is not registered at all.
|
||||
ambientToken := flag.String("ambient-token", "", "shared secret for POST /api/ambient notification ingest (empty = ingest disabled, route not registered)")
|
||||
// (see ambient.go). Enabling and authenticating are separate on purpose: an
|
||||
// expanded-empty secret cannot silently turn a live integration off.
|
||||
ambientEnabled := flag.Bool("ambient-enabled", false, "enable POST /api/ambient notification ingest (requires -ambient-token)")
|
||||
ambientToken := flag.String("ambient-token", "", "shared secret for POST /api/ambient notification ingest")
|
||||
flag.Parse()
|
||||
if err := validateAmbientConfig(*ambientEnabled, *ambientToken); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var core ipc.CoreAPI
|
||||
// swapConn — a second connection, for /models and nothing else. A model swap
|
||||
@@ -129,9 +134,9 @@ func main() {
|
||||
w.Write([]byte(*ntfyWS))
|
||||
})
|
||||
mux.HandleFunc("/api/signal", corePage(handleSignal))
|
||||
// Off unless configured: no token, no route — an unconfigured ingest is not
|
||||
// a 503 waiting to be probed, it does not exist.
|
||||
if *ambientToken != "" {
|
||||
// Off unless explicitly enabled: a dark ingest has no route at all, while an
|
||||
// enabled ingest with no token was rejected before the server was built.
|
||||
if *ambientEnabled {
|
||||
mux.HandleFunc("/api/ambient", func(w http.ResponseWriter, r *http.Request) {
|
||||
handleAmbient(w, r, core, *ambientToken)
|
||||
})
|
||||
@@ -251,6 +256,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func validateAmbientConfig(enabled bool, token string) error {
|
||||
if enabled && token == "" {
|
||||
return errors.New("mavweb: ambient ingest is enabled but -ambient-token is empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// logUnguardedSurfaces names, at startup, what step-up would have covered had
|
||||
// WebAuthn been configured. One surface per line: these are read in a terminal
|
||||
// at the moment someone is deciding whether the box is safe to expose.
|
||||
@@ -288,7 +300,7 @@ const (
|
||||
func mavwebHTTPServer(addr string, handler http.Handler) *http.Server {
|
||||
return &http.Server{
|
||||
Addr: addr,
|
||||
Handler: handler,
|
||||
Handler: withRequestID(handler),
|
||||
ReadHeaderTimeout: mavwebReadHeaderTimeout,
|
||||
ReadTimeout: mavwebReadTimeout,
|
||||
IdleTimeout: mavwebIdleTimeout,
|
||||
|
||||
Reference in New Issue
Block a user