admin-gui

star 121

Documentation of the HTMX admin GUI including template rendering, session management, CRUD patterns, and the GUIHandler structure.

gjovanovicst By gjovanovicst schedule Updated 3/4/2026

name: admin-gui description: Documentation of the HTMX admin GUI including template rendering, session management, CRUD patterns, and the GUIHandler structure. license: MIT

Overview

The admin GUI is an HTMX-powered web interface at /gui/*. It provides a complete management dashboard for the Auth API platform. The main handler is internal/admin/gui_handler.go (4976 lines, the largest file in the project).

Architecture

GUIHandler (internal/admin/gui_handler.go)
  |-- AccountService   -> admin auth, sessions, 2FA, CSRF
  |-- DashboardService -> stats aggregation
  |-- Repository       -> data access (tenants, apps, users, etc.)
  |-- SettingsService  -> system settings management
  |-- EmailService     -> email template/server management
  |-- RBACService      -> role/permission management
  |-- PasskeyService   -> WebAuthn for admin accounts

Template Rendering (web/renderer.go)

Embedded filesystem: //go:embed templates in web/renderer.go

Template structure:

web/templates/
  layouts/     -> base layout files (*.tmpl)
  partials/    -> reusable fragments (*.tmpl) -- also served as standalone for HTMX
  pages/       -> full page templates (*.tmpl)

Parsing strategy:

  • Full pages = layouts + partials + page file (rendered via c.HTML())
  • HTMX fragments = partials rendered standalone (for dynamic swaps)

Template data struct (web.TemplateData):

type TemplateData struct {
    ActivePage    string      // Current page identifier for nav highlighting
    AdminUsername string      // From auth context
    AdminID       string      // From auth context
    CSRFToken     string      // From CSRF middleware
    FlashSuccess  string      // Flash messages
    FlashError    string
    Error         string      // Login-specific error
    Username      string      // Pre-filled username on login error
    Redirect      string      // Post-login redirect URL
    TempToken     string      // 2FA temp token
    TwoFAMethod   string      // "totp" or "email"
    Data          interface{} // Page-specific arbitrary data
}

Template functions available (web.defaultFuncMap):

  • formatDate, formatDateTime, formatDateTimeFull -- date formatting
  • timeAgo -- human-readable relative time
  • upper, lower, title -- string transforms
  • safeHTML, safeURL -- mark content as safe (no escaping)
  • eq -- string equality
  • deref -- dereference *time.Time (nil-safe)
  • isExpired -- check if time is in the past
  • add, sub -- arithmetic for pagination

Authentication Flow

Standard Login

GET  /gui/login          -> LoginPage (render login form)
POST /gui/login          -> LoginSubmit [rate limited: 5/min]
  -> accountService.Authenticate(username, password)
  -> If 2FA: CreatePending2FASession -> redirect to /gui/2fa-verify
  -> If no 2FA: CreateSession -> set cookie -> redirect to /gui/

2FA Verification

GET  /gui/2fa-verify     -> TwoFAVerifyPage (render 2FA form)
POST /gui/2fa-verify     -> TwoFAVerifySubmit
  -> Validate TOTP code, email code, or recovery code
  -> PromotePendingSession -> set cookie -> redirect

Passkey Login (passwordless)

POST /gui/passkey-login/begin  -> PasskeyLoginBegin (returns JSON challenge)
POST /gui/passkey-login/finish -> PasskeyLoginFinish (validates assertion)
  -> CreateSession -> set cookie -> return JSON success

Magic Link Login (passwordless)

POST /gui/magic-link-login         -> MagicLinkLoginRequest
  -> Generate token in Redis (10 min) -> send email
GET  /gui/magic-link-login/verify  -> MagicLinkLoginVerify
  -> Validate token -> CreateSession -> set cookie -> redirect

Session Cookie

  • Name: admin_session (constant: web.AdminSessionCookie)
  • Path: /gui
  • Flags: HttpOnly, SameSite=Strict, Secure (auto-detected)
  • Set via web.SetSessionCookie(), cleared via web.ClearSessionCookie()

HTMX CRUD Pattern

Every entity domain follows a consistent pattern. Example for tenants:

GET  /gui/tenants              -> TenantPage (full page with layout)
GET  /gui/tenants/list         -> TenantList (HTMX partial, paginated table)
GET  /gui/tenants/new          -> TenantCreateForm (HTMX partial, form)
POST /gui/tenants              -> TenantCreate (creates, returns alert + triggers list refresh)
GET  /gui/tenants/form-cancel  -> TenantFormCancel (empty response, cancels form)
GET  /gui/tenants/:id/edit     -> TenantEditForm (HTMX partial, pre-filled form)
PUT  /gui/tenants/:id          -> TenantUpdate (updates, returns alert + triggers list refresh)
GET  /gui/tenants/:id/delete   -> TenantDeleteConfirm (HTMX partial, confirmation modal)
DELETE /gui/tenants/:id        -> TenantDelete (deletes, triggers list refresh)

HTMX signals: Methods set HX-Trigger headers to signal events:

  • Entity events: tenantDeleted, roleDeleted, sessionListRefresh, socialAccountUnlinked, permissionsSaved, etc.
  • These trigger list refreshes and modal closes on the client side

Error handling: Errors are returned as Bootstrap alert HTML snippets via c.String() or c.HTML().

GUIHandler Method Groups

Approx Lines Section Entity/Feature
1-120 Auth Login, Logout, 2FA verify
120-200 Dashboard Stats display
200-550 Tenants Full CRUD
550-950 Applications Full CRUD
950-1350 OAuth Configs Full CRUD + toggle enabled
1350-1900 Users List (paginated, searchable), detail, toggle active
1900-2200 Activity Logs List (paginated, filterable), detail
2200-2600 API Keys CRUD + revoke
2600-2850 Settings Three-tier resolution display, update, reset
2850-3050 Email (Servers/Templates/Types) Full CRUD for each
3050-3100 My Account (Email/Password) Profile management
3100-3330 My Account (2FA) TOTP generate/verify, email 2FA, recovery codes
3335-3480 My Account (Passkeys) Register, delete, rename
3480-3715 Roles CRUD + permission assignment modal
3715-3865 Permissions List, create
3865-4115 User Roles Assign, revoke, search users, dynamic dropdowns
4115-4210 Social Account Mgmt Unlink (with lockout prevention)
4215-4290 Passkey Mgmt (for users) Delete user's passkey
4290-4340 Helpers parseVariablesFromForm, escapeHTML
4340-4420 Passkey Login WebAuthn discoverable login ceremony
4420-4600 Magic Link Login Request, verify
4600-4976 Session Management List (cross-app), detail, revoke, per-user sessions

CSRF Protection

Middleware: internal/middleware/csrf.go

  • GET requests: generate CSRF token, set in context as csrf_token
  • POST/PUT/DELETE: read from X-CSRF-Token header (HTMX) or _csrf form field
  • Token validated against session via sessionValidator.ValidateCSRFToken()

HTMX sends CSRF token via header: templates set hx-headers='{"X-CSRF-Token": "{{.CSRFToken}}"}'

Rate Limiting (GUI-specific)

Endpoint Limit Window Lockout
POST /gui/login 5/min 60s 10 -> 15min
POST /gui/passkey-login/* 10/min 60s 20 -> 15min
POST /gui/magic-link-login 3/15min 15min none

GUI rate limiting sets web.RateLimitErrorKey in context (doesn't abort), letting the handler render the error in the form.

Static Assets

Embedded via web/static/embed.go using //go:embed. Served at /gui/static/*.

Key Dependencies

  • admin.AccountService implements web.SessionValidator (for GUI auth + CSRF middleware)
  • admin.Repository implements web.ApiKeyValidator (for admin/app API key middleware)
  • Both interfaces defined in web/context_keys.go to avoid import cycles

When To Use This Skill

Load this skill when working on the admin web interface, HTMX templates, GUI authentication, or any /gui/* route.

Install via CLI
npx skills add https://github.com/gjovanovicst/golang-auth-api --skill admin-gui
Repository Details
star Stars 121
call_split Forks 18
navigation Branch main
article Path SKILL.md
More from Creator
gjovanovicst
gjovanovicst Explore all skills →