Documentation
¶
Index ¶
- Constants
- Variables
- func APIBodyLimit(limit int64, larger map[string]int64, next http.Handler) http.Handler
- func ClearLauncherDashboardSessionCookie(w http.ResponseWriter, r *http.Request, secure func(*http.Request) bool)
- func ContentSecurityPolicy(scriptHashes []string) string
- func DefaultLauncherDashboardSecureCookie(r *http.Request) bool
- func HostAllowlist(cfg HostAllowlistConfig, next http.Handler) http.Handler
- func IPAllowlist(cfg IPAllowlistConfig, next http.Handler) (http.Handler, error)
- func InlineScriptHashes(html []byte) []string
- func JSONContentType(next http.Handler) http.Handler
- func LauncherDashboardAuth(cfg LauncherDashboardAuthConfig, next http.Handler) http.Handler
- func LauncherDashboardSetupURLPath(token string) string
- func Logger(next http.Handler) http.Handler
- func NewLauncherDashboardSessionCookie() (string, error)
- func NewLauncherDashboardSetupToken() (string, error)
- func Recoverer(next http.Handler) http.Handler
- func ReferrerPolicyNoReferrer(next http.Handler) http.Handler
- func RequestScheme(r *http.Request) string
- func SameOriginGuard(next http.Handler) http.Handler
- func SameOriginRequest(r *http.Request) bool
- func SecurityHeaders(cfg SecurityHeadersConfig, next http.Handler) http.Handler
- func SetLauncherDashboardSessionCookie(w http.ResponseWriter, r *http.Request, sessionValue string, ...)
- type ClientIPResolver
- type HostAllowlistConfig
- type IPAllowlistConfig
- type LauncherDashboardAuthConfig
- type LauncherDashboardLocalAutoLogin
- type LauncherDashboardSession
- type SecurityHeadersConfig
Constants ¶
const ( // LauncherDashboardLocalAutoLoginPath is the one-shot local browser // bootstrap endpoint used by the launcher-managed auto-open flow. LauncherDashboardLocalAutoLoginPath = "/launcher-auto-login" // LauncherDashboardSetupPath is the setup page used before the dashboard // password is initialized. LauncherDashboardSetupPath = "/launcher-setup" // LauncherDashboardSetupTokenParam is the query parameter of the setup // page that carries the one-time setup token. LauncherDashboardSetupTokenParam = "token" )
const APIBodyReadTimeout = 60 * time.Second
APIBodyReadTimeout bounds reading one request body. It is not a server-wide ReadTimeout: that one stays armed while the handler runs and cancels long requests (module installs, catalog syncs) once it passes.
const DashboardThemeScriptHash = "'sha256-R49sAvhnDYMkfDhvWDBUrx9TOFbwiKRoQrWcjzGQFsI='"
DashboardThemeScriptHash is the CSP hash of the inline script in web/frontend/index.html that applies the saved theme before first paint. The launcher hashes the inline scripts of the page it embeds at startup; this is the fallback when it cannot.
const DefaultAPIBodyLimit = 2 << 20
DefaultAPIBodyLimit bounds an /api request body unless the route reads a larger one itself.
const LauncherDashboardCookieName = "compa_launcher_auth"
LauncherDashboardCookieName is the HttpOnly cookie set after a successful password login.
Variables ¶
var ErrInvalidLauncherDashboardGrant = errors.New("invalid launcher dashboard grant")
ErrInvalidLauncherDashboardGrant reports that an auto-login grant is missing, expired, already consumed, or otherwise invalid.
Functions ¶
func APIBodyLimit ¶
APIBodyLimit caps /api request bodies at limit bytes. Routes in larger (exact paths) are capped at their own limit instead: they take uploads and check the size themselves. A body declared larger is refused at once. Reading a body must finish within APIBodyReadTimeout; the deadline is lifted once it is read.
func ClearLauncherDashboardSessionCookie ¶
func ClearLauncherDashboardSessionCookie(w http.ResponseWriter, r *http.Request, secure func(*http.Request) bool)
ClearLauncherDashboardSessionCookie clears the dashboard session (e.g. logout).
func ContentSecurityPolicy ¶
ContentSecurityPolicy is the dashboard's CSP. Remote https images stay allowed because the owner chooses whether chat shows them (remote_images); connect-src admits the web chat WebSocket.
func DefaultLauncherDashboardSecureCookie ¶
DefaultLauncherDashboardSecureCookie mirrors typical production HTTPS detection (TLS or X-Forwarded-Proto).
func HostAllowlist ¶
func HostAllowlist(cfg HostAllowlistConfig, next http.Handler) http.Handler
HostAllowlist answers only requests whose Host names this computer. A page on another site that rebinds its DNS name to this computer's address still sends its own name as Host, so it is refused before it reaches any endpoint, the first-run setup included. Ports are ignored: the Vite dev server proxies from localhost:5173.
func IPAllowlist ¶
IPAllowlist restricts access to requests from configured CIDR ranges. Loopback addresses can optionally bypass CIDR checks for local administration. X-Forwarded-For is only trusted when the immediate peer is in a trusted CIDR. Empty CIDR list means no restriction.
func InlineScriptHashes ¶
InlineScriptHashes returns the CSP sources ('sha256-...') of the inline scripts in an HTML page, the ones without src, in page order.
func JSONContentType ¶
JSONContentType sets the Content-Type header to application/json for API requests handled by the wrapped handler.
func LauncherDashboardAuth ¶
func LauncherDashboardAuth(cfg LauncherDashboardAuthConfig, next http.Handler) http.Handler
LauncherDashboardAuth requires a valid session cookie before calling next. Public paths are login/setup pages and /api/auth/* handlers.
func LauncherDashboardSetupURLPath ¶
LauncherDashboardSetupURLPath returns the setup page path carrying token.
func NewLauncherDashboardSessionCookie ¶
NewLauncherDashboardSessionCookie creates the per-process session cookie value.
func NewLauncherDashboardSetupToken ¶
NewLauncherDashboardSetupToken creates the one-time token that lets the person who started Compa set the first dashboard password. Only the launcher's own browser launch and console show it.
func Recoverer ¶
Recoverer recovers from panics in downstream handlers and returns a 500 Internal Server Error response when nothing was sent yet.
http.ErrAbortHandler is not a crash: a reverse proxy raises it when the client goes away mid-copy, so it is re-panicked for net/http to handle quietly. A response whose headers already went out is left as it is; writing an error into it would only corrupt it.
func ReferrerPolicyNoReferrer ¶
ReferrerPolicyNoReferrer sets Referrer-Policy: no-referrer on every response so sensitive paths and query parameters are not leaked via the Referer header.
func RequestScheme ¶
RequestScheme is the scheme the browser used: https behind TLS or a proxy that says so in X-Forwarded-Proto, else http.
func SameOriginGuard ¶
SameOriginGuard refuses API writes (POST, PUT, PATCH, DELETE) and the web chat WebSocket handshake when a browser sent them from another origin. The session cookie is SameSite=Lax, which browsers also send from any other localhost port, so the cookie alone does not show that the dashboard asked. A request with neither Origin nor Sec-Fetch-Site comes from no browser, such as curl holding the cookie, and passes: its cookie is the gate.
func SameOriginRequest ¶
SameOriginRequest reports whether r may act: a browser request must come from the page origin r itself names (scheme://host), shown by Origin or, when a browser omits that, by Sec-Fetch-Site same-origin. A request with neither header comes from no browser and passes.
func SecurityHeaders ¶
func SecurityHeaders(cfg SecurityHeadersConfig, next http.Handler) http.Handler
SecurityHeaders sets the content security policy, nosniff, framing and referrer policies on every response, and keeps API answers out of caches. A handler serving other content (a downloaded file) replaces the CSP.
func SetLauncherDashboardSessionCookie ¶
func SetLauncherDashboardSessionCookie( w http.ResponseWriter, r *http.Request, sessionValue string, secure func(*http.Request) bool, )
SetLauncherDashboardSessionCookie writes the HttpOnly session cookie after successful dashboard password login.
Types ¶
type ClientIPResolver ¶
type ClientIPResolver struct {
// contains filtered or unexported fields
}
ClientIPResolver tells the address of the client behind a request the way IPAllowlist does: the peer, or, when the peer is a trusted proxy, the rightmost X-Forwarded-For address that is not one.
func NewClientIPResolver ¶
func NewClientIPResolver(trustedProxyCIDRs []string) (*ClientIPResolver, error)
NewClientIPResolver returns a resolver trusting the proxies in trustedProxyCIDRs.
type HostAllowlistConfig ¶
type HostAllowlistConfig struct {
// ListenHosts are the hosts the launcher was told to listen on (-host or
// COMPA_LAUNCHER_HOST). Wildcards add nothing.
ListenHosts []string
// AllowedHosts are extra names, such as a reverse proxy's
// (launcher-config allowed_hosts).
AllowedHosts []string
// LocalAddrs returns this computer's addresses. Nil reads the interfaces.
LocalAddrs func() []net.IP
}
HostAllowlistConfig lists the Host names the dashboard answers to besides the ones it always accepts: loopback names, this computer's addresses and its host name.
type IPAllowlistConfig ¶
type IPAllowlistConfig struct {
AllowedCIDRs []string
AllowLocalhostBypass bool
TrustedProxyCIDRs []string
}
IPAllowlistConfig controls launcher network access decisions.
type LauncherDashboardAuthConfig ¶
type LauncherDashboardAuthConfig struct {
// Session is the session browsers must hold. When nil, ExpectedCookie is
// the fixed session token.
Session *LauncherDashboardSession
ExpectedCookie string
// LocalAutoLogin enables one-shot startup auto-login.
LocalAutoLogin *LauncherDashboardLocalAutoLogin
// SecureCookie sets the session cookie's Secure flag. If nil, DefaultLauncherDashboardSecureCookie is used.
SecureCookie func(*http.Request) bool
}
LauncherDashboardAuthConfig holds runtime material for dashboard access checks.
type LauncherDashboardLocalAutoLogin ¶
type LauncherDashboardLocalAutoLogin struct {
// contains filtered or unexported fields
}
LauncherDashboardLocalAutoLogin is an in-memory, one-shot startup grant. It is not a reusable credential; it only lets the launcher-opened browser receive the current process session cookie.
func NewLauncherDashboardLocalAutoLogin ¶
func NewLauncherDashboardLocalAutoLogin(ttl time.Duration) (*LauncherDashboardLocalAutoLogin, error)
NewLauncherDashboardLocalAutoLogin creates a one-shot local auto-login grant.
func (*LauncherDashboardLocalAutoLogin) Renew ¶
func (a *LauncherDashboardLocalAutoLogin) Renew(ttl time.Duration) (string, error)
Renew replaces the grant with a fresh one-shot nonce valid for ttl and returns its URL path, so each browser the launcher opens gets its own link and an earlier, used one never comes back.
func (*LauncherDashboardLocalAutoLogin) URLPath ¶
func (a *LauncherDashboardLocalAutoLogin) URLPath() string
URLPath returns the one-shot local auto-login URL path including its nonce.
type LauncherDashboardSession ¶
type LauncherDashboardSession struct {
// contains filtered or unexported fields
}
LauncherDashboardSession holds the session token every signed-in browser carries in its cookie. Rotating it signs every browser out at once.
func FixedLauncherDashboardSession ¶
func FixedLauncherDashboardSession(token string) *LauncherDashboardSession
FixedLauncherDashboardSession returns a session holding token, for callers that pass a fixed cookie value.
func NewLauncherDashboardSession ¶
func NewLauncherDashboardSession() (*LauncherDashboardSession, error)
NewLauncherDashboardSession creates a session with a fresh random token.
func (*LauncherDashboardSession) Rotate ¶
func (s *LauncherDashboardSession) Rotate() (string, error)
Rotate replaces the session token, so every cookie issued before stops working, and returns the new one.
func (*LauncherDashboardSession) Token ¶
func (s *LauncherDashboardSession) Token() string
Token returns the current session token.
func (*LauncherDashboardSession) Valid ¶
func (s *LauncherDashboardSession) Valid(value string) bool
Valid reports whether value is the current session token.
type SecurityHeadersConfig ¶
type SecurityHeadersConfig struct {
// ScriptHashes are the CSP sources ('sha256-...') of the inline scripts
// the dashboard page carries. Empty uses DashboardThemeScriptHash.
ScriptHashes []string
}
SecurityHeadersConfig configures SecurityHeaders.