package config import ( "fmt" "os" "strings" ) type Config struct { Port string AppURL string AutheliaURL string AutheliaInternalURL string StripeSecretKey string StripeWebhookSecret string StripePriceID string // Fallback when tier prices not set StripePaymentLink string // Optional: legacy Payment Link for $0 StripePriceIDFree string // $0/3mo, auto-cancel (first 10) StripePriceIDYear string // $20/year (customers 11–50) StripePriceIDMonth100 string // $100/month (after year for 11–50) StripePriceIDMonth200 string // $200/month (customers 51+) FreeTierLimit int // First N get free tier (default 10) YearTierLimit int // Up to this count get year tier (default 50) MaxSignups int // Cap on new signups (0 = no limit) LDAPUrl string LDAPAdminDN string LDAPAdminPassword string LDAPBaseDN string LLDAPHttpURL string DockerHost string TraefikDomain string TraefikNetwork string TemplatePath string CustomerDomain string ArchivePath string LandingTagline string // Main tagline under logo LandingFeatures []string // Bullet points on subscribe card (comma-separated in env) } func Load() *Config { return &Config{ Port: envOrDefault("PORT", "8080"), AppURL: envOrDefault("APP_URL", "https://bc.a250.ca"), AutheliaURL: envOrDefault("AUTHELIA_URL", "https://bc.a250.ca/login"), AutheliaInternalURL: envOrDefault("AUTHELIA_INTERNAL_URL", "http://authelia_dev_main:9091/login"), StripeSecretKey: envOrDefault("STRIPE_SECRET_KEY", ""), StripeWebhookSecret: envOrDefault("STRIPE_WEBHOOK_SECRET", ""), StripePriceID: envOrDefault("STRIPE_PRICE_ID", ""), StripePaymentLink: envOrDefault("STRIPE_PAYMENT_LINK", ""), StripePriceIDFree: envOrDefault("STRIPE_PRICE_ID_FREE", ""), StripePriceIDYear: envOrDefault("STRIPE_PRICE_ID_YEAR", ""), StripePriceIDMonth100: envOrDefault("STRIPE_PRICE_ID_MONTH_100", ""), StripePriceIDMonth200: envOrDefault("STRIPE_PRICE_ID_MONTH_200", ""), FreeTierLimit: envIntOrDefault("FREE_TIER_LIMIT", 10), YearTierLimit: envIntOrDefault("YEAR_TIER_LIMIT", 50), MaxSignups: envIntOrDefault("MAX_SIGNUPS", 0), LDAPUrl: envOrDefault("LLDAP_URL", "ldap://lldap_lldap:3890"), LDAPAdminDN: envOrDefault("LLDAP_ADMIN_DN", "uid=admin,ou=people,dc=a250,dc=ca"), LDAPAdminPassword: envOrDefault("LLDAP_ADMIN_PASSWORD", ""), LDAPBaseDN: envOrDefault("LLDAP_BASE_DN", "dc=a250,dc=ca"), LLDAPHttpURL: envOrDefault("LLDAP_HTTP_URL", "http://lldap:17170"), DockerHost: envOrDefault("DOCKER_HOST", "unix:///var/run/docker.sock"), TraefikDomain: envOrDefault("TRAEFIK_DOMAIN", "bc.a250.ca"), TraefikNetwork: envOrDefault("TRAEFIK_NETWORK", "authelia_dev"), TemplatePath: envOrDefault("TEMPLATE_PATH", "/app/templates"), CustomerDomain: envOrDefault("CUSTOMER_DOMAIN", "bc.a250.ca"), ArchivePath: envOrDefault("ARCHIVE_PATH", "/archives"), LandingTagline: envOrDefault("LANDING_TAGLINE", "Your own workspace, ready in minutes."), LandingFeatures: envListOrDefault("LANDING_FEATURES", []string{"Dedicated environment", "Secure single sign-on", "Automatic provisioning", "Manage subscription anytime"}), } } func envOrDefault(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func envIntOrDefault(key string, fallback int) int { if v := os.Getenv(key); v != "" { var n int if _, err := fmt.Sscanf(v, "%d", &n); err == nil { return n } } return fallback } func envListOrDefault(key string, fallback []string) []string { if v := os.Getenv(key); v != "" { parts := strings.Split(v, "|") out := make([]string, 0, len(parts)) for _, p := range parts { if s := strings.TrimSpace(p); s != "" { out = append(out, s) } } if len(out) > 0 { return out } } return fallback }