api

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BasicAuthMiddleware

func BasicAuthMiddleware(svc *service.Service, sessions *SessionStore) func(http.Handler) http.Handler

BasicAuthMiddleware wraps the whole standalone server — the login page, every API route, the embedded SPA's static assets — behind HTTP Basic Auth, checked against the same single admin account used for the session-cookie login (internal/api/auth.go). Off by default (models.AuthCredentials.BasicAuthEnabled); when off, every request passes straight through. This is a coarser gate than the session login: it's meant for exposing the standalone server directly on the internet without a reverse proxy in front of it, so even the login page/JS bundle isn't reachable by an unauthenticated visitor.

A request that already carries a valid session cookie skips the basic auth check entirely, regardless of path. Without this, an admin who's already logged in gets challenged by the browser's native Basic Auth popup for *every* page load/request once this is turned on — including the Settings page itself, so turning it back off required first passing a second, separate login prompt on top of the session they already had. Basic auth here is a perimeter gate against visitors who haven't authenticated at all yet (hiding the login page from random scanners); it isn't meant to nag someone who already has a valid session.

Must be wrapped *inside* CorsMiddleware (i.e. cmd/awg-admin.go should build the handler chain as CorsMiddleware(BasicAuthMiddleware(...))) — CorsMiddleware answers cross-origin preflight OPTIONS requests itself without calling next, so putting it outside keeps `npm run dev`'s CORS preflight working even when basic auth is enabled (browsers don't send credentials on preflight requests, so a naive outermost wrap would reject every preflight with 401, breaking the dev server in cross-origin setups whenever this toggle is on).

func CorsMiddleware

func CorsMiddleware(next http.Handler) http.Handler

CorsMiddleware wraps the whole standalone-server http.Handler (router and all) so cross-origin requests with cookies work — needed by `npm run dev` (Vite on :5173) talking to the backend on :8080 during development. The production deployment serves the SPA and API from the same origin and doesn't need this, but it's harmless there too.

The request's Origin is reflected back rather than using "*": browsers reject credentialed (cookie-bearing) requests against a wildcard origin, and Access-Control-Allow-Credentials is what makes the session cookie set by /auth/login actually get sent on subsequent cross-origin requests.

func Serve

func Serve(router *bunrouter.Router) http.Handler

Serve adapts router into a plain http.Handler that actually writes the HTTP status/body for errors returned by route handlers (handleErr's *ErrorResponse, badRequest, requireAuth's 401, ...).

(*bunrouter.Router).ServeHTTP discards those errors silently — `_ = r.ServeHTTPError(w, req)` — leaving every error response as an empty "200 OK" with nothing written. Only bunrouter.HandlerFunc's own ServeHTTP (used when a single route is adapted into a raw http.Handler, e.g. via bunrouter.HTTPHandler) performs the error-to-http.Error conversion; the router itself never does it for the request as a whole. Use this instead of the router directly as the top-level http.Server Handler.

Types

type ErrorResponse

type ErrorResponse struct {
	Err    error
	Status int
}

func (*ErrorResponse) Error

func (e *ErrorResponse) Error() string

func (*ErrorResponse) StatusCode

func (e *ErrorResponse) StatusCode() int

type Handler

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

type SessionStore

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

SessionStore is an in-memory set of valid session tokens for the standalone web server's single admin account. Tokens are opaque random values rather than signed/stateless JWTs — there's exactly one account and one process holding the store, so there's nothing distributed to support (see project conventions: single-user app). Sessions don't survive a server restart, matching how the SSH passphrase cache (internal/sshclient.Manager) already treats in-memory state as scoped to the process's lifetime ("for the duration of the session").

func New

func New(svc *service.Service, rootGroup *bunrouter.Group) *SessionStore

New registers every route of the standalone web server's JSON API (cmd/awg-admin.go) on rootGroup. The Wails desktop app (app.go) never calls this — it binds *service.Service directly to the frontend, so none of this — including the login/session requirement — applies there.

/auth/login and /auth/logout are deliberately left outside the requireAuth-protected group: there's no session yet to check before logging in, and logging out must work even with a stale/invalid cookie.

Returns the session store it created so the caller can wire it into BasicAuthMiddleware, letting an already-logged-in session bypass that gate (see BasicAuthMiddleware's doc comment).

Jump to

Keyboard shortcuts

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