From 20ed66623bf1c0842e07ea584543423a2e31448b Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:06:43 +0200 Subject: [PATCH 1/6] feat: auto generate example env file --- .env.example | 249 +++++++++++++++++++++++--------------- Makefile | 8 +- cmd/tinyauth/tinyauth.go | 54 +-------- gen/gen.go | 11 ++ gen/gen_env.go | 111 +++++++++++++++++ internal/config/config.go | 53 ++++++++ 6 files changed, 333 insertions(+), 153 deletions(-) create mode 100644 gen/gen.go create mode 100644 gen/gen_env.go diff --git a/.env.example b/.env.example index 905775ef..211a1bd7 100644 --- a/.env.example +++ b/.env.example @@ -1,99 +1,152 @@ -# Base Configuration +# Tinyauth example configuration -# The base URL where Tinyauth is accessible -TINYAUTH_APPURL="https://auth.example.com" -# Directory for static resources -TINYAUTH_RESOURCESDIR="/data/resources" -# Path to SQLite database file -TINYAUTH_DATABASEPATH="/data/tinyauth.db" -# Disable version heartbeat -TINYAUTH_DISABLEANALYTICS="false" -# Disable static resource serving -TINYAUTH_DISABLERESOURCES="false" - -# Logging Configuration - -# Log level: trace, debug, info, warn, error -TINYAUTH_LOG_LEVEL="info" -# Enable JSON formatted logs -TINYAUTH_LOG_JSON="false" -# Specific Log stream configurations -# APP and HTTP log streams are enabled by default, and use the global log level unless overridden -TINYAUTH_LOG_STREAMS_APP_ENABLED="true" -TINYAUTH_LOG_STREAMS_APP_LEVEL="info" -TINYAUTH_LOG_STREAMS_HTTP_ENABLED="true" -TINYAUTH_LOG_STREAMS_HTTP_LEVEL="info" -TINYAUTH_LOG_STREAMS_AUDIT_ENABLED="false" -TINYAUTH_LOG_STREAMS_AUDIT_LEVEL="info" - -# Server Configuration - -# Port to listen on -TINYAUTH_SERVER_PORT="3000" -# Interface to bind to (0.0.0.0 for all interfaces) -TINYAUTH_SERVER_ADDRESS="0.0.0.0" -# Unix socket path (optional, overrides port/address if set) -TINYAUTH_SERVER_SOCKETPATH="" - -# Authentication Configuration - -# Format: username:bcrypt_hash (use bcrypt to generate hash) -TINYAUTH_AUTH_USERS="admin:$2a$10$example_bcrypt_hash_here" -# Path to external users file (optional) -TINYAUTH_AUTH_USERSFILE="" -# Enable secure cookies (requires HTTPS) -TINYAUTH_AUTH_SECURECOOKIE="true" -# Session expiry in seconds (7200 = 2 hours) -TINYAUTH_AUTH_SESSIONEXPIRY="7200" -# Session maximum lifetime in seconds (0 = unlimited) -TINYAUTH_AUTH_SESSIONMAXLIFETIME="0" -# Login timeout in seconds (300 = 5 minutes) -TINYAUTH_AUTH_LOGINTIMEOUT="300" -# Maximum login retries before lockout -TINYAUTH_AUTH_LOGINMAXRETRIES="5" -# Comma-separated list of trusted proxy IPs/CIDRs -TINYAUTH_AUTH_TRUSTEDPROXIES="" - -# OAuth Configuration - -# Regex pattern for allowed email addresses (e.g., /@example\.com$/) -TINYAUTH_OAUTH_WHITELIST="" -# Provider ID to auto-redirect to (skips login page) -TINYAUTH_OAUTH_AUTOREDIRECT="" -# OAuth Provider Configuration (replace MYPROVIDER with your provider name) -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTID="your_client_id_here" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_CLIENTSECRET="your_client_secret_here" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_AUTHURL="https://provider.example.com/oauth/authorize" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_TOKENURL="https://provider.example.com/oauth/token" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_USERINFOURL="https://provider.example.com/oauth/userinfo" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_REDIRECTURL="https://auth.example.com/oauth/callback/myprovider" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_SCOPES="openid email profile" -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_NAME="My OAuth Provider" -# Allow self-signed certificates -TINYAUTH_OAUTH_PROVIDERS_MYPROVIDER_INSECURE="false" - -# UI Customization - -# Custom title for login page -TINYAUTH_UI_TITLE="Tinyauth" -# Message shown on forgot password page -TINYAUTH_UI_FORGOTPASSWORDMESSAGE="Contact your administrator to reset your password" -# Background image URL for login page -TINYAUTH_UI_BACKGROUNDIMAGE="" -# Disable UI warning messages -TINYAUTH_UI_DISABLEWARNINGS="false" - -# LDAP Configuration - -# LDAP server address -TINYAUTH_LDAP_ADDRESS="ldap://ldap.example.com:389" -# DN for binding to LDAP server -TINYAUTH_LDAP_BINDDN="cn=readonly,dc=example,dc=com" -# Password for bind DN -TINYAUTH_LDAP_BINDPASSWORD="your_bind_password" -# Base DN for user searches -TINYAUTH_LDAP_BASEDN="dc=example,dc=com" -# Search filter (%s will be replaced with username) -TINYAUTH_LDAP_SEARCHFILTER="(&(uid=%s)(memberOf=cn=users,ou=groups,dc=example,dc=com))" -# Allow insecure LDAP connections -TINYAUTH_LDAP_INSECURE="false" +# The base URL where the app is hosted. +TINYAUTH_APPURL= +# The directory where resources are stored. +TINYAUTH_RESOURCESDIR=./resources +# The path to the database file. +TINYAUTH_DATABASEPATH=./tinyauth.db +# Disable analytics. +TINYAUTH_DISABLEANALYTICS=false +# Disable resources server. +TINYAUTH_DISABLERESOURCES=false +# The port on which the server listens. +TINYAUTH_SERVER_PORT=3000 +# The address on which the server listens. +TINYAUTH_SERVER_ADDRESS=0.0.0.0 +# The path to the Unix socket. +TINYAUTH_SERVER_SOCKETPATH= +# List of allowed IPs or CIDR ranges. +TINYAUTH_AUTH_IP_ALLOW=[] +# List of blocked IPs or CIDR ranges. +TINYAUTH_AUTH_IP_BLOCK=[] +# Comma-separated list of users (username:hashed_password). +TINYAUTH_AUTH_USERS=[] +# Path to the users file. +TINYAUTH_AUTH_USERSFILE= +# Enable secure cookies. +TINYAUTH_AUTH_SECURECOOKIE=false +# Session expiry time in seconds. +TINYAUTH_AUTH_SESSIONEXPIRY=86400 +# Maximum session lifetime in seconds. +TINYAUTH_AUTH_SESSIONMAXLIFETIME=0 +# Login timeout in seconds. +TINYAUTH_AUTH_LOGINTIMEOUT=300 +# Maximum login retries. +TINYAUTH_AUTH_LOGINMAXRETRIES=3 +# Comma-separated list of trusted proxy addresses. +TINYAUTH_AUTH_TRUSTEDPROXIES=[] +# The domain of the app. +TINYAUTH_APPS_[NAME]_CONFIG_DOMAIN= +# Comma-separated list of allowed users. +TINYAUTH_APPS_[NAME]_USERS_ALLOW= +# Comma-separated list of blocked users. +TINYAUTH_APPS_[NAME]_USERS_BLOCK= +# Comma-separated list of allowed OAuth groups. +TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST= +# Comma-separated list of required OAuth groups. +TINYAUTH_APPS_[NAME]_OAUTH_GROUPS= +# List of allowed IPs or CIDR ranges. +TINYAUTH_APPS_[NAME]_IP_ALLOW=[] +# List of blocked IPs or CIDR ranges. +TINYAUTH_APPS_[NAME]_IP_BLOCK=[] +# List of IPs or CIDR ranges that bypass authentication. +TINYAUTH_APPS_[NAME]_IP_BYPASS=[] +# Custom headers to add to the response. +TINYAUTH_APPS_[NAME]_RESPONSE_HEADERS=[] +# Basic auth username. +TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_USERNAME= +# Basic auth password. +TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORD= +# Path to the file containing the basic auth password. +TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORDFILE= +# Comma-separated list of allowed paths. +TINYAUTH_APPS_[NAME]_PATH_ALLOW= +# Comma-separated list of blocked paths. +TINYAUTH_APPS_[NAME]_PATH_BLOCK= +# Comma-separated list of required LDAP groups. +TINYAUTH_APPS_[NAME]_LDAP_GROUPS= +# Comma-separated list of allowed OAuth domains. +TINYAUTH_OAUTH_WHITELIST=[] +# The OAuth provider to use for automatic redirection. +TINYAUTH_OAUTH_AUTOREDIRECT= +# OAuth client ID. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTID= +# OAuth client secret. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRET= +# Path to the file containing the OAuth client secret. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRETFILE= +# OAuth scopes. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_SCOPES=[] +# OAuth redirect URL. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_REDIRECTURL= +# OAuth authorization URL. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_AUTHURL= +# OAuth token URL. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_TOKENURL= +# OAuth userinfo URL. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_USERINFOURL= +# Allow insecure OAuth connections. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_INSECURE=false +# Provider name in UI. +TINYAUTH_OAUTH_PROVIDERS_[NAME]_NAME= +# Path to the private key file. +TINYAUTH_OIDC_PRIVATEKEYPATH=./tinyauth_oidc_key +# Path to the public key file. +TINYAUTH_OIDC_PUBLICKEYPATH=./tinyauth_oidc_key.pub +# OIDC client ID. +TINYAUTH_OIDC_CLIENTS_[NAME]_ID= +# OIDC client ID. +TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTID= +# OIDC client secret. +TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRET= +# Path to the file containing the OIDC client secret. +TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRETFILE= +# List of trusted redirect URIs. +TINYAUTH_OIDC_CLIENTS_[NAME]_TRUSTEDREDIRECTURIS=[] +# Client name in UI. +TINYAUTH_OIDC_CLIENTS_[NAME]_NAME= +# The title of the UI. +TINYAUTH_UI_TITLE=Tinyauth +# Message displayed on the forgot password page. +TINYAUTH_UI_FORGOTPASSWORDMESSAGE=You can change your password by changing the configuration. +# Path to the background image. +TINYAUTH_UI_BACKGROUNDIMAGE=/background.jpg +# Disable UI warnings. +TINYAUTH_UI_DISABLEWARNINGS=false +# LDAP server address. +TINYAUTH_LDAP_ADDRESS= +# Bind DN for LDAP authentication. +TINYAUTH_LDAP_BINDDN= +# Bind password for LDAP authentication. +TINYAUTH_LDAP_BINDPASSWORD= +# Base DN for LDAP searches. +TINYAUTH_LDAP_BASEDN= +# Allow insecure LDAP connections. +TINYAUTH_LDAP_INSECURE=false +# LDAP search filter. +TINYAUTH_LDAP_SEARCHFILTER=(uid=%s) +# Certificate for mTLS authentication. +TINYAUTH_LDAP_AUTHCERT= +# Certificate key for mTLS authentication. +TINYAUTH_LDAP_AUTHKEY= +# Cache duration for LDAP group membership in seconds. +TINYAUTH_LDAP_GROUPCACHETTL=900 +# Path to config file. +TINYAUTH_EXPERIMENTAL_CONFIGFILE= +# Log level (trace, debug, info, warn, error). +TINYAUTH_LOG_LEVEL=info +# Enable JSON formatted logs. +TINYAUTH_LOG_JSON=false +# Enable this log stream. +TINYAUTH_LOG_STREAMS_HTTP_ENABLED=true +# Log level for this stream. Use global if empty. +TINYAUTH_LOG_STREAMS_HTTP_LEVEL= +# Enable this log stream. +TINYAUTH_LOG_STREAMS_APP_ENABLED=true +# Log level for this stream. Use global if empty. +TINYAUTH_LOG_STREAMS_APP_LEVEL= +# Enable this log stream. +TINYAUTH_LOG_STREAMS_AUDIT_ENABLED=false +# Log level for this stream. Use global if empty. +TINYAUTH_LOG_STREAMS_AUDIT_LEVEL= diff --git a/Makefile b/Makefile index 4ac08c41..dfabc343 100644 --- a/Makefile +++ b/Makefile @@ -60,11 +60,11 @@ test: go test -v ./... # Development -develop: +dev: docker compose -f $(DEV_COMPOSE) up --force-recreate --pull=always --remove-orphans --build # Development - Infisical -develop-infisical: +dev-infisical: infisical run --env=dev -- docker compose -f $(DEV_COMPOSE) up --force-recreate --pull=always --remove-orphans --build # Production @@ -79,3 +79,7 @@ prod-infisical: .PHONY: sql sql: sqlc generate + +# Go gen +generate: + go run ./gen diff --git a/cmd/tinyauth/tinyauth.go b/cmd/tinyauth/tinyauth.go index 5516c6bf..a6cb93e0 100644 --- a/cmd/tinyauth/tinyauth.go +++ b/cmd/tinyauth/tinyauth.go @@ -12,60 +12,8 @@ import ( "github.com/traefik/paerser/cli" ) -func NewTinyauthCmdConfiguration() *config.Config { - return &config.Config{ - ResourcesDir: "./resources", - DatabasePath: "./tinyauth.db", - Server: config.ServerConfig{ - Port: 3000, - Address: "0.0.0.0", - }, - Auth: config.AuthConfig{ - SessionExpiry: 86400, // 1 day - SessionMaxLifetime: 0, // disabled - LoginTimeout: 300, // 5 minutes - LoginMaxRetries: 3, - }, - UI: config.UIConfig{ - Title: "Tinyauth", - ForgotPasswordMessage: "You can change your password by changing the configuration.", - BackgroundImage: "/background.jpg", - }, - Ldap: config.LdapConfig{ - Insecure: false, - SearchFilter: "(uid=%s)", - GroupCacheTTL: 900, // 15 minutes - }, - Log: config.LogConfig{ - Level: "info", - Json: false, - Streams: config.LogStreams{ - HTTP: config.LogStreamConfig{ - Enabled: true, - Level: "", - }, - App: config.LogStreamConfig{ - Enabled: true, - Level: "", - }, - Audit: config.LogStreamConfig{ - Enabled: false, - Level: "", - }, - }, - }, - OIDC: config.OIDCConfig{ - PrivateKeyPath: "./tinyauth_oidc_key", - PublicKeyPath: "./tinyauth_oidc_key.pub", - }, - Experimental: config.ExperimentalConfig{ - ConfigFile: "", - }, - } -} - func main() { - tConfig := NewTinyauthCmdConfiguration() + tConfig := config.NewDefaultConfiguration() loaders := []cli.ResourceLoader{ &loaders.FileLoader{}, diff --git a/gen/gen.go b/gen/gen.go new file mode 100644 index 00000000..520eec89 --- /dev/null +++ b/gen/gen.go @@ -0,0 +1,11 @@ +package main + +import ( + "log/slog" +) + +func main() { + slog.Info("generating example env file") + + generateExampleEnv() +} diff --git a/gen/gen_env.go b/gen/gen_env.go new file mode 100644 index 00000000..50155e59 --- /dev/null +++ b/gen/gen_env.go @@ -0,0 +1,111 @@ +package main + +import ( + "bytes" + "fmt" + "log/slog" + "os" + "reflect" + "strings" + + "github.com/steveiliop56/tinyauth/internal/config" +) + +type Path struct { + Name string + Description string + Value any +} + +func generateExampleEnv() { + cfg := config.NewDefaultConfiguration() + paths := make([]Path, 0) + + root := reflect.TypeOf(cfg).Elem() + rootValue := reflect.ValueOf(cfg).Elem() + rootPath := "TINYAUTH_" + + buildPaths(root, rootValue, rootPath, &paths) + compiled := compileEnv(paths) + + err := os.Remove(".env.example") + if err != nil { + slog.Error("failed to remove example env file", "error", err) + } + + err = os.WriteFile(".env.example", compiled, 0644) + if err != nil { + slog.Error("failed to write example env file", "error", err) + } +} + +func buildPaths(parent reflect.Type, parentValue reflect.Value, parentPath string, paths *[]Path) { + for i := 0; i < parent.NumField(); i++ { + field := parent.Field(i) + fieldType := field.Type + fieldValue := parentValue.Field(i) + switch fieldType.Kind() { + case reflect.Struct: + childPath := parentPath + strings.ToUpper(field.Name) + "_" + buildPaths(fieldType, fieldValue, childPath, paths) + case reflect.Bool: + buildPath(field, fieldValue, parentPath, paths) + case reflect.String: + buildPath(field, fieldValue, parentPath, paths) + case reflect.Slice: + buildPath(field, fieldValue, parentPath, paths) + case reflect.Int: + buildPath(field, fieldValue, parentPath, paths) + case reflect.Map: + buildMapPaths(field, parentPath, paths) + default: + slog.Info("unknown type", "type", fieldType.Kind()) + } + + } +} + +func buildPath(field reflect.StructField, fieldValue reflect.Value, parent string, paths *[]Path) { + desc := field.Tag.Get("description") + defaultValue := fieldValue.Interface() + path := Path{ + Name: parent + strings.ToUpper(field.Name), + Description: desc, + Value: defaultValue, + } + *paths = append(*paths, path) +} + +func buildMapPaths(field reflect.StructField, parentPath string, paths *[]Path) { + fieldType := field.Type + + if fieldType.Key().Kind() != reflect.String { + slog.Info("unsupported map key type", "type", fieldType.Key().Kind()) + return + } + + mapPath := parentPath + strings.ToUpper(field.Name) + "_[NAME]_" + valueType := fieldType.Elem() + + if valueType.Kind() == reflect.Struct { + zeroValue := reflect.New(valueType).Elem() + buildPaths(valueType, zeroValue, mapPath, paths) + } +} + +func compileEnv(paths []Path) []byte { + buffer := bytes.Buffer{} + buffer.WriteString("# Tinyauth example configuration\n\n") + + for _, path := range paths { + buffer.WriteString("# ") + buffer.WriteString(path.Description) + buffer.WriteString("\n") + buffer.WriteString(path.Name) + buffer.WriteString("=") + fmt.Fprintf(&buffer, "%v", path.Value) + buffer.WriteString("\n") + } + + return buffer.Bytes() +} diff --git a/internal/config/config.go b/internal/config/config.go index 8b9be236..9403d628 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,5 +1,58 @@ package config +// Default configuration +func NewDefaultConfiguration() *Config { + return &Config{ + ResourcesDir: "./resources", + DatabasePath: "./tinyauth.db", + Server: ServerConfig{ + Port: 3000, + Address: "0.0.0.0", + }, + Auth: AuthConfig{ + SessionExpiry: 86400, // 1 day + SessionMaxLifetime: 0, // disabled + LoginTimeout: 300, // 5 minutes + LoginMaxRetries: 3, + }, + UI: UIConfig{ + Title: "Tinyauth", + ForgotPasswordMessage: "You can change your password by changing the configuration.", + BackgroundImage: "/background.jpg", + }, + Ldap: LdapConfig{ + Insecure: false, + SearchFilter: "(uid=%s)", + GroupCacheTTL: 900, // 15 minutes + }, + Log: LogConfig{ + Level: "info", + Json: false, + Streams: LogStreams{ + HTTP: LogStreamConfig{ + Enabled: true, + Level: "", + }, + App: LogStreamConfig{ + Enabled: true, + Level: "", + }, + Audit: LogStreamConfig{ + Enabled: false, + Level: "", + }, + }, + }, + OIDC: OIDCConfig{ + PrivateKeyPath: "./tinyauth_oidc_key", + PublicKeyPath: "./tinyauth_oidc_key.pub", + }, + Experimental: ExperimentalConfig{ + ConfigFile: "", + }, + } +} + // Version information, set at build time var Version = "development" From 6f4424dd08fda72f41ea98500972cb21d91ef1d2 Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:19:26 +0200 Subject: [PATCH 2/6] refactor: simplify build paths func and better slice handling --- .env.example | 22 +++++++++++----------- gen/gen_env.go | 13 ++++--------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/.env.example b/.env.example index 211a1bd7..bac87862 100644 --- a/.env.example +++ b/.env.example @@ -17,11 +17,11 @@ TINYAUTH_SERVER_ADDRESS=0.0.0.0 # The path to the Unix socket. TINYAUTH_SERVER_SOCKETPATH= # List of allowed IPs or CIDR ranges. -TINYAUTH_AUTH_IP_ALLOW=[] +TINYAUTH_AUTH_IP_ALLOW= # List of blocked IPs or CIDR ranges. -TINYAUTH_AUTH_IP_BLOCK=[] +TINYAUTH_AUTH_IP_BLOCK= # Comma-separated list of users (username:hashed_password). -TINYAUTH_AUTH_USERS=[] +TINYAUTH_AUTH_USERS= # Path to the users file. TINYAUTH_AUTH_USERSFILE= # Enable secure cookies. @@ -35,7 +35,7 @@ TINYAUTH_AUTH_LOGINTIMEOUT=300 # Maximum login retries. TINYAUTH_AUTH_LOGINMAXRETRIES=3 # Comma-separated list of trusted proxy addresses. -TINYAUTH_AUTH_TRUSTEDPROXIES=[] +TINYAUTH_AUTH_TRUSTEDPROXIES= # The domain of the app. TINYAUTH_APPS_[NAME]_CONFIG_DOMAIN= # Comma-separated list of allowed users. @@ -47,13 +47,13 @@ TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST= # Comma-separated list of required OAuth groups. TINYAUTH_APPS_[NAME]_OAUTH_GROUPS= # List of allowed IPs or CIDR ranges. -TINYAUTH_APPS_[NAME]_IP_ALLOW=[] +TINYAUTH_APPS_[NAME]_IP_ALLOW= # List of blocked IPs or CIDR ranges. -TINYAUTH_APPS_[NAME]_IP_BLOCK=[] +TINYAUTH_APPS_[NAME]_IP_BLOCK= # List of IPs or CIDR ranges that bypass authentication. -TINYAUTH_APPS_[NAME]_IP_BYPASS=[] +TINYAUTH_APPS_[NAME]_IP_BYPASS= # Custom headers to add to the response. -TINYAUTH_APPS_[NAME]_RESPONSE_HEADERS=[] +TINYAUTH_APPS_[NAME]_RESPONSE_HEADERS= # Basic auth username. TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_USERNAME= # Basic auth password. @@ -67,7 +67,7 @@ TINYAUTH_APPS_[NAME]_PATH_BLOCK= # Comma-separated list of required LDAP groups. TINYAUTH_APPS_[NAME]_LDAP_GROUPS= # Comma-separated list of allowed OAuth domains. -TINYAUTH_OAUTH_WHITELIST=[] +TINYAUTH_OAUTH_WHITELIST= # The OAuth provider to use for automatic redirection. TINYAUTH_OAUTH_AUTOREDIRECT= # OAuth client ID. @@ -77,7 +77,7 @@ TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRET= # Path to the file containing the OAuth client secret. TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRETFILE= # OAuth scopes. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_SCOPES=[] +TINYAUTH_OAUTH_PROVIDERS_[NAME]_SCOPES= # OAuth redirect URL. TINYAUTH_OAUTH_PROVIDERS_[NAME]_REDIRECTURL= # OAuth authorization URL. @@ -103,7 +103,7 @@ TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRET= # Path to the file containing the OIDC client secret. TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRETFILE= # List of trusted redirect URIs. -TINYAUTH_OIDC_CLIENTS_[NAME]_TRUSTEDREDIRECTURIS=[] +TINYAUTH_OIDC_CLIENTS_[NAME]_TRUSTEDREDIRECTURIS= # Client name in UI. TINYAUTH_OIDC_CLIENTS_[NAME]_NAME= # The title of the UI. diff --git a/gen/gen_env.go b/gen/gen_env.go index 50155e59..1ddbf686 100644 --- a/gen/gen_env.go +++ b/gen/gen_env.go @@ -31,11 +31,13 @@ func generateExampleEnv() { err := os.Remove(".env.example") if err != nil { slog.Error("failed to remove example env file", "error", err) + os.Exit(1) } err = os.WriteFile(".env.example", compiled, 0644) if err != nil { slog.Error("failed to write example env file", "error", err) + os.Exit(1) } } @@ -48,20 +50,13 @@ func buildPaths(parent reflect.Type, parentValue reflect.Value, parentPath strin case reflect.Struct: childPath := parentPath + strings.ToUpper(field.Name) + "_" buildPaths(fieldType, fieldValue, childPath, paths) - case reflect.Bool: - buildPath(field, fieldValue, parentPath, paths) - case reflect.String: - buildPath(field, fieldValue, parentPath, paths) - case reflect.Slice: - buildPath(field, fieldValue, parentPath, paths) - case reflect.Int: - buildPath(field, fieldValue, parentPath, paths) case reflect.Map: buildMapPaths(field, parentPath, paths) + case reflect.Bool, reflect.String, reflect.Slice, reflect.Int: + buildPath(field, fieldValue, parentPath, paths) default: slog.Info("unknown type", "type", fieldType.Kind()) } - } } From e72c7acb5dc0a0ac3cbeb7c7041dfc5f53d955e7 Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:20:23 +0200 Subject: [PATCH 3/6] chore: forgot to stage everything --- gen/gen_env.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gen/gen_env.go b/gen/gen_env.go index 1ddbf686..60612efd 100644 --- a/gen/gen_env.go +++ b/gen/gen_env.go @@ -68,6 +68,14 @@ func buildPath(field reflect.StructField, fieldValue reflect.Value, parent strin Description: desc, Value: defaultValue, } + if fieldValue.Kind() == reflect.Slice { + sl, ok := defaultValue.([]string) + if !ok { + slog.Error("invalid default value", "value", defaultValue) + return + } + path.Value = strings.Join(sl, ",") + } *paths = append(*paths, path) } From 5f9bf1cd80e56cd5b2db3686fcceff1791539f9a Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:30:31 +0200 Subject: [PATCH 4/6] chore: review comments --- .env.example | 97 ++++++++++++++++++++++++++++++++++++++++++-------- gen/gen_env.go | 29 +++++++++++++-- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/.env.example b/.env.example index bac87862..5d3e2846 100644 --- a/.env.example +++ b/.env.example @@ -2,151 +2,220 @@ # The base URL where the app is hosted. TINYAUTH_APPURL= + # The directory where resources are stored. -TINYAUTH_RESOURCESDIR=./resources +TINYAUTH_RESOURCESDIR="./resources" + # The path to the database file. -TINYAUTH_DATABASEPATH=./tinyauth.db +TINYAUTH_DATABASEPATH="./tinyauth.db" + # Disable analytics. TINYAUTH_DISABLEANALYTICS=false + # Disable resources server. TINYAUTH_DISABLERESOURCES=false + # The port on which the server listens. TINYAUTH_SERVER_PORT=3000 + # The address on which the server listens. -TINYAUTH_SERVER_ADDRESS=0.0.0.0 +TINYAUTH_SERVER_ADDRESS="0.0.0.0" + # The path to the Unix socket. TINYAUTH_SERVER_SOCKETPATH= + # List of allowed IPs or CIDR ranges. TINYAUTH_AUTH_IP_ALLOW= + # List of blocked IPs or CIDR ranges. TINYAUTH_AUTH_IP_BLOCK= + # Comma-separated list of users (username:hashed_password). TINYAUTH_AUTH_USERS= + # Path to the users file. TINYAUTH_AUTH_USERSFILE= + # Enable secure cookies. TINYAUTH_AUTH_SECURECOOKIE=false + # Session expiry time in seconds. TINYAUTH_AUTH_SESSIONEXPIRY=86400 + # Maximum session lifetime in seconds. TINYAUTH_AUTH_SESSIONMAXLIFETIME=0 + # Login timeout in seconds. TINYAUTH_AUTH_LOGINTIMEOUT=300 + # Maximum login retries. TINYAUTH_AUTH_LOGINMAXRETRIES=3 + # Comma-separated list of trusted proxy addresses. TINYAUTH_AUTH_TRUSTEDPROXIES= + # The domain of the app. TINYAUTH_APPS_[NAME]_CONFIG_DOMAIN= + # Comma-separated list of allowed users. TINYAUTH_APPS_[NAME]_USERS_ALLOW= + # Comma-separated list of blocked users. TINYAUTH_APPS_[NAME]_USERS_BLOCK= + # Comma-separated list of allowed OAuth groups. TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST= + # Comma-separated list of required OAuth groups. TINYAUTH_APPS_[NAME]_OAUTH_GROUPS= + # List of allowed IPs or CIDR ranges. TINYAUTH_APPS_[NAME]_IP_ALLOW= + # List of blocked IPs or CIDR ranges. TINYAUTH_APPS_[NAME]_IP_BLOCK= + # List of IPs or CIDR ranges that bypass authentication. TINYAUTH_APPS_[NAME]_IP_BYPASS= + # Custom headers to add to the response. TINYAUTH_APPS_[NAME]_RESPONSE_HEADERS= + # Basic auth username. TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_USERNAME= + # Basic auth password. TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORD= + # Path to the file containing the basic auth password. TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORDFILE= + # Comma-separated list of allowed paths. TINYAUTH_APPS_[NAME]_PATH_ALLOW= + # Comma-separated list of blocked paths. TINYAUTH_APPS_[NAME]_PATH_BLOCK= + # Comma-separated list of required LDAP groups. TINYAUTH_APPS_[NAME]_LDAP_GROUPS= + # Comma-separated list of allowed OAuth domains. TINYAUTH_OAUTH_WHITELIST= + # The OAuth provider to use for automatic redirection. TINYAUTH_OAUTH_AUTOREDIRECT= + # OAuth client ID. TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTID= + # OAuth client secret. TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRET= + # Path to the file containing the OAuth client secret. TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRETFILE= + # OAuth scopes. TINYAUTH_OAUTH_PROVIDERS_[NAME]_SCOPES= + # OAuth redirect URL. TINYAUTH_OAUTH_PROVIDERS_[NAME]_REDIRECTURL= + # OAuth authorization URL. TINYAUTH_OAUTH_PROVIDERS_[NAME]_AUTHURL= + # OAuth token URL. TINYAUTH_OAUTH_PROVIDERS_[NAME]_TOKENURL= + # OAuth userinfo URL. TINYAUTH_OAUTH_PROVIDERS_[NAME]_USERINFOURL= + # Allow insecure OAuth connections. TINYAUTH_OAUTH_PROVIDERS_[NAME]_INSECURE=false + # Provider name in UI. TINYAUTH_OAUTH_PROVIDERS_[NAME]_NAME= + # Path to the private key file. -TINYAUTH_OIDC_PRIVATEKEYPATH=./tinyauth_oidc_key +TINYAUTH_OIDC_PRIVATEKEYPATH="./tinyauth_oidc_key" + # Path to the public key file. -TINYAUTH_OIDC_PUBLICKEYPATH=./tinyauth_oidc_key.pub -# OIDC client ID. -TINYAUTH_OIDC_CLIENTS_[NAME]_ID= +TINYAUTH_OIDC_PUBLICKEYPATH="./tinyauth_oidc_key.pub" + # OIDC client ID. TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTID= + # OIDC client secret. TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRET= + # Path to the file containing the OIDC client secret. TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRETFILE= + # List of trusted redirect URIs. TINYAUTH_OIDC_CLIENTS_[NAME]_TRUSTEDREDIRECTURIS= + # Client name in UI. TINYAUTH_OIDC_CLIENTS_[NAME]_NAME= + # The title of the UI. -TINYAUTH_UI_TITLE=Tinyauth +TINYAUTH_UI_TITLE="Tinyauth" + # Message displayed on the forgot password page. -TINYAUTH_UI_FORGOTPASSWORDMESSAGE=You can change your password by changing the configuration. +TINYAUTH_UI_FORGOTPASSWORDMESSAGE="You can change your password by changing the configuration." + # Path to the background image. -TINYAUTH_UI_BACKGROUNDIMAGE=/background.jpg +TINYAUTH_UI_BACKGROUNDIMAGE="/background.jpg" + # Disable UI warnings. TINYAUTH_UI_DISABLEWARNINGS=false + # LDAP server address. TINYAUTH_LDAP_ADDRESS= + # Bind DN for LDAP authentication. TINYAUTH_LDAP_BINDDN= + # Bind password for LDAP authentication. TINYAUTH_LDAP_BINDPASSWORD= + # Base DN for LDAP searches. TINYAUTH_LDAP_BASEDN= + # Allow insecure LDAP connections. TINYAUTH_LDAP_INSECURE=false + # LDAP search filter. -TINYAUTH_LDAP_SEARCHFILTER=(uid=%s) +TINYAUTH_LDAP_SEARCHFILTER="(uid=%s)" + # Certificate for mTLS authentication. TINYAUTH_LDAP_AUTHCERT= + # Certificate key for mTLS authentication. TINYAUTH_LDAP_AUTHKEY= + # Cache duration for LDAP group membership in seconds. TINYAUTH_LDAP_GROUPCACHETTL=900 -# Path to config file. -TINYAUTH_EXPERIMENTAL_CONFIGFILE= + # Log level (trace, debug, info, warn, error). -TINYAUTH_LOG_LEVEL=info +TINYAUTH_LOG_LEVEL="info" + # Enable JSON formatted logs. TINYAUTH_LOG_JSON=false + # Enable this log stream. TINYAUTH_LOG_STREAMS_HTTP_ENABLED=true + # Log level for this stream. Use global if empty. TINYAUTH_LOG_STREAMS_HTTP_LEVEL= + # Enable this log stream. TINYAUTH_LOG_STREAMS_APP_ENABLED=true + # Log level for this stream. Use global if empty. TINYAUTH_LOG_STREAMS_APP_LEVEL= + # Enable this log stream. TINYAUTH_LOG_STREAMS_AUDIT_ENABLED=false + # Log level for this stream. Use global if empty. TINYAUTH_LOG_STREAMS_AUDIT_LEVEL= + diff --git a/gen/gen_env.go b/gen/gen_env.go index 60612efd..f9524525 100644 --- a/gen/gen_env.go +++ b/gen/gen_env.go @@ -62,19 +62,42 @@ func buildPaths(parent reflect.Type, parentValue reflect.Value, parentPath strin func buildPath(field reflect.StructField, fieldValue reflect.Value, parent string, paths *[]Path) { desc := field.Tag.Get("description") + yamlTag := field.Tag.Get("yaml") + + // probably internal logic, should be skipped + if yamlTag == "-" { + return + } + defaultValue := fieldValue.Interface() + path := Path{ Name: parent + strings.ToUpper(field.Name), Description: desc, - Value: defaultValue, } - if fieldValue.Kind() == reflect.Slice { + + switch fieldValue.Kind() { + case reflect.Slice: sl, ok := defaultValue.([]string) if !ok { slog.Error("invalid default value", "value", defaultValue) return } path.Value = strings.Join(sl, ",") + case reflect.String: + st, ok := defaultValue.(string) + if !ok { + slog.Error("invalid default value", "value", defaultValue) + return + } + // good idea to escape strings probably + if st != "" { + path.Value = fmt.Sprintf(`"%s"`, st) + } else { + path.Value = "" + } + default: + path.Value = defaultValue } *paths = append(*paths, path) } @@ -107,7 +130,7 @@ func compileEnv(paths []Path) []byte { buffer.WriteString(path.Name) buffer.WriteString("=") fmt.Fprintf(&buffer, "%v", path.Value) - buffer.WriteString("\n") + buffer.WriteString("\n\n") } return buffer.Bytes() From 907621664959b0b29a299da0db1e015442eabfda Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:33:41 +0200 Subject: [PATCH 5/6] refactor: remove square brackets because they mess up the syntax highlighting --- .env.example | 60 +++++++++++++++++++++++++------------------------- gen/gen_env.go | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.env.example b/.env.example index 5d3e2846..c89d8ccc 100644 --- a/.env.example +++ b/.env.example @@ -55,49 +55,49 @@ TINYAUTH_AUTH_LOGINMAXRETRIES=3 TINYAUTH_AUTH_TRUSTEDPROXIES= # The domain of the app. -TINYAUTH_APPS_[NAME]_CONFIG_DOMAIN= +TINYAUTH_APPS_NAME_CONFIG_DOMAIN= # Comma-separated list of allowed users. -TINYAUTH_APPS_[NAME]_USERS_ALLOW= +TINYAUTH_APPS_NAME_USERS_ALLOW= # Comma-separated list of blocked users. -TINYAUTH_APPS_[NAME]_USERS_BLOCK= +TINYAUTH_APPS_NAME_USERS_BLOCK= # Comma-separated list of allowed OAuth groups. -TINYAUTH_APPS_[NAME]_OAUTH_WHITELIST= +TINYAUTH_APPS_NAME_OAUTH_WHITELIST= # Comma-separated list of required OAuth groups. -TINYAUTH_APPS_[NAME]_OAUTH_GROUPS= +TINYAUTH_APPS_NAME_OAUTH_GROUPS= # List of allowed IPs or CIDR ranges. -TINYAUTH_APPS_[NAME]_IP_ALLOW= +TINYAUTH_APPS_NAME_IP_ALLOW= # List of blocked IPs or CIDR ranges. -TINYAUTH_APPS_[NAME]_IP_BLOCK= +TINYAUTH_APPS_NAME_IP_BLOCK= # List of IPs or CIDR ranges that bypass authentication. -TINYAUTH_APPS_[NAME]_IP_BYPASS= +TINYAUTH_APPS_NAME_IP_BYPASS= # Custom headers to add to the response. -TINYAUTH_APPS_[NAME]_RESPONSE_HEADERS= +TINYAUTH_APPS_NAME_RESPONSE_HEADERS= # Basic auth username. -TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_USERNAME= +TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_USERNAME= # Basic auth password. -TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORD= +TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_PASSWORD= # Path to the file containing the basic auth password. -TINYAUTH_APPS_[NAME]_RESPONSE_BASICAUTH_PASSWORDFILE= +TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_PASSWORDFILE= # Comma-separated list of allowed paths. -TINYAUTH_APPS_[NAME]_PATH_ALLOW= +TINYAUTH_APPS_NAME_PATH_ALLOW= # Comma-separated list of blocked paths. -TINYAUTH_APPS_[NAME]_PATH_BLOCK= +TINYAUTH_APPS_NAME_PATH_BLOCK= # Comma-separated list of required LDAP groups. -TINYAUTH_APPS_[NAME]_LDAP_GROUPS= +TINYAUTH_APPS_NAME_LDAP_GROUPS= # Comma-separated list of allowed OAuth domains. TINYAUTH_OAUTH_WHITELIST= @@ -106,34 +106,34 @@ TINYAUTH_OAUTH_WHITELIST= TINYAUTH_OAUTH_AUTOREDIRECT= # OAuth client ID. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTID= +TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTID= # OAuth client secret. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRET= +TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTSECRET= # Path to the file containing the OAuth client secret. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_CLIENTSECRETFILE= +TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTSECRETFILE= # OAuth scopes. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_SCOPES= +TINYAUTH_OAUTH_PROVIDERS_NAME_SCOPES= # OAuth redirect URL. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_REDIRECTURL= +TINYAUTH_OAUTH_PROVIDERS_NAME_REDIRECTURL= # OAuth authorization URL. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_AUTHURL= +TINYAUTH_OAUTH_PROVIDERS_NAME_AUTHURL= # OAuth token URL. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_TOKENURL= +TINYAUTH_OAUTH_PROVIDERS_NAME_TOKENURL= # OAuth userinfo URL. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_USERINFOURL= +TINYAUTH_OAUTH_PROVIDERS_NAME_USERINFOURL= # Allow insecure OAuth connections. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_INSECURE=false +TINYAUTH_OAUTH_PROVIDERS_NAME_INSECURE=false # Provider name in UI. -TINYAUTH_OAUTH_PROVIDERS_[NAME]_NAME= +TINYAUTH_OAUTH_PROVIDERS_NAME_NAME= # Path to the private key file. TINYAUTH_OIDC_PRIVATEKEYPATH="./tinyauth_oidc_key" @@ -142,19 +142,19 @@ TINYAUTH_OIDC_PRIVATEKEYPATH="./tinyauth_oidc_key" TINYAUTH_OIDC_PUBLICKEYPATH="./tinyauth_oidc_key.pub" # OIDC client ID. -TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTID= +TINYAUTH_OIDC_CLIENTS_NAME_CLIENTID= # OIDC client secret. -TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRET= +TINYAUTH_OIDC_CLIENTS_NAME_CLIENTSECRET= # Path to the file containing the OIDC client secret. -TINYAUTH_OIDC_CLIENTS_[NAME]_CLIENTSECRETFILE= +TINYAUTH_OIDC_CLIENTS_NAME_CLIENTSECRETFILE= # List of trusted redirect URIs. -TINYAUTH_OIDC_CLIENTS_[NAME]_TRUSTEDREDIRECTURIS= +TINYAUTH_OIDC_CLIENTS_NAME_TRUSTEDREDIRECTURIS= # Client name in UI. -TINYAUTH_OIDC_CLIENTS_[NAME]_NAME= +TINYAUTH_OIDC_CLIENTS_NAME_NAME= # The title of the UI. TINYAUTH_UI_TITLE="Tinyauth" diff --git a/gen/gen_env.go b/gen/gen_env.go index f9524525..f5723dec 100644 --- a/gen/gen_env.go +++ b/gen/gen_env.go @@ -110,7 +110,7 @@ func buildMapPaths(field reflect.StructField, parentPath string, paths *[]Path) return } - mapPath := parentPath + strings.ToUpper(field.Name) + "_[NAME]_" + mapPath := parentPath + strings.ToUpper(field.Name) + "_NAME_" valueType := fieldType.Elem() if valueType.Kind() == reflect.Struct { From 8e3f10bc1f3f1c5478ed6a769a163fe5f3ca4d0f Mon Sep 17 00:00:00 2001 From: Stavros Date: Mon, 16 Feb 2026 23:36:12 +0200 Subject: [PATCH 6/6] refactor: use lowercase name to mark dynamic values --- .env.example | 60 +++++++++++++++++++++++++------------------------- gen/gen_env.go | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.env.example b/.env.example index c89d8ccc..091662f9 100644 --- a/.env.example +++ b/.env.example @@ -55,49 +55,49 @@ TINYAUTH_AUTH_LOGINMAXRETRIES=3 TINYAUTH_AUTH_TRUSTEDPROXIES= # The domain of the app. -TINYAUTH_APPS_NAME_CONFIG_DOMAIN= +TINYAUTH_APPS_name_CONFIG_DOMAIN= # Comma-separated list of allowed users. -TINYAUTH_APPS_NAME_USERS_ALLOW= +TINYAUTH_APPS_name_USERS_ALLOW= # Comma-separated list of blocked users. -TINYAUTH_APPS_NAME_USERS_BLOCK= +TINYAUTH_APPS_name_USERS_BLOCK= # Comma-separated list of allowed OAuth groups. -TINYAUTH_APPS_NAME_OAUTH_WHITELIST= +TINYAUTH_APPS_name_OAUTH_WHITELIST= # Comma-separated list of required OAuth groups. -TINYAUTH_APPS_NAME_OAUTH_GROUPS= +TINYAUTH_APPS_name_OAUTH_GROUPS= # List of allowed IPs or CIDR ranges. -TINYAUTH_APPS_NAME_IP_ALLOW= +TINYAUTH_APPS_name_IP_ALLOW= # List of blocked IPs or CIDR ranges. -TINYAUTH_APPS_NAME_IP_BLOCK= +TINYAUTH_APPS_name_IP_BLOCK= # List of IPs or CIDR ranges that bypass authentication. -TINYAUTH_APPS_NAME_IP_BYPASS= +TINYAUTH_APPS_name_IP_BYPASS= # Custom headers to add to the response. -TINYAUTH_APPS_NAME_RESPONSE_HEADERS= +TINYAUTH_APPS_name_RESPONSE_HEADERS= # Basic auth username. -TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_USERNAME= +TINYAUTH_APPS_name_RESPONSE_BASICAUTH_USERNAME= # Basic auth password. -TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_PASSWORD= +TINYAUTH_APPS_name_RESPONSE_BASICAUTH_PASSWORD= # Path to the file containing the basic auth password. -TINYAUTH_APPS_NAME_RESPONSE_BASICAUTH_PASSWORDFILE= +TINYAUTH_APPS_name_RESPONSE_BASICAUTH_PASSWORDFILE= # Comma-separated list of allowed paths. -TINYAUTH_APPS_NAME_PATH_ALLOW= +TINYAUTH_APPS_name_PATH_ALLOW= # Comma-separated list of blocked paths. -TINYAUTH_APPS_NAME_PATH_BLOCK= +TINYAUTH_APPS_name_PATH_BLOCK= # Comma-separated list of required LDAP groups. -TINYAUTH_APPS_NAME_LDAP_GROUPS= +TINYAUTH_APPS_name_LDAP_GROUPS= # Comma-separated list of allowed OAuth domains. TINYAUTH_OAUTH_WHITELIST= @@ -106,34 +106,34 @@ TINYAUTH_OAUTH_WHITELIST= TINYAUTH_OAUTH_AUTOREDIRECT= # OAuth client ID. -TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTID= +TINYAUTH_OAUTH_PROVIDERS_name_CLIENTID= # OAuth client secret. -TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTSECRET= +TINYAUTH_OAUTH_PROVIDERS_name_CLIENTSECRET= # Path to the file containing the OAuth client secret. -TINYAUTH_OAUTH_PROVIDERS_NAME_CLIENTSECRETFILE= +TINYAUTH_OAUTH_PROVIDERS_name_CLIENTSECRETFILE= # OAuth scopes. -TINYAUTH_OAUTH_PROVIDERS_NAME_SCOPES= +TINYAUTH_OAUTH_PROVIDERS_name_SCOPES= # OAuth redirect URL. -TINYAUTH_OAUTH_PROVIDERS_NAME_REDIRECTURL= +TINYAUTH_OAUTH_PROVIDERS_name_REDIRECTURL= # OAuth authorization URL. -TINYAUTH_OAUTH_PROVIDERS_NAME_AUTHURL= +TINYAUTH_OAUTH_PROVIDERS_name_AUTHURL= # OAuth token URL. -TINYAUTH_OAUTH_PROVIDERS_NAME_TOKENURL= +TINYAUTH_OAUTH_PROVIDERS_name_TOKENURL= # OAuth userinfo URL. -TINYAUTH_OAUTH_PROVIDERS_NAME_USERINFOURL= +TINYAUTH_OAUTH_PROVIDERS_name_USERINFOURL= # Allow insecure OAuth connections. -TINYAUTH_OAUTH_PROVIDERS_NAME_INSECURE=false +TINYAUTH_OAUTH_PROVIDERS_name_INSECURE=false # Provider name in UI. -TINYAUTH_OAUTH_PROVIDERS_NAME_NAME= +TINYAUTH_OAUTH_PROVIDERS_name_NAME= # Path to the private key file. TINYAUTH_OIDC_PRIVATEKEYPATH="./tinyauth_oidc_key" @@ -142,19 +142,19 @@ TINYAUTH_OIDC_PRIVATEKEYPATH="./tinyauth_oidc_key" TINYAUTH_OIDC_PUBLICKEYPATH="./tinyauth_oidc_key.pub" # OIDC client ID. -TINYAUTH_OIDC_CLIENTS_NAME_CLIENTID= +TINYAUTH_OIDC_CLIENTS_name_CLIENTID= # OIDC client secret. -TINYAUTH_OIDC_CLIENTS_NAME_CLIENTSECRET= +TINYAUTH_OIDC_CLIENTS_name_CLIENTSECRET= # Path to the file containing the OIDC client secret. -TINYAUTH_OIDC_CLIENTS_NAME_CLIENTSECRETFILE= +TINYAUTH_OIDC_CLIENTS_name_CLIENTSECRETFILE= # List of trusted redirect URIs. -TINYAUTH_OIDC_CLIENTS_NAME_TRUSTEDREDIRECTURIS= +TINYAUTH_OIDC_CLIENTS_name_TRUSTEDREDIRECTURIS= # Client name in UI. -TINYAUTH_OIDC_CLIENTS_NAME_NAME= +TINYAUTH_OIDC_CLIENTS_name_NAME= # The title of the UI. TINYAUTH_UI_TITLE="Tinyauth" diff --git a/gen/gen_env.go b/gen/gen_env.go index f5723dec..8db51c97 100644 --- a/gen/gen_env.go +++ b/gen/gen_env.go @@ -110,7 +110,7 @@ func buildMapPaths(field reflect.StructField, parentPath string, paths *[]Path) return } - mapPath := parentPath + strings.ToUpper(field.Name) + "_NAME_" + mapPath := parentPath + strings.ToUpper(field.Name) + "_name_" valueType := fieldType.Elem() if valueType.Kind() == reflect.Struct {