Files
zeekayandHanzo Dev 55aa586615 a product states which of its own routes a publishable key reaches
What such a key may reach was a list of addresses kept in the rule that
reads it. The list held Base's own routes and nothing else, so bootnode's
twelve reads — which it registers precisely to be reachable that way, and
guards with a read-only refusal beside each of its eleven writes —
answered 403 wherever the plugin was on.

A list of one package's addresses kept in another goes stale the moment
that package mounts a route, and it goes stale silently. So the answer
moves to the route: apis.Public declares one where it is registered, and
the rule holds no addresses at all. Bootnode declares its twelve reads;
Base declares its records, rest, files and health reads. The rule keeps
one address of its own, the public submit path, because whether it is
public is the collection's statement and not the route's.

A route needs to know its whole address for that, so the mux records it
as it mounts: Route.Pattern is the method, the group prefixes and the
path, the same string a request reports having matched.

Second layer, restored: bootnode read ReadOnly off the identity headers,
which the org plugin writes identically for every key it resolves — so a
publishable key arrived as a person and no read-only refusal could fire.
The headers say who; the credential says what kind.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-24 06:55:07 -07:00

61 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package apis
import (
"net/http"
"slices"
"github.com/hanzoai/base/core"
"github.com/hanzoai/base/tools/router"
)
// BindHealthzRoute registers health check endpoints.
// /healthz at root (platform standard) and /health under the API group.
func BindHealthzRoute(rg *router.Router[*core.RequestEvent]) {
// Liveness answers a request carrying no credential at all, so a
// credential widens nothing here and is not grounds for a refusal.
Public(rg.GET("/healthz", healthCheck))
}
// bindHealthApi registers /v1/health.
func bindHealthApi(app core.App, rg *router.RouterGroup[*core.RequestEvent]) {
Public(rg.GET("/health", healthCheck))
}
// healthCheck returns a 200 OK response if the server is healthy.
func healthCheck(e *core.RequestEvent) error {
resp := struct {
Message string `json:"message"`
Code int `json:"code"`
Data map[string]any `json:"data"`
}{
Code: http.StatusOK,
Message: "API is healthy.",
}
if e.HasSuperuserAuth() {
resp.Data = make(map[string]any, 3)
resp.Data["canBackup"] = !e.App.Store().Has(core.StoreKeyActiveBackup)
resp.Data["realIP"] = e.RealIP()
// loosely check if behind a reverse proxy
// (usually used in the dashboard to remind superusers in case deployed behind reverse-proxy)
possibleProxyHeader := ""
headersToCheck := append(
slices.Clone(e.App.Settings().TrustedProxy.Headers),
// common proxy headers
"CF-Connecting-IP", "Fly-Client-IP", "X‑Forwarded-For",
)
for _, header := range headersToCheck {
if e.Request.Header.Get(header) != "" {
possibleProxyHeader = header
break
}
}
resp.Data["possibleProxyHeader"] = possibleProxyHeader
} else {
resp.Data = map[string]any{} // ensure that it is returned as object
}
return e.JSON(http.StatusOK, resp)
}