config

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2026 License: Apache-2.0, BSD-3-Clause, MIT Imports: 22 Imported by: 0

Documentation

Overview

Package config provides configuration sync for cluster mode Per AI.md PART 5 lines 5212-5310: Configuration Source of Truth (NON-NEGOTIABLE)

Index

Constants

View Source
const (
	// ProjectOrg is the organization name
	ProjectOrg = "apimgr"
	// ProjectName is the project name
	ProjectName = "search"
)

Variables

View Source
var (
	Version      = "dev"
	CommitID     = "unknown"
	BuildDate    = "unknown"
	OfficialSite = "https://scour.li" // Default, can be overridden via -ldflags
)

Build info - set via -ldflags at build time Per AI.md PART 26: LDFLAGS must include Version, CommitID, BuildDate, OfficialSite

Functions

func EnsureDirectories

func EnsureDirectories() error

EnsureDirectories creates all required directories if they don't exist Per AI.md PART 7: Server Startup Sequence - setup directories with proper permissions

func EnsureSensitiveFile

func EnsureSensitiveFile(path string) error

EnsureSensitiveFile ensures a file has proper sensitive permissions (0600) Per AI.md PART 7: Tor files, key files, config files

func EnsureSystemDirectories

func EnsureSystemDirectories(userName string) error

EnsureSystemDirectories creates system directories and sets ownership Per AI.md PART 8: Step 8b-d - Create directories while running as root This is called BEFORE privilege dropping when running as root

func GetAdminPath

func GetAdminPath() string

GetAdminPath returns the admin panel path Per AI.md PART 8: Configurable admin path, defaults to "admin"

func GetAllDomains

func GetAllDomains() []string

GetAllDomains returns all domains from DOMAIN env var Per AI.md PART 5: Used for CORS configuration and SSL certificates

func GetArch

func GetArch() string

GetArch returns the current architecture

func GetBackupDir

func GetBackupDir() string

GetBackupDir returns the OS-appropriate backup directory

func GetBinaryPath

func GetBinaryPath() string

GetBinaryPath returns the expected installation path for the binary

func GetCacheDir

func GetCacheDir() string

GetCacheDir returns the OS-appropriate cache directory

func GetColorMode

func GetColorMode() string

GetColorMode returns the color output mode Per AI.md PART 8: Priority: CLI flag > Config > NO_COLOR env > Auto-detect

func GetConfigDir

func GetConfigDir() string

GetConfigDir returns the OS-appropriate configuration directory

func GetConfigPath

func GetConfigPath() string

GetConfigPath returns the path to the configuration file

func GetCurrentGID

func GetCurrentGID() int

GetCurrentGID returns the current group ID

func GetCurrentUID

func GetCurrentUID() int

GetCurrentUID returns the current user ID

func GetDataDir

func GetDataDir() string

GetDataDir returns the OS-appropriate data directory

func GetDatabaseDir

func GetDatabaseDir() string

GetDatabaseDir returns the OS-appropriate database directory

func GetDatabaseDriver

func GetDatabaseDriver() string

GetDatabaseDriver returns the DATABASE_DRIVER environment variable Per AI.md PART 5: Database driver override

func GetDatabaseURL

func GetDatabaseURL() string

GetDatabaseURL returns the DATABASE_URL environment variable Per AI.md PART 5: Database connection string

func GetDirectoryPermissions

func GetDirectoryPermissions() os.FileMode

GetDirectoryPermissions returns the appropriate directory permissions Per AI.md PART 7: root: 0755, user: 0700

func GetDomain

func GetDomain() string

GetDomain returns the DOMAIN environment variable Per AI.md PART 5: DOMAIN env var for FQDN override (highest priority) Returns first domain if comma-separated list

func GetEmailTemplatesDir

func GetEmailTemplatesDir() string

GetEmailTemplatesDir returns the email templates directory

func GetFileOwnership

func GetFileOwnership(path string) (uid, gid int, err error)

GetFileOwnership returns the owner UID and GID of a file

func GetGeoIPDir

func GetGeoIPDir() string

GetGeoIPDir returns the OS-appropriate GeoIP database directory Per AI.md PART 4: Security DBs are under config/security/ (geoip, blocklists, cve, trivy)

func GetLogDir

func GetLogDir() string

GetLogDir returns the OS-appropriate log directory

func GetOS

func GetOS() string

GetOS returns the current operating system

func GetPIDFile

func GetPIDFile() string

GetPIDFile returns the OS-appropriate PID file path

func GetRandomPort

func GetRandomPort() int

GetRandomPort returns a random port in the 64xxx range (64000-64999) Per spec, port 0 means random port in 64xxx range to avoid conflicts

func GetSSLDir

func GetSSLDir() string

GetSSLDir returns the OS-appropriate SSL certificates directory Per AI.md PART 4: SSL is under config directory with letsencrypt/ and local/ subdirs

func GetSecurityDir

func GetSecurityDir() string

GetSecurityDir returns the OS-appropriate security directory Per AI.md PART 4: Contains geoip/, blocklists/, cve/, trivy/

func GetSensitiveDirectoryPermissions

func GetSensitiveDirectoryPermissions() os.FileMode

GetSensitiveDirectoryPermissions returns permissions for sensitive directories Per AI.md PART 7: Tor dirs, SSL dirs always 0700

func GetSensitiveFilePermissions

func GetSensitiveFilePermissions() os.FileMode

GetSensitiveFilePermissions returns permissions for sensitive files Per AI.md PART 7: keys, config files 0600

func GetServiceFile

func GetServiceFile() string

GetServiceFile returns the OS-appropriate service file path

func GetTemplatesDir

func GetTemplatesDir() string

GetTemplatesDir returns the email templates directory (customizable)

func GetTorDir

func GetTorDir() string

GetTorDir returns the OS-appropriate Tor data directory

func GetTorKeysDir

func GetTorKeysDir() string

GetTorKeysDir returns the directory for Tor hidden service keys

func GetWebDataDir

func GetWebDataDir() string

GetWebDataDir returns the web data directory for custom assets

func GetWellKnownDir

func GetWellKnownDir() string

GetWellKnownDir returns the .well-known directory for custom files

func IsColorEnabled

func IsColorEnabled() bool

IsColorEnabled returns whether color output should be enabled Per AI.md PART 8: Honor NO_COLOR standard

func IsFalsy

func IsFalsy(s string) bool

IsFalsy returns true if the string is a falsy value. Returns false for empty, invalid, or truthy values (no error). Per AI.md PART 4: Boolean Handling (NON-NEGOTIABLE)

func IsPrivileged

func IsPrivileged() bool

IsPrivileged returns true if running with elevated privileges (Unix) Per AI.md PART 4: Check EUID for root/sudo

func IsRunningInContainer

func IsRunningInContainer() bool

IsRunningInContainer returns true if running inside a container

func IsTorAvailable

func IsTorAvailable() bool

IsTorAvailable is an exported version of isTorAvailable Per AI.md PART 29: Tor auto-enabled if tor binary installed

func IsTruthy

func IsTruthy(s string) bool

IsTruthy returns true if the string is a truthy value. Returns false for empty, invalid, or falsy values (no error). Per AI.md PART 4: Boolean Handling (NON-NEGOTIABLE)

func IsValidEmail

func IsValidEmail(email string) bool

IsValidEmail validates an email address format

func IsValidHost

func IsValidHost(host string, devMode bool, projectName string) bool

IsValidHost validates that a hostname is a valid FQDN. Per AI.md specification: - devMode: if true, allows dev-only TLDs (.local, .test, localhost, etc.) - projectName: if non-empty, allows project-specific TLDs (e.g., .jokes) in dev mode - IP addresses are ALWAYS rejected - Uses golang.org/x/net/publicsuffix for proper TLD validation

func IsValidPort

func IsValidPort(port int) bool

IsValidPort validates a port number

func IsValidSSLHost

func IsValidSSLHost(host string) bool

IsValidSSLHost validates a host for SSL certificate requests. SSL always requires production-valid host (no dev TLDs). .onion addresses cannot use Let's Encrypt (Tor provides encryption).

func LogValidationWarnings

func LogValidationWarnings(warnings []ValidationWarning)

LogValidationWarnings prints validation warnings to stdout Per AI.md PART 12: Warn and use defaults, not error

func MustParseBool

func MustParseBool(s string, defaultVal bool) bool

MustParseBool parses a string into a boolean, panics on invalid value. Use only during initialization where invalid config should halt startup. Per AI.md PART 4: Boolean Handling (NON-NEGOTIABLE)

func ParseBool

func ParseBool(s string, defaultVal bool) (bool, error)

ParseBool parses a string into a boolean using truthy/falsy values. Returns the parsed value and nil on success. Returns false and an error for invalid values. Empty string returns the provided default value. Per AI.md PART 4: Boolean Handling (NON-NEGOTIABLE)

func ParseBoolDefault

func ParseBoolDefault(val string, defaultVal bool) bool

ParseBoolDefault parses boolean with a default value Calls ParseBool from bool.go

func ParseDuration

func ParseDuration(val string) (int, error)

ParseDuration parses a duration string (e.g., "30d", "24h", "30m", "60s")

func ParseFormBool

func ParseFormBool(val string) bool

ParseFormBool parses boolean from HTML form values Per AI.md PART 4: Extended boolean handling HTML checkboxes send "on" when checked, nothing when unchecked HTML radio buttons send their value attribute

func ParseInt

func ParseInt(val string, defaultVal int) int

ParseInt parses an integer from string with default

func ResolvePort

func ResolvePort(port int) int

ResolvePort resolves the port, using random port if 0

func SetAdminPathOverride

func SetAdminPathOverride(path string)

SetAdminPathOverride sets a CLI override for the admin panel path Per AI.md PART 8: --admin-path flag to customize admin panel URL

func SetBackupDirOverride

func SetBackupDirOverride(dir string)

SetBackupDirOverride sets a CLI override for the backup directory

func SetCacheDirOverride

func SetCacheDirOverride(dir string)

SetCacheDirOverride sets a CLI override for the cache directory

func SetColorMode

func SetColorMode(mode string)

SetColorMode sets the color output mode Per AI.md PART 8: --color {always|never|auto} flag Priority: CLI flag > Config > NO_COLOR env > Auto-detect

func SetConfigDirOverride

func SetConfigDirOverride(dir string)

SetConfigDirOverride sets a CLI override for the config directory

func SetDataDirOverride

func SetDataDirOverride(dir string)

SetDataDirOverride sets a CLI override for the data directory

func SetFileOwnership

func SetFileOwnership(path string, uid, gid int) error

SetFileOwnership sets ownership for a specific file Per AI.md PART 7: Tor files, key files owned by app user

func SetLogDirOverride

func SetLogDirOverride(dir string)

SetLogDirOverride sets a CLI override for the log directory

func SetPIDFileOverride

func SetPIDFileOverride(path string)

SetPIDFileOverride sets a CLI override for the PID file path

func TrimmedFormValue

func TrimmedFormValue(r *http.Request, key string) string

TrimmedFormValue returns a form value with leading and trailing whitespace stripped Per AI.md: ALL input fields must have whitespace trimmed

func TrimmedPostFormValue

func TrimmedPostFormValue(r *http.Request, key string) string

TrimmedPostFormValue returns a POST form value with whitespace stripped

Types

type AdminConfig

type AdminConfig struct {
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	Token    string `yaml:"token"`
	APIToken string `yaml:"api_token"`
	Email    string `yaml:"email"`
	Enabled  bool   `yaml:"enabled"`
}

AdminConfig represents admin configuration

type Announcement

type Announcement struct {
	ID          string `yaml:"id"`
	Type        string `yaml:"type"` // warning, info, error, success
	Title       string `yaml:"title"`
	Message     string `yaml:"message"`
	Start       string `yaml:"start"`       // ISO 8601 datetime
	End         string `yaml:"end"`         // ISO 8601 datetime
	Dismissible bool   `yaml:"dismissible"` // User can dismiss
}

Announcement represents a single announcement message

type AnnouncementsConfig

type AnnouncementsConfig struct {
	Enabled  bool           `yaml:"enabled"`
	Messages []Announcement `yaml:"messages"`
}

AnnouncementsConfig represents announcement settings (per AI.md)

func (*AnnouncementsConfig) ActiveAnnouncements

func (c *AnnouncementsConfig) ActiveAnnouncements() []Announcement

ActiveAnnouncements returns announcements that are currently active

type AuthConfig

type AuthConfig struct {
	OIDC []OIDCProviderConfig `yaml:"oidc"`
	LDAP []LDAPConfig         `yaml:"ldap"`
}

AuthConfig represents external authentication configuration per AI.md PART 31

type BackupConfig

type BackupConfig struct {
	// Encryption configuration
	Encryption BackupEncryptionConfig `yaml:"encryption"`
	// Retention policy
	Retention BackupRetentionConfig `yaml:"retention"`
}

BackupConfig represents backup configuration Per AI.md PART 22: Backup & Restore configuration

type BackupEncryptionConfig

type BackupEncryptionConfig struct {
	Enabled bool   `yaml:"enabled"` // true if password was set during setup
	Hint    string `yaml:"hint"`    // Optional password hint (stored, NOT the password)
}

BackupEncryptionConfig represents backup encryption settings Per AI.md PART 22: Password is NEVER stored - derived on-demand

type BackupRetentionConfig

type BackupRetentionConfig struct {
	MaxBackups  int `yaml:"max_backups"`  // Daily full backups to keep (default: 1)
	KeepWeekly  int `yaml:"keep_weekly"`  // Weekly backups (Sunday) to keep (0 = disabled)
	KeepMonthly int `yaml:"keep_monthly"` // Monthly backups (1st) to keep (0 = disabled)
	KeepYearly  int `yaml:"keep_yearly"`  // Yearly backups (Jan 1st) to keep (0 = disabled)
}

BackupRetentionConfig represents backup retention policy Per AI.md PART 22: Retention settings

type BangConfig

type BangConfig struct {
	Shortcut    string   `yaml:"shortcut"`
	Name        string   `yaml:"name"`
	URL         string   `yaml:"url"`
	Category    string   `yaml:"category"`
	Description string   `yaml:"description,omitempty"`
	Aliases     []string `yaml:"aliases,omitempty"`
}

BangConfig represents a custom bang configuration

type BangsConfig

type BangsConfig struct {
	Enabled       bool         `yaml:"enabled"`
	ProxyRequests bool         `yaml:"proxy_requests"`
	Custom        []BangConfig `yaml:"custom"`
}

BangsConfig represents bang configuration

type BrandingConfig

type BrandingConfig struct {
	Title        string `yaml:"title"`       // Per PART 13: project.name source
	Tagline      string `yaml:"tagline"`     // Per PART 13: project.tagline source
	Description  string `yaml:"description"` // Per PART 13: project.description source
	LogoURL      string `yaml:"logo_url"`
	FaviconURL   string `yaml:"favicon_url"`
	FooterText   string `yaml:"footer_text"`
	Theme        string `yaml:"theme"`
	PrimaryColor string `yaml:"primary_color"`
}

BrandingConfig represents branding configuration Per AI.md PART 13/16: branding fields for healthz project info

type CacheConfig

type CacheConfig struct {
	// Type: none (disabled), memory (default), valkey, redis
	// IMPORTANT: Use valkey/redis for cluster or mixed mode deployments
	Type string `yaml:"type"`

	// Connection: Use EITHER url OR host/port/password (not both)
	// url takes precedence if both are specified
	// Format: redis://user:password@host:port/db or valkey://...
	URL string `yaml:"url"`

	// Individual connection settings (alternative to url)
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`

	// Connection pool settings
	PoolSize int    `yaml:"pool_size"`
	MinIdle  int    `yaml:"min_idle"`
	Timeout  string `yaml:"timeout"` // Connection timeout (e.g., "5s")

	// Key prefix to avoid collisions (use unique prefix per app)
	Prefix string `yaml:"prefix"`

	// Default TTL in seconds
	TTL int `yaml:"ttl"`

	// Cluster settings (when using Valkey/Redis Cluster)
	Cluster      bool     `yaml:"cluster"`
	ClusterNodes []string `yaml:"cluster_nodes"` // e.g., ["node1:6379", "node2:6379"]
}

CacheConfig represents cache configuration per AI.md PART 18 EVERY application MUST support Valkey/Redis for clustering

type ComplianceConfig

type ComplianceConfig struct {
	Enabled bool `yaml:"enabled"` // HIPAA, SOC2, etc. compliance mode
}

ComplianceConfig represents compliance mode configuration Per AI.md PART 22: When enabled, backup encryption is REQUIRED

type CompressionConfig

type CompressionConfig struct {
	Enabled      bool     `yaml:"enabled"`
	Level        int      `yaml:"level"`         // 1-9, higher = more compression, more CPU
	MinSize      int      `yaml:"min_size"`      // Minimum response size to compress (bytes)
	MimeTypes    []string `yaml:"mime_types"`    // MIME types to compress
	Gzip         bool     `yaml:"gzip"`          // Enable gzip compression
	Brotli       bool     `yaml:"brotli"`        // Enable Brotli compression
	DisableProxy bool     `yaml:"disable_proxy"` // Disable compression for proxied requests
}

CompressionConfig represents HTTP response compression settings

type Config

type Config struct {
	Server  ServerConfig            `yaml:"server"`
	Search  SearchConfig            `yaml:"search"`
	Engines map[string]EngineConfig `yaml:"engines"`
	// contains filtered or unexported fields
}

Config represents the complete application configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a default configuration

func Initialize

func Initialize() (*Config, error)

Initialize initializes the configuration system Per AI.md PART 3: Environment variables only work on first run

func Load

func Load(path string) (*Config, error)

Load loads configuration from file Per AI.md PART 5: Unknown config keys are ERRORS, not ignored

func LoadOrCreate

func LoadOrCreate(path string) (*Config, bool, error)

LoadOrCreate loads configuration from file or creates default if not exists Per AI.md: If server.yaml found, auto-migrate to server.yml on startup

func (*Config) ApplyEnv

func (c *Config) ApplyEnv(env *EnvConfig)

ApplyEnv applies environment variable overrides to config

func (*Config) Get

func (c *Config) Get() ServerConfig

Get returns a read-locked copy of server config

func (*Config) GetAddress

func (c *Config) GetAddress() string

GetAddress returns the full bind address

func (*Config) GetEncryptionKey

func (c *Config) GetEncryptionKey() []byte

GetEncryptionKey returns a 32-byte encryption key derived from the SecretKey Uses SHA256 to ensure consistent 32-byte length for AES-256

func (*Config) GetPath

func (c *Config) GetPath() string

GetPath returns the config file path

func (*Config) IsDebug

func (c *Config) IsDebug() bool

IsDebug returns true if debug mode is enabled via DEBUG=true environment variable or if server mode is set to "debug"

func (*Config) IsDevelopment

func (c *Config) IsDevelopment() bool

IsDevelopment returns true if in development mode

func (*Config) IsFirstRun

func (c *Config) IsFirstRun() bool

IsFirstRun returns true if this is the first run (config was just created) Per AI.md PART 14: First run shows setup token for admin creation

func (*Config) IsProduction

func (c *Config) IsProduction() bool

IsProduction returns true if in production mode

func (*Config) Reload

func (c *Config) Reload() error

Reload reloads the configuration from the original file Note: Some settings (port, address) may require restart to take effect Per AI.md PART 5: Unknown config keys are ERRORS, not ignored

func (*Config) Save

func (c *Config) Save(path string) error

Save saves configuration to file with comments per AI.md config-rules.md Comments are placed ABOVE each setting, never inline

func (*Config) SetPath

func (c *Config) SetPath(path string)

SetPath sets the config file path for reload

func (*Config) Update

func (c *Config) Update(fn func(*ServerConfig))

Update allows thread-safe config updates

func (*Config) ValidateAndApplyDefaults

func (c *Config) ValidateAndApplyDefaults() []ValidationWarning

ValidateAndApplyDefaults validates configuration and applies defaults Per AI.md PART 12: Config validation should warn and use defaults, NOT error Returns list of warnings (errors are logged but defaults are applied)

type ConfigSync

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

ConfigSync handles syncing configuration between database and server.yml Per AI.md PART 5: - Single Instance (SQLite): server.yml is source of truth - Cluster Mode (Remote DB): Database is source of truth, server.yml is cache/backup

func NewConfigSync

func NewConfigSync(db *sql.DB, config *Config, configPath string, isCluster bool) *ConfigSync

NewConfigSync creates a new config sync manager

func (*ConfigSync) IsClusterMode

func (cs *ConfigSync) IsClusterMode() bool

IsClusterMode returns true if running in cluster mode

func (*ConfigSync) LastSync

func (cs *ConfigSync) LastSync() time.Time

LastSync returns the last sync time

func (*ConfigSync) LoadFromSource

func (cs *ConfigSync) LoadFromSource() error

LoadFromSource loads config from the appropriate source Per AI.md PART 5: Cluster mode reads from database, standalone from server.yml

func (*ConfigSync) SaveSetting

func (cs *ConfigSync) SaveSetting(key string, value interface{}) error

SaveSetting saves a config setting to the appropriate source of truth Per AI.md PART 5 lines 5263-5310: server.yml as Cache/Backup (NON-NEGOTIABLE)

func (*ConfigSync) StartPeriodicSync

func (cs *ConfigSync) StartPeriodicSync(interval time.Duration)

StartPeriodicSync starts a background goroutine to sync config periodically Per AI.md PART 5 lines 5308-5310: Sync periodically (every 5 minutes)

func (*ConfigSync) SyncToLocal

func (cs *ConfigSync) SyncToLocal() error

SyncToLocal syncs database config to local server.yml Per AI.md PART 5 lines 5291-5310: Config Sync (Database → server.yml)

type ContactConfig

type ContactConfig struct {
	Enabled bool   `yaml:"enabled"`
	Email   string `yaml:"email"`
}

ContactConfig represents contact page configuration

type CookieConsentConfig

type CookieConsentConfig struct {
	Enabled    bool   `yaml:"enabled"`
	Message    string `yaml:"message"`
	PolicyURL  string `yaml:"policy_url"`
	TrackingID string `yaml:"tracking_id"` // Google Analytics ID
}

CookieConsentConfig represents cookie consent popup settings

type CryptoWidgetConfig

type CryptoWidgetConfig struct {
	Enabled      bool     `yaml:"enabled"`
	DefaultCoins []string `yaml:"default_coins"`
	Currency     string   `yaml:"currency"` // "usd", "eur", etc.
}

CryptoWidgetConfig holds crypto widget configuration

type DNS01Config

type DNS01Config struct {
	Provider             string `yaml:"provider"`              // Provider identifier (cloudflare, route53, etc.)
	CredentialsEncrypted string `yaml:"credentials_encrypted"` // AES-256-GCM encrypted JSON
	ValidatedAt          string `yaml:"validated_at"`          // Timestamp of last successful validation
}

DNS01Config represents DNS-01 ACME challenge configuration Per AI.md: ALL DNS providers are supported via go-acme/lego

type EmailConfig

type EmailConfig struct {
	// Enabled is auto-set based on SMTP availability (no manual toggle)
	Enabled bool            `yaml:"-"` // Computed, not stored
	SMTP    SMTPConfig      `yaml:"smtp"`
	From    EmailFromConfig `yaml:"from"`
}

EmailConfig represents email/SMTP configuration Per AI.md PART 18: Nested SMTP and From blocks

type EmailFromConfig

type EmailFromConfig struct {
	// Default: app title
	Name string `yaml:"name"`
	// Default: no-reply@{fqdn}
	Email string `yaml:"email"`
}

EmailFromConfig represents the from address configuration Per AI.md PART 18: From name and email defaults

type EngineConfig

type EngineConfig struct {
	Enabled    bool     `yaml:"enabled"`
	Priority   int      `yaml:"priority"`
	Categories []string `yaml:"categories"`
	Timeout    int      `yaml:"timeout"`
	Weight     float64  `yaml:"weight"`
	APIKey     string   `yaml:"api_key,omitempty"`
}

EngineConfig represents search engine configuration

type EnvConfig

type EnvConfig struct {
	// Core configuration
	SettingsPath string
	Debug        bool
	Secret       string
	BindAddress  string
	InstanceName string
	Autocomplete string
	BaseURL      string

	// Per AI.md PART 5: DOMAIN env var for FQDN override
	Domain string

	// Per AI.md PART 5: DATABASE_DRIVER env var
	DatabaseDriver string
	DatabaseURL    string

	// Image proxy
	ImageProxyURL string
	ImageProxyKey string

	// Search-specific
	Port      string
	Mode      string
	DataDir   string
	ConfigDir string
	LogDir    string

	// SMTP - Per AI.md PART 18: SMTP_* env vars override config file
	SMTPHost      string
	SMTPPort      int
	SMTPUsername  string
	SMTPPassword  string
	SMTPTLS       string
	SMTPFromName  string
	SMTPFromEmail string

	// Engines
	EnableGoogle     bool
	EnableDuckDuckGo bool
	EnableBing       bool
}

EnvConfig loads configuration from environment variables

func LoadFromEnv

func LoadFromEnv() *EnvConfig

LoadFromEnv loads configuration from environment variables

func (*EnvConfig) GetMode

func (e *EnvConfig) GetMode() string

GetMode returns the application mode

func (*EnvConfig) IsDevelopment

func (e *EnvConfig) IsDevelopment() bool

IsDevelopment returns true if in development mode

func (*EnvConfig) IsProduction

func (e *EnvConfig) IsProduction() bool

IsProduction returns true if in production mode

type GeoIPConfig

type GeoIPConfig struct {
	Enabled          bool     `yaml:"enabled"`
	Dir              string   `yaml:"dir"`               // Directory for MMDB files
	Update           string   `yaml:"update"`            // never, daily, weekly, monthly
	DenyCountries    []string `yaml:"deny_countries"`    // Countries to block (ISO 3166-1 alpha-2)
	AllowedCountries []string `yaml:"allowed_countries"` // If set, only these countries allowed
	// Database toggles per AI.md PART 20
	ASN     bool `yaml:"asn"`     // Enable ASN lookups
	Country bool `yaml:"country"` // Enable country lookups
	City    bool `yaml:"city"`    // Enable city lookups (larger download)
	WHOIS   bool `yaml:"whois"`   // Enable WHOIS lookups
}

GeoIPConfig represents GeoIP configuration (uses MMDB from sapics/ip-location-db) Per AI.md PART 20: GeoIP configuration

type I18nConfig

type I18nConfig struct {
	Enabled            bool     `yaml:"enabled"`
	DefaultLanguage    string   `yaml:"default_language"`    // BCP 47 language tag (e.g., en, en-US, de)
	SupportedLanguages []string `yaml:"supported_languages"` // List of supported languages
	AutoDetect         bool     `yaml:"auto_detect"`         // Detect from Accept-Language header
	ShowSelector       bool     `yaml:"show_selector"`       // Show language selector in UI
	RTLLanguages       []string `yaml:"rtl_languages"`       // Right-to-left languages (ar, he, etc.)
	TranslationsDir    string   `yaml:"translations_dir"`    // Directory for translation files
	FallbackLanguage   string   `yaml:"fallback_language"`   // Fallback if requested language not available
}

I18nConfig represents internationalization configuration

type ImageProxyConfig

type ImageProxyConfig struct {
	Enabled bool   `yaml:"enabled"`
	URL     string `yaml:"url"`
	Key     string `yaml:"key"`
}

ImageProxyConfig represents image proxy configuration

type LDAPConfig

type LDAPConfig struct {
	ID            string `yaml:"id"`
	Name          string `yaml:"name"`
	Enabled       bool   `yaml:"enabled"`
	Host          string `yaml:"host"`
	Port          int    `yaml:"port"`
	UseTLS        bool   `yaml:"use_tls"`
	SkipTLSVerify bool   `yaml:"skip_tls_verify"`
	BindDN        string `yaml:"bind_dn"`
	BindPassword  string `yaml:"bind_password"`
	BaseDN        string `yaml:"base_dn"`
	UserFilter    string `yaml:"user_filter"`
	UsernameAttr  string `yaml:"username_attr"`
	EmailAttr     string `yaml:"email_attr"`
	// Admin group mapping per AI.md PART 31
	AdminGroups     []string `yaml:"admin_groups"`
	GroupFilter     string   `yaml:"group_filter"`
	GroupMemberAttr string   `yaml:"group_member_attr"`
}

LDAPConfig represents LDAP authentication configuration

type LimitsConfig

type LimitsConfig struct {
	MaxBodySize  string `yaml:"max_body_size"` // Maximum request body size (e.g., "10MB")
	ReadTimeout  string `yaml:"read_timeout"`  // HTTP read timeout (e.g., "30s")
	WriteTimeout string `yaml:"write_timeout"` // HTTP write timeout (e.g., "30s")
	IdleTimeout  string `yaml:"idle_timeout"`  // HTTP idle connection timeout (e.g., "120s")
}

LimitsConfig represents request limits configuration per AI.md PART 18 Protects against DoS attacks (Slowloris, large uploads)

func (*LimitsConfig) GetMaxBodySizeBytes

func (l *LimitsConfig) GetMaxBodySizeBytes() int64

GetMaxBodySizeBytes parses MaxBodySize and returns bytes

type LogsConfig

type LogsConfig struct {
	Level  string `yaml:"level"`
	File   string `yaml:"file"`
	Format string `yaml:"format"`
	Access struct {
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"access"`
	Server struct {
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"server"`
	Error struct {
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"error"`
	Audit struct {
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"audit"`
	Security struct {
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"security"`
	Debug struct {
		Enabled  bool   `yaml:"enabled"`
		Filename string `yaml:"filename"`
		Format   string `yaml:"format"`
		Custom   string `yaml:"custom"`
		Rotate   string `yaml:"rotate"`
		Keep     string `yaml:"keep"`
	} `yaml:"debug"`
}

LogsConfig represents logging configuration

type MetricsConfig

type MetricsConfig struct {
	Enabled         bool      `yaml:"enabled"`
	Endpoint        string    `yaml:"endpoint"`         // Endpoint path (default: /metrics)
	IncludeSystem   bool      `yaml:"include_system"`   // Include system metrics (CPU, memory, disk)
	IncludeRuntime  bool      `yaml:"include_runtime"`  // Include Go runtime metrics
	Token           string    `yaml:"token"`            // Bearer token for authentication (empty = no auth)
	DurationBuckets []float64 `yaml:"duration_buckets"` // Histogram buckets for request duration (seconds)
	SizeBuckets     []float64 `yaml:"size_buckets"`     // Histogram buckets for request size (bytes)
}

MetricsConfig represents Prometheus-compatible metrics configuration Per AI.md PART 21: Metrics configuration

type NewsWidgetConfig

type NewsWidgetConfig struct {
	Enabled  bool     `yaml:"enabled"`
	Sources  []string `yaml:"sources"` // RSS feed URLs
	MaxItems int      `yaml:"max_items"`
}

NewsWidgetConfig holds news widget configuration

type OIDCProviderConfig

type OIDCProviderConfig struct {
	ID           string   `yaml:"id"`
	Name         string   `yaml:"name"`
	Enabled      bool     `yaml:"enabled"`
	Issuer       string   `yaml:"issuer"`
	ClientID     string   `yaml:"client_id"`
	ClientSecret string   `yaml:"client_secret"`
	RedirectURL  string   `yaml:"redirect_url"`
	Scopes       []string `yaml:"scopes"`
	// Admin group mapping per AI.md PART 31
	AdminGroups []string `yaml:"admin_groups"`
	GroupsClaim string   `yaml:"groups_claim"`
	AutoCreate  bool     `yaml:"auto_create"`
}

OIDCProviderConfig represents an OIDC provider configuration

type OpenGraphConfig

type OpenGraphConfig struct {
	Enabled     bool   `yaml:"enabled"`
	Type        string `yaml:"type"`
	SiteName    string `yaml:"site_name"`
	Image       string `yaml:"image"`
	Description string `yaml:"description"`
}

OpenGraphConfig represents OpenGraph meta tags

type OpenSearchConfig

type OpenSearchConfig struct {
	Enabled     bool   `yaml:"enabled"`
	ShortName   string `yaml:"short_name"`
	Description string `yaml:"description"`
	Contact     string `yaml:"contact"`
	Tags        string `yaml:"tags"`
	LongName    string `yaml:"long_name"`
	Image       string `yaml:"image"`
}

OpenSearchConfig represents OpenSearch configuration

type PagesConfig

type PagesConfig struct {
	About struct {
		Enabled bool   `yaml:"enabled"`
		Content string `yaml:"content"`
	} `yaml:"about"`
	Privacy struct {
		Enabled bool   `yaml:"enabled"`
		Content string `yaml:"content"`
	} `yaml:"privacy"`
	Contact struct {
		Enabled bool   `yaml:"enabled"`
		Email   string `yaml:"email"`
	} `yaml:"contact"`
	Help struct {
		Enabled bool   `yaml:"enabled"`
		Content string `yaml:"content"`
	} `yaml:"help"`
	Terms struct {
		Enabled bool   `yaml:"enabled"`
		Content string `yaml:"content"`
	} `yaml:"terms"`
}

PagesConfig represents standard pages configuration

type RSSWidgetConfig

type RSSWidgetConfig struct {
	Enabled  bool `yaml:"enabled"`
	MaxFeeds int  `yaml:"max_feeds"`
	MaxItems int  `yaml:"max_items"`
}

RSSWidgetConfig holds RSS widget configuration

type RateLimitConfig

type RateLimitConfig struct {
	Enabled           bool     `yaml:"enabled"`
	RequestsPerMinute int      `yaml:"requests_per_minute"`
	RequestsPerHour   int      `yaml:"requests_per_hour"`
	RequestsPerDay    int      `yaml:"requests_per_day"`
	BurstSize         int      `yaml:"burst_size"`
	ByIP              bool     `yaml:"by_ip"`
	ByUser            bool     `yaml:"by_user"`
	Whitelist         []string `yaml:"whitelist"`
	Blacklist         []string `yaml:"blacklist"`
}

RateLimitConfig represents rate limiting configuration

type SEOConfig

type SEOConfig struct {
	Enabled            bool              `yaml:"enabled"`
	DefaultTitle       string            `yaml:"default_title"`
	TitleSeparator     string            `yaml:"title_separator"`
	DefaultDescription string            `yaml:"default_description"`
	Keywords           []string          `yaml:"keywords"`
	MetaTags           map[string]string `yaml:"meta_tags"`
	OpenGraph          OpenGraphConfig   `yaml:"opengraph"`
	Twitter            TwitterConfig     `yaml:"twitter"`
	Canonical          bool              `yaml:"canonical"` // Include canonical URLs
	NoIndex            bool              `yaml:"noindex"`   // Set noindex on search results
	Sitemap            bool              `yaml:"sitemap"`   // Generate sitemap.xml
}

SEOConfig represents SEO configuration

type SMTPConfig

type SMTPConfig struct {
	// If empty: autodetect local SMTP on startup
	// If set: test connection on startup
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Username string `yaml:"username"`
	Password string `yaml:"password"`
	// TLS mode: auto, starttls, tls, none
	TLS string `yaml:"tls"`
}

SMTPConfig represents SMTP server configuration Per AI.md PART 18: SMTP configuration with env var overrides

type SSLConfig

type SSLConfig struct {
	Enabled     bool   `yaml:"enabled"`
	AutoTLS     bool   `yaml:"auto_tls"`
	CertFile    string `yaml:"cert_file"`
	KeyFile     string `yaml:"key_file"`
	LetsEncrypt struct {
		Enabled   bool     `yaml:"enabled"`
		Email     string   `yaml:"email"`
		Domains   []string `yaml:"domains"`
		Staging   bool     `yaml:"staging"`
		Challenge string   `yaml:"challenge"` // http-01, tls-alpn-01, dns-01
	} `yaml:"letsencrypt"`
	// DNS-01 provider configuration per AI.md PART 17
	DNS01 DNS01Config `yaml:"dns01"`
}

SSLConfig represents SSL/TLS configuration

type SchedulerConfig

type SchedulerConfig struct {
	// Timezone for scheduled tasks (default: America/New_York)
	Timezone string `yaml:"timezone"`
	// CatchUpWindow: run missed tasks if within this duration (default: 1h)
	CatchUpWindow string `yaml:"catch_up_window"`
	// Task-specific configuration (only skippable tasks can be disabled)
	Tasks SchedulerTasksConfig `yaml:"tasks"`
}

SchedulerConfig represents scheduler configuration per AI.md PART 19 Note: Scheduler is ALWAYS RUNNING - no enable/disable option for the scheduler itself

type SchedulerTasksConfig

type SchedulerTasksConfig struct {
	// Daily backup at 02:00 (skippable)
	BackupDaily TaskConfig `yaml:"backup_daily"`
	// Hourly incremental backup (skippable, disabled by default)
	BackupHourly TaskConfig `yaml:"backup_hourly"`
	// GeoIP database update (skippable)
	GeoIPUpdate TaskConfig `yaml:"geoip_update"`
	// Blocklist update (skippable)
	BlocklistUpdate TaskConfig `yaml:"blocklist_update"`
	// CVE database update (skippable)
	CVEUpdate TaskConfig `yaml:"cve_update"`
}

SchedulerTasksConfig represents per-task configuration

type SearchConfig

type SearchConfig struct {
	SafeSearch        int              `yaml:"safe_search"`
	Autocomplete      string           `yaml:"autocomplete"`
	DefaultLang       string           `yaml:"default_lang"`
	DefaultCategories []string         `yaml:"default_categories"`
	ResultsPerPage    int              `yaml:"results_per_page"`
	Timeout           int              `yaml:"timeout"`
	MaxConcurrent     int              `yaml:"max_concurrent"`
	Bangs             BangsConfig      `yaml:"bangs"`
	OpenSearch        OpenSearchConfig `yaml:"opensearch"`
	Widgets           WidgetsConfig    `yaml:"widgets"`
}

SearchConfig represents search configuration

type SecurityConfig

type SecurityConfig struct {
	// CORS
	CORS struct {
		Enabled          bool     `yaml:"enabled"`
		AllowedOrigins   []string `yaml:"allowed_origins"`
		AllowedMethods   []string `yaml:"allowed_methods"`
		AllowedHeaders   []string `yaml:"allowed_headers"`
		AllowCredentials bool     `yaml:"allow_credentials"`
		MaxAge           int      `yaml:"max_age"`
	} `yaml:"cors"`
	// CSRF
	CSRF struct {
		Enabled    bool   `yaml:"enabled"`
		CookieName string `yaml:"cookie_name"`
		HeaderName string `yaml:"header_name"`
		FieldName  string `yaml:"field_name"`
	} `yaml:"csrf"`
	// Headers
	Headers struct {
		XFrameOptions         string `yaml:"x_frame_options"`
		XContentTypeOptions   string `yaml:"x_content_type_options"`
		XXSSProtection        string `yaml:"x_xss_protection"`
		ReferrerPolicy        string `yaml:"referrer_policy"`
		ContentSecurityPolicy string `yaml:"content_security_policy"`
		PermissionsPolicy     string `yaml:"permissions_policy"`
	} `yaml:"headers"`
	// Trusted Proxies
	TrustedProxies []string `yaml:"trusted_proxies"`
}

SecurityConfig represents security configuration

type ServerConfig

type ServerConfig struct {
	// Core settings
	Title       string `yaml:"title"`
	Description string `yaml:"description"`
	Port        int    `yaml:"port"`       // HTTP port (or single port if HTTPSPort not set)
	HTTPSPort   int    `yaml:"https_port"` // HTTPS port for dual port mode (optional)
	Address     string `yaml:"address"`
	Mode        string `yaml:"mode"`
	SecretKey   string `yaml:"secret_key"`
	BaseURL     string `yaml:"base_url"`

	// SSL/TLS
	SSL SSLConfig `yaml:"ssl"`

	// Admin
	Admin AdminConfig `yaml:"admin"`

	// Branding
	Branding BrandingConfig `yaml:"branding"`

	// Rate Limiting
	RateLimit RateLimitConfig `yaml:"rate_limit"`

	// Session
	Session SessionConfig `yaml:"session"`

	// Logs
	Logs LogsConfig `yaml:"logs"`

	// Tor
	Tor TorConfig `yaml:"tor"`

	// Email
	Email EmailConfig `yaml:"email"`

	// Security
	Security SecurityConfig `yaml:"security"`

	// External Auth (OIDC/LDAP) per AI.md PART 31
	Auth AuthConfig `yaml:"auth"`

	// Users
	Users UsersConfig `yaml:"users"`

	// Pages
	Pages PagesConfig `yaml:"pages"`

	// Web (robots.txt, security.txt)
	Web WebConfig `yaml:"web"`

	// Scheduler
	Scheduler SchedulerConfig `yaml:"scheduler"`

	// Cache - per AI.md PART 18
	Cache CacheConfig `yaml:"cache"`

	// GeoIP
	GeoIP GeoIPConfig `yaml:"geoip"`

	// Metrics
	Metrics MetricsConfig `yaml:"metrics"`

	// Image Proxy
	ImageProxy ImageProxyConfig `yaml:"image_proxy"`

	// Contact
	Contact ContactConfig `yaml:"contact"`

	// SEO
	SEO SEOConfig `yaml:"seo"`

	// Compression
	Compression CompressionConfig `yaml:"compression"`

	// Request Limits per AI.md PART 18
	Limits LimitsConfig `yaml:"limits"`

	// I18n (Internationalization)
	I18n I18nConfig `yaml:"i18n"`

	// Maintenance mode - when enabled, shows maintenance page to all users
	MaintenanceMode bool `yaml:"maintenance_mode"`

	// Backup configuration per AI.md PART 22
	Backup BackupConfig `yaml:"backup"`

	// Compliance configuration per AI.md PART 22
	Compliance ComplianceConfig `yaml:"compliance"`
}

ServerConfig represents server configuration

func (*ServerConfig) GetHTTPPort

func (c *ServerConfig) GetHTTPPort() int

GetHTTPPort returns the HTTP port, resolving random if needed

func (*ServerConfig) GetHTTPSPort

func (c *ServerConfig) GetHTTPSPort() int

GetHTTPSPort returns the HTTPS port, resolving random if needed

func (*ServerConfig) IsDualPortMode

func (c *ServerConfig) IsDualPortMode() bool

IsDualPortMode returns true if both HTTP and HTTPS ports are configured

type SessionConfig

type SessionConfig struct {
	// Admin sessions (server.db admin_sessions table)
	Admin SessionTypeConfig `yaml:"admin"`
	// User sessions (user.db user_sessions table)
	User SessionTypeConfig `yaml:"user"`
	// Common settings
	ExtendOnActivity bool   `yaml:"extend_on_activity"` // Reset idle timeout on each request
	Secure           string `yaml:"secure"`             // auto, true, false
	HTTPOnly         bool   `yaml:"http_only"`
	SameSite         string `yaml:"same_site"` // strict, lax, none

	// Legacy fields for backward compatibility
	Duration       string `yaml:"duration,omitempty"`
	CookieName     string `yaml:"cookie_name,omitempty"`
	CookieSecure   bool   `yaml:"cookie_secure,omitempty"`
	CookieHTTPOnly bool   `yaml:"cookie_http_only,omitempty"`
	CookieSameSite string `yaml:"cookie_same_site,omitempty"`
}

SessionConfig represents session configuration per AI.md PART 13

func (*SessionConfig) GetAdminCookieName

func (s *SessionConfig) GetAdminCookieName() string

GetAdminCookieName returns the admin session cookie name

func (*SessionConfig) GetAdminMaxAge

func (s *SessionConfig) GetAdminMaxAge() int

GetAdminMaxAge returns admin session max age in seconds (default 30 days)

func (*SessionConfig) GetIdleTimeout

func (s *SessionConfig) GetIdleTimeout() int

GetIdleTimeout returns idle timeout in seconds (default 24 hours)

func (*SessionConfig) GetSameSite

func (s *SessionConfig) GetSameSite() string

GetSameSite returns the SameSite cookie attribute

func (*SessionConfig) GetUserCookieName

func (s *SessionConfig) GetUserCookieName() string

GetUserCookieName returns the user session cookie name

func (*SessionConfig) GetUserMaxAge

func (s *SessionConfig) GetUserMaxAge() int

GetUserMaxAge returns user session max age in seconds (default 7 days)

func (*SessionConfig) IsHTTPOnly

func (s *SessionConfig) IsHTTPOnly() bool

IsHTTPOnly returns whether cookies should be HTTP only

func (*SessionConfig) IsSecure

func (s *SessionConfig) IsSecure(sslEnabled bool) bool

IsSecure returns whether cookies should be secure

type SessionTypeConfig

type SessionTypeConfig struct {
	CookieName  string `yaml:"cookie_name"`
	MaxAge      int    `yaml:"max_age"`      // Absolute session lifetime in seconds
	IdleTimeout int    `yaml:"idle_timeout"` // Expires after inactivity in seconds
}

SessionTypeConfig represents configuration for a specific session type (admin or user)

type SportsWidgetConfig

type SportsWidgetConfig struct {
	Enabled        bool     `yaml:"enabled"`
	DefaultLeagues []string `yaml:"default_leagues"`
}

SportsWidgetConfig holds sports widget configuration

type StocksWidgetConfig

type StocksWidgetConfig struct {
	Enabled        bool     `yaml:"enabled"`
	DefaultSymbols []string `yaml:"default_symbols"`
}

StocksWidgetConfig holds stocks widget configuration

type TaskConfig

type TaskConfig struct {
	Schedule string `yaml:"schedule"` // Cron expression or @every interval
	Enabled  bool   `yaml:"enabled"`
}

TaskConfig represents configuration for a scheduled task

type TorConfig

type TorConfig struct {
	// Runtime state - NOT configurable
	Enabled      bool   `yaml:"-"` // Computed at runtime when Tor binary is found
	OnionAddress string `yaml:"-"` // Set at runtime when Tor starts

	// Binary path (empty = auto-detect)
	Binary string `yaml:"binary"`

	// --- Outbound Network Settings ---
	// Use Tor network for outbound connections (server-wide default)
	UseNetwork bool `yaml:"use_network"`
	// Allow users to set their own Tor network preference
	AllowUserPreference bool `yaml:"allow_user_preference"`

	// --- Performance Settings ---
	// Maximum circuits to keep open (1-128, default 32)
	MaxCircuits int `yaml:"max_circuits"`
	// Circuit timeout in seconds (10-300, default 60)
	CircuitTimeout int `yaml:"circuit_timeout"`
	// Bootstrap timeout in seconds (30-600, default 180)
	BootstrapTimeout int `yaml:"bootstrap_timeout"`

	// --- Security Settings ---
	// Scrub sensitive info from Tor logs (default true)
	SafeLogging bool `yaml:"safe_logging"`
	// Maximum concurrent streams per circuit (10-500, default 100)
	MaxStreamsPerCircuit int `yaml:"max_streams_per_circuit"`
	// Close circuit when stream limit exceeded (default true)
	CloseCircuitOnStreamLimit bool `yaml:"close_circuit_on_stream_limit"`

	// --- Bandwidth Settings ---
	// Maximum bandwidth rate per second (e.g., "1 MB", "500 KB")
	BandwidthRate string `yaml:"bandwidth_rate"`
	// Maximum bandwidth burst per second (e.g., "2 MB", "1 MB")
	BandwidthBurst string `yaml:"bandwidth_burst"`
	// Maximum monthly bandwidth (e.g., "100 GB", "50 GB", "unlimited")
	MaxMonthlyBandwidth string `yaml:"max_monthly_bandwidth"`

	// --- Hidden Service Settings ---
	// Number of introduction points (3-10, default 3)
	NumIntroPoints int `yaml:"num_intro_points"`
	// Virtual port for hidden service (1-65535, default 80)
	HiddenServicePort int `yaml:"hidden_service_port"`
}

TorConfig represents Tor configuration Per AI.md PART 32: "Auto-enabled if tor binary is installed - no enable flag needed"

type TwitterConfig

type TwitterConfig struct {
	Enabled bool   `yaml:"enabled"`
	Card    string `yaml:"card"` // summary, summary_large_image
	Site    string `yaml:"site"` // @username
	Creator string `yaml:"creator"`
}

TwitterConfig represents Twitter card meta tags

type UsersConfig

type UsersConfig struct {
	Enabled      bool `yaml:"enabled"`
	Registration struct {
		Enabled                  bool     `yaml:"enabled"`
		RequireEmailVerification bool     `yaml:"require_email_verification"`
		RequireApproval          bool     `yaml:"require_approval"`
		AllowedDomains           []string `yaml:"allowed_domains"`
		BlockedDomains           []string `yaml:"blocked_domains"`
	} `yaml:"registration"`
	Roles struct {
		Available []string `yaml:"available"`
		Default   string   `yaml:"default"`
	} `yaml:"roles"`
	Tokens struct {
		Enabled        bool `yaml:"enabled"`
		MaxPerUser     int  `yaml:"max_per_user"`
		ExpirationDays int  `yaml:"expiration_days"`
	} `yaml:"tokens"`
	Profile struct {
		AllowAvatar      bool `yaml:"allow_avatar"`
		AllowDisplayName bool `yaml:"allow_display_name"`
		AllowBio         bool `yaml:"allow_bio"`
	} `yaml:"profile"`
	Auth struct {
		SessionDuration          string `yaml:"session_duration"`
		SessionDurationDays      int    `yaml:"session_duration_days"` // Parsed from SessionDuration
		Require2FA               bool   `yaml:"require_2fa"`
		Allow2FA                 bool   `yaml:"allow_2fa"`
		PasswordMinLength        int    `yaml:"password_min_length"`
		PasswordRequireUppercase bool   `yaml:"password_require_uppercase"`
		PasswordRequireNumber    bool   `yaml:"password_require_number"`
		PasswordRequireSpecial   bool   `yaml:"password_require_special"`
	} `yaml:"auth"`
	Limits struct {
		RequestsPerMinute int `yaml:"requests_per_minute"`
		RequestsPerDay    int `yaml:"requests_per_day"`
	} `yaml:"limits"`
	SSO struct {
		Enabled bool `yaml:"enabled"`
		OIDC    map[string]struct {
			Name         string `yaml:"name"`
			ClientID     string `yaml:"client_id"`
			ClientSecret string `yaml:"client_secret"`
			Issuer       string `yaml:"issuer"`
			IconURL      string `yaml:"icon_url"`
		} `yaml:"oidc"`
		LDAP struct {
			Enabled  bool   `yaml:"enabled"`
			Server   string `yaml:"server"`
			Port     int    `yaml:"port"`
			BaseDN   string `yaml:"base_dn"`
			BindDN   string `yaml:"bind_dn"`
			BindPass string `yaml:"bind_pass"`
		} `yaml:"ldap"`
	} `yaml:"sso"`
}

UsersConfig represents user management configuration

func (*UsersConfig) GetSessionDurationDays

func (u *UsersConfig) GetSessionDurationDays() int

GetSessionDurationDays returns the session duration in days, parsing from string if needed

type ValidationWarning

type ValidationWarning struct {
	Field   string
	Message string
	Default interface{}
}

ValidationWarning represents a configuration validation warning Per AI.md PART 12: Config validation should warn and use defaults, not error

type WeatherWidgetConfig

type WeatherWidgetConfig struct {
	Enabled     bool   `yaml:"enabled"`
	DefaultCity string `yaml:"default_city"`
	Units       string `yaml:"units"` // "metric" or "imperial"
}

WeatherWidgetConfig holds weather widget configuration

type WebConfig

type WebConfig struct {
	Robots struct {
		Allow []string `yaml:"allow"`
		Deny  []string `yaml:"deny"`
	} `yaml:"robots"`
	Security struct {
		Contact string `yaml:"contact"` // Security contact email (mailto: prefix added automatically)
		Expires string `yaml:"expires"` // Expiration date (auto-calculated 1 year from now if not set)
	} `yaml:"security"`
	Announcements AnnouncementsConfig `yaml:"announcements"`
	CookieConsent CookieConsentConfig `yaml:"cookie_consent"`
	CORS          string              `yaml:"cors"` // "*", "origin1,origin2", or ""
}

WebConfig represents web settings (robots.txt, security.txt, announcements)

type WidgetsConfig

type WidgetsConfig struct {
	Enabled        bool     `yaml:"enabled"`
	DefaultWidgets []string `yaml:"default_widgets"`
	CacheTTL       int      `yaml:"cache_ttl"` // seconds

	Weather WeatherWidgetConfig `yaml:"weather"`
	News    NewsWidgetConfig    `yaml:"news"`
	Stocks  StocksWidgetConfig  `yaml:"stocks"`
	Crypto  CryptoWidgetConfig  `yaml:"crypto"`
	Sports  SportsWidgetConfig  `yaml:"sports"`
	RSS     RSSWidgetConfig     `yaml:"rss"`
}

WidgetsConfig represents widget system configuration

Jump to

Keyboard shortcuts

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