Documentation
¶
Overview ¶
Package admin implements the optional HTTP admin server when ENABLE_ADMIN_UI is set.
Authenticated JSON API (Bearer ADMIN_PASSWORD or X-Admin-Token) under /api/:
GET /api/config — raw JSON file
PUT /api/config — replace file (validated, atomic, changelog)
GET /api/config/changelog — recent config changes (?limit=)
GET /api/audit — audit rows (?limit,&offset,&since,&until,&action,&pubkey,&kind); JSON {entries,total}
GET /api/audit/kinds — distinct kinds from recent audit rows (?scan_limit=); JSON {kinds:[]int}
GET /api/audit/connections — WebSocket sessions (?limit,&offset,&include_live=,&include_closed=); JSON {retention_days,live,closed,closed_total?}
GET /api/audit/connections/{ref} — session detail + audit_entries; ref is live:{conn_id} or session:{numeric_id}
GET /api/events — stored events by kind (?kind=&limit=&offset=&since=&until=&pubkey=); {events,total}
GET /api/events/{id} — single stored Nostr event by hex id (404 if not in DB)
GET /api/nips — known NIPs + enabled flags
PATCH /api/nips — body {"nip":N,"enabled":bool}; response includes restart_required
GET /api/stats — open connections, subscriptions, uptime, relay_counters, storage (size details only when database.analyze is on), series.buckets (UTC minutes), recent_query_latency; ports + relay_version
GET /api/relay-identity — relay pubkey_hex, npub, relay_instance_id at process start (read-only)
GET /api/relay-assets/icon|banner — hosted NIP-11 image preview (default art or upload)
POST /api/relay-assets/icon|banner — multipart file upload; sets that image source to upload
POST /api/migration/start — copy sqlite↔postgres with SSE progress; optional make_target_primary to rewrite config
POST /api/migration/target-preflight — read-only target schema inspection (JSON)
Non-API GET requests: CONGEE_ENV dev|development|local reverse-proxies to http://127.0.0.1:5173; if Vite is unreachable, falls back to web/admin/build when index.html exists (e.g. after make ui-build). Otherwise static files from web/admin/build with SPA fallback to index.html.
Index ¶
- func AdminPassword() string
- func DevEnvironment() string
- func Enabled() bool
- func HandleAudit(st storage.Store) http.HandlerFunc
- func HandleAuditConnectionsDetail(cfg *config.Config, relaySrv *relay.Server, store storage.Store) http.HandlerFunc
- func HandleAuditConnectionsList(cfg *config.Config, relaySrv *relay.Server, store storage.Store) http.HandlerFunc
- func HandleAuditKinds(st storage.Store) http.HandlerFunc
- func RequireAdminAuth(password string, next http.Handler) http.Handler
- type Server
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AdminPassword ¶
func AdminPassword() string
AdminPassword returns ADMIN_PASSWORD from the environment (may be empty).
func DevEnvironment ¶
func DevEnvironment() string
DevEnvironment returns lowercased CONGEE_ENV (may be empty).
func Enabled ¶
func Enabled() bool
Enabled reports whether ENABLE_ADMIN_UI is truthy (case-insensitive for common tokens).
func HandleAudit ¶
func HandleAudit(st storage.Store) http.HandlerFunc
HandleAudit serves GET /audit (mounted under /api/ after StripPrefix, wrapped by RequireAdminAuth).
func HandleAuditConnectionsDetail ¶
func HandleAuditConnectionsDetail(cfg *config.Config, relaySrv *relay.Server, store storage.Store) http.HandlerFunc
HandleAuditConnectionsDetail serves GET /audit/connections/{ref}.
func HandleAuditConnectionsList ¶
func HandleAuditConnectionsList(cfg *config.Config, relaySrv *relay.Server, store storage.Store) http.HandlerFunc
HandleAuditConnectionsList serves GET /audit/connections (mounted under /api/ after StripPrefix).
func HandleAuditKinds ¶
func HandleAuditKinds(st storage.Store) http.HandlerFunc
HandleAuditKinds serves GET /audit/kinds (under /api/ after StripPrefix). JSON body: {"kinds":[int,...]}. Optional ?scan_limit= caps how many newest audit rows are scanned (default from storage, max storage.MaxAuditKindsScanLimit).
Types ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the standalone admin HTTP server (API + static UI or Vite proxy).
All JSON APIs are mounted under /api/ and require auth when ENABLE_ADMIN_UI is on (see RequireAdminAuth): Authorization: Bearer <ADMIN_PASSWORD> or X-Admin-Token.
Endpoints (strip prefix /api):
GET/PUT /config — raw JSON file; PUT validates, atomic write, changelog row
GET /config/changelog — recent config change records (?limit=)
GET /audit — audit log (?limit,&offset,&since,&until,&action,&pubkey,&kind); body {entries,total}
GET /audit/kinds — distinct kinds from recent audit rows (?scan_limit=); body {kinds:[]int}
GET /audit/connections — WebSocket sessions (?limit,&offset,&include_live=,&include_closed=); body {retention_days,live,closed,closed_total?}
GET /audit/connections/{ref} — session detail + audit_entries; ref is live:{conn_id} or session:{numeric_id}
GET /events — stored events by kind (?kind= required); body {events,total}
GET /events/{id} — stored event JSON for admin UI (ephemeral / missing → 404)
GET /nips — known NIPs + enabled flags from config
PATCH /nips — toggle optional NIP; restart_required in response
GET /stats — connections, subscriptions_open, started_at_unix, uptime_sec, relay_counters, storage{analysis_enabled,bytes?,events?,...}, series{bucket_sec,buckets}, recent_query_latency; ports + relay_version
GET /relay-identity — relay pubkey_hex, npub, relay_instance_id (runtime)
GET /relay-assets/icon|banner — hosted NIP-11 image bytes for the admin preview
POST /relay-assets/icon|banner — multipart upload; writes the file and sets source to upload
POST /migration/start — data migration (SSE); body may set make_target_primary to update config
POST /migration/target-preflight — JSON { target }; schema status for migration UI
Non-API routes: CONGEE_ENV dev|development|local → reverse proxy to Vite :5173 (GET/HEAD only); otherwise static files from web/admin/build with SPA fallback to index.html.
func NewServer ¶
func NewServer(cfg *config.Config, cfgPath string, store storage.Store, relaySrv *relay.Server, log zerolog.Logger, password, staticDir string, scheduleRestart func(), relayID *relayidentity.Identity, relayInstanceBoot config.RelayInstanceResolution, plugins *plugin.Manager) *Server
NewServer builds an admin server. staticDir is the filesystem root for production assets (e.g. web/admin/build). relaySrv may be nil (stats will show 0 connections). scheduleRestart is invoked after a successful config write or NIP toggle when the running process should be replaced (nil in tests or when restart is disabled). relayInstanceBoot must be the config.RelayInstanceResolution from the same process start as db.Open (see cmd/congee); it is served by GET /relay-identity and does not track in-memory config mutations until the process restarts.
func (*Server) ListenAndServe ¶
ListenAndServe binds the admin port and blocks until the server stops.