package config import ( "os" "strconv" "time" ) type Config struct { AppName string Environment string HTTPAddress string DatabaseURL string JWTIssuer string JWTSecret string AccessTokenTTL time.Duration RefreshTokenTTL time.Duration GatewayBootstrapToken string DefaultGatewayID string DefaultDNS []string DefaultVPNCIDR string DefaultGatewayHost string DefaultGatewayPubKey string } func Load() Config { return Config{ AppName: getenv("APP_NAME", "NexaVPN"), Environment: getenv("APP_ENV", "development"), HTTPAddress: getenv("HTTP_ADDRESS", ":8080"), DatabaseURL: getenv("DATABASE_URL", "postgres://nexavpn:nexavpn@localhost:5432/nexavpn?sslmode=disable"), JWTIssuer: getenv("JWT_ISSUER", "nexavpn"), JWTSecret: getenv("JWT_SECRET", "change-me-in-production"), AccessTokenTTL: time.Duration(getenvInt("ACCESS_TOKEN_TTL_SECONDS", 900)) * time.Second, RefreshTokenTTL: time.Duration(getenvInt("REFRESH_TOKEN_TTL_SECONDS", 2592000)) * time.Second, GatewayBootstrapToken: getenv("GATEWAY_BOOTSTRAP_TOKEN", "nexavpn-gateway-bootstrap"), DefaultGatewayID: getenv("DEFAULT_GATEWAY_ID", ""), DefaultDNS: splitCSV(getenv("DEFAULT_DNS_SERVERS", "10.20.0.53")), DefaultVPNCIDR: getenv("DEFAULT_VPN_CIDR", "100.96.0.0/24"), DefaultGatewayHost: getenv("DEFAULT_GATEWAY_ENDPOINT", "vpn.example.com:51820"), DefaultGatewayPubKey: getenv("DEFAULT_GATEWAY_PUBLIC_KEY", "replace-me"), } } func getenv(key, fallback string) string { if value := os.Getenv(key); value != "" { return value } return fallback } func getenvInt(key string, fallback int) int { if value := os.Getenv(key); value != "" { parsed, err := strconv.Atoi(value) if err == nil { return parsed } } return fallback } func splitCSV(value string) []string { if value == "" { return nil } var items []string start := 0 for i := range value { if value[i] == ',' { if start < i { items = append(items, value[start:i]) } start = i + 1 } } if start < len(value) { items = append(items, value[start:]) } return items }