web

package
v0.0.0-...-b140ed9 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 16 Imported by: 0

README

Admin Dashboard Branding

Customize the admin dashboard appearance by setting fields on AdminBrandingConfig in your core.Config.

Configuration

cfg := core.Config{
    Admin: core.AdminConfig{
        Branding: core.AdminBrandingConfig{
            OrgName:      "Acme Corp",
            LogoURL:      "https://acme.com/logo.svg",
            PrimaryColor: "#4f46e5",
            BorderRadius: "0.75rem",
            SidebarColor: "#1a1a2e",
        },
    },
}

All fields are optional. Zero values produce the default Bootstrap look.

Fields

Field Type Default Description
OrgName string "Auth API" Organization name shown on the login page and sidebar header.
LogoURL string Shield icon URL or file path to your logo. Shown at 64px on the login page and 28px in the sidebar.
PrimaryColor string Bootstrap blue (#0d6efd) Hex color (#RGB or #RRGGBB). Overrides buttons, links, and active states.
SecondaryColor string Bootstrap default Hex color. Overrides the Bootstrap secondary color.
BorderRadius string Bootstrap default CSS length (e.g. "0.5rem", "0", "8px"). Controls roundness of cards, buttons, inputs.
SidebarColor string #212529 light / #101214 dark Hex color for sidebar background. Applies to both light and dark themes.
SidebarTextColor string Auto-derived Hex color for sidebar text. When empty, automatically picks #ffffff (dark bg) or #212529 (light bg) based on sidebar background luminance.

LogoURL accepts two formats:

  • URL (http:// or https://): used directly as <img src>.
  • File path: the file is read at startup and served at <AdminBasePath>/branding/logo (default /gui/branding/logo). The file must exist when app.New() is called.

Supported formats: PNG, SVG, JPG, WebP — anything a browser <img> tag can render.

Sidebar Text Auto-Derivation

When SidebarColor is set but SidebarTextColor is empty, the text color is computed automatically using WCAG relative luminance:

  • Luminance > 0.5 → dark text (#212529)
  • Luminance ≤ 0.5 → light text (#ffffff)

Set SidebarTextColor explicitly to override this behavior.

CSS Variables Overridden

When branding is configured, these Bootstrap CSS variables are overridden via inline <style> blocks:

  • --bs-primary (from PrimaryColor)
  • --bs-secondary (from SecondaryColor)
  • --bs-border-radius (from BorderRadius)
  • .btn-primary component variables (hover, active states derived via color-mix)
  • .sidebar background and nav-link colors (from SidebarColor / SidebarTextColor)

Documentation

Overview

Package web provides the embedded admin GUI assets and HTML template renderer used by the go-core admin interface.

Index

Constants

View Source
const (
	// AdminSessionCookie is the name of the HTTP-only cookie for admin GUI sessions.
	AdminSessionCookie = "admin_session"

	// ThemeCookieName is the name of the cookie that stores the admin GUI theme preference.
	ThemeCookieName = "gui_theme"

	// GUIAdminIDKey is the Gin context key for the authenticated admin's ID.
	GUIAdminIDKey = "admin_id"

	// GUIAdminUsernameKey is the Gin context key for the authenticated admin's username.
	GUIAdminUsernameKey = "admin_username"

	// GUISessionIDKey is the Gin context key for the current session ID.
	GUISessionIDKey = "admin_session_id"

	// CSRFTokenKey is the Gin context key where the CSRF token is stored for templates.
	CSRFTokenKey = "csrf_token"

	// RateLimitErrorKey is the Gin context key set by the rate limiter
	// when a request is rate-limited. The value is the error message string.
	RateLimitErrorKey = "rate_limit_error"

	// AuthTypeKey is the Gin context key set by API key middleware to indicate
	// how the request was authenticated. Handlers can use this to adjust behavior
	// based on access type (e.g., hide sensitive fields for app-level access).
	AuthTypeKey = "auth_type"

	// AuthTypeAdmin indicates the request was authenticated with an admin API key.
	AuthTypeAdmin = "admin"

	// AuthTypeApp indicates the request was authenticated with a per-application API key.
	AuthTypeApp = "app"

	// ApiKeyScopesKey is the Gin context key for the scopes granted by the validated API key.
	// Value is []string; set by AppApiKeyMiddleware and AdminAuthMiddleware after successful validation.
	ApiKeyScopesKey = "api_key_scopes" // #nosec G101 -- context key string, not a credential
)

Variables

View Source
var ClearRateLimitFallback func(keyPrefix, identifier string)

ClearRateLimitFallback is a hook set by the rate-limit middleware package. It clears the in-memory fallback counters for a given prefix + identifier. Callers (e.g. login handlers) should invoke this alongside the Redis clear so that both stores are reset on success.

The function is nil until the middleware package's init() registers it.

Functions

func AutoSidebarTextColor

func AutoSidebarTextColor(sidebarHex string) string

AutoSidebarTextColor returns "#ffffff" for dark sidebar backgrounds and "#212529" for light ones, based on WCAG relative luminance. Falls back to "#ffffff" if sidebarHex cannot be parsed.

func ClearSessionCookie

func ClearSessionCookie(c *gin.Context, basePath string)

ClearSessionCookie removes the admin session cookie. basePath must match the path used when the cookie was set.

func GetTheme

func GetTheme(c *gin.Context) string

GetTheme reads the gui_theme cookie and returns "dark" or "light" (default). Used by GUI handlers to populate TemplateData.Theme for server-side theme injection.

func IsSecureCookie

func IsSecureCookie(c *gin.Context) bool

IsSecureCookie returns true if the request is over HTTPS (Secure flag for cookies).

func ParseHexColor

func ParseHexColor(hex string) (r, g, b uint8, err error)

ParseHexColor parses a CSS hex color string (3-digit or 6-digit, with leading #) into its red, green, and blue uint8 components. It is case-insensitive.

func RelativeLuminance

func RelativeLuminance(r, g, b uint8) float64

RelativeLuminance computes the WCAG 2.1 relative luminance of an sRGB color. Returns a value in [0, 1] where 0 is black and 1 is white.

func SetSessionCookie

func SetSessionCookie(c *gin.Context, sessionID string, maxAge int, basePath string)

SetSessionCookie sets the admin session cookie with security flags. Uses http.SetCookie directly to set SameSite=Strict (not supported by Gin's c.SetCookie). basePath scopes the cookie to the admin GUI prefix (e.g. "/gui").

Types

type ApiKeyValidator

type ApiKeyValidator interface {
	// FindActiveKeyByHash looks up an active (non-revoked, non-expired) API key by its SHA-256 hash.
	// Returns nil, nil if no matching key is found.
	FindActiveKeyByHash(keyHash string) (*models.ApiKey, error)

	// UpdateApiKeyLastUsed sets the last_used_at timestamp to now (fire-and-forget).
	UpdateApiKeyLastUsed(id uuid.UUID)

	// IncrementDailyUsage increments the daily usage counter for the key (fire-and-forget).
	IncrementDailyUsage(id uuid.UUID)
}

ApiKeyValidator is the interface used by admin/app API key middleware to validate keys against hashed keys stored in the database. Implemented by admin.Repository.

type HTMLRender

type HTMLRender struct {
	Template *template.Template
	Name     string
	Data     interface{}
}

HTMLRender implements gin's render.Render interface for a single template execution.

func (*HTMLRender) Render

func (h *HTMLRender) Render(w http.ResponseWriter) error

Render writes the template to the response writer.

func (*HTMLRender) WriteContentType

func (h *HTMLRender) WriteContentType(w http.ResponseWriter)

WriteContentType sets the Content-Type header.

type Renderer

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

Renderer implements gin's render.HTMLRender interface using embedded templates.

func NewRenderer

func NewRenderer(basePath string) (*Renderer, error)

NewRenderer creates a Renderer by parsing all embedded templates. Layout templates are combined with each page template so that {{template "base" .}} works from page templates. basePath is the URL prefix for the admin GUI (e.g. "/gui", "/admin").

func (*Renderer) Instance

func (r *Renderer) Instance(name string, data interface{}) render.Render

Instance returns a render.Render for a specific template name and data. This satisfies the render.HTMLRender interface.

func (*Renderer) SetBranding

func (r *Renderer) SetBranding(b ResolvedBranding)

SetBranding stores the resolved branding config. Call once during initialization.

type ResolvedBranding

type ResolvedBranding struct {
	OrgName          string
	LogoURL          string
	PrimaryColor     string
	SecondaryColor   string
	BorderRadius     string
	SidebarColor     string
	SidebarTextColor string
}

ResolvedBranding holds the fully resolved branding values ready for template rendering. Fields remain empty when the consumer does not configure them.

func ResolveBranding

func ResolveBranding(orgName, logoURL, primaryColor, secondaryColor, borderRadius, sidebarColor, sidebarTextColor, logoServeURL string) ResolvedBranding

ResolveBranding applies precedence rules to produce a ResolvedBranding:

  • logoServeURL overrides logoURL when non-empty (served upload takes priority)
  • sidebarTextColor is used as-is when set; otherwise it is auto-derived from sidebarColor via WCAG luminance; if sidebarColor is also empty the field is left blank for the template to apply its own default.

type SessionValidator

type SessionValidator interface {
	// ValidateSession checks if a session ID is valid and returns the associated admin account.
	ValidateSession(sessionID string) (*models.AdminAccount, error)

	// GenerateCSRFToken creates a CSRF token bound to the session.
	GenerateCSRFToken(sessionID string) (string, error)

	// ValidateCSRFToken checks if the provided token matches the stored one for the session.
	ValidateCSRFToken(sessionID, token string) bool
}

SessionValidator is the interface used by GUI middleware to validate sessions and manage CSRF tokens. Implemented by admin.AccountService.

type TemplateData

type TemplateData struct {
	// Page metadata
	ActivePage string

	// Auth context (set by middleware)
	AdminUsername string
	AdminID       string

	// CSRF token (set by CSRF middleware)
	CSRFToken string

	// Flash messages
	FlashSuccess string
	FlashError   string

	// Login-specific fields
	Error    string // Login error message
	Username string // Pre-filled username on login error
	Redirect string // Post-login redirect URL

	// 2FA-specific fields
	TempToken   string // Temporary token for 2FA login verification
	TwoFAMethod string // "totp" or "email" — which 2FA method is required

	// Theme is the active UI theme: "light" or "dark".
	// Read from the gui_theme cookie via web.GetTheme(c).
	Theme string

	// Branding (auto-populated by Renderer from resolved config)
	OrgName          string
	LogoURL          string
	PrimaryColor     string
	SecondaryColor   string
	BorderRadius     string
	SidebarColor     string
	SidebarTextColor string

	// Page-specific data (each page can put arbitrary data here)
	Data interface{}
}

TemplateData is the standard data structure passed to all templates. Handlers populate specific fields; the renderer ensures defaults.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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