package configs import ( "os" "strconv" "time" ) // API configuration constants const ( // Prefix for all API routes Prefix = "/api/v1" // Default values DefaultPort = "3000" DefaultDatabaseName = "app.db" DefaultJWTExpiryHours = 24 DefaultPasswordMinLen = 8 DefaultMaxLoginAttempts = 5 DefaultLockoutMinutes = 30 DefaultRateLimitReqs = 100 DefaultRateLimitWindow = 1 // minute ) // Environment variable keys const ( EnvPort = "PORT" EnvDatabaseName = "DB_NAME" EnvJWTSecret = "JWT_SECRET" EnvAppSecret = "APP_SECRET" EnvAppSecretCode = "APP_SECRET_CODE" EnvEncryptionKey = "ENCRYPTION_KEY" EnvCORSAllowedOrigin = "CORS_ALLOWED_ORIGIN" EnvLogLevel = "LOG_LEVEL" EnvDebugMode = "DEBUG_MODE" EnvDefaultAdminPassword = "DEFAULT_ADMIN_PASSWORD" EnvJWTAccessTTLHours = "JWT_ACCESS_TTL_HOURS" EnvJWTRefreshTTLDays = "JWT_REFRESH_TTL_DAYS" EnvJWTIssuer = "JWT_ISSUER" ) // GetEnv returns environment variable value or default func GetEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } // GetEnvInt returns environment variable as integer or default func GetEnvInt(key string, defaultValue int) int { if value := os.Getenv(key); value != "" { if intValue, err := strconv.Atoi(value); err == nil { return intValue } } return defaultValue } // GetEnvBool returns environment variable as boolean or default func GetEnvBool(key string, defaultValue bool) bool { if value := os.Getenv(key); value != "" { if boolValue, err := strconv.ParseBool(value); err == nil { return boolValue } } return defaultValue } // GetEnvDuration returns environment variable as duration or default func GetEnvDuration(key string, defaultValue time.Duration) time.Duration { if value := os.Getenv(key); value != "" { if duration, err := time.ParseDuration(value); err == nil { return duration } } return defaultValue } // Config holds application configuration type Config struct { // Server configuration Port string DatabaseName string LogLevel string DebugMode bool // Security configuration JWTSecret string AppSecret string AppSecretCode string EncryptionKey string JWTAccessTTLHours int JWTRefreshTTLDays int JWTIssuer string PasswordMinLength int MaxLoginAttempts int LockoutDurationMins int // CORS configuration CORSAllowedOrigin string // Rate limiting RateLimitRequests int RateLimitWindow int // minutes // Admin configuration DefaultAdminPassword string } // LoadConfig loads configuration from environment variables func LoadConfig() *Config { return &Config{ // Server configuration Port: GetEnv(EnvPort, DefaultPort), DatabaseName: GetEnv(EnvDatabaseName, DefaultDatabaseName), LogLevel: GetEnv(EnvLogLevel, "INFO"), DebugMode: GetEnvBool(EnvDebugMode, false), // Security configuration JWTSecret: GetEnv(EnvJWTSecret, ""), AppSecret: GetEnv(EnvAppSecret, ""), AppSecretCode: GetEnv(EnvAppSecretCode, ""), EncryptionKey: GetEnv(EnvEncryptionKey, ""), JWTAccessTTLHours: GetEnvInt(EnvJWTAccessTTLHours, DefaultJWTExpiryHours), JWTRefreshTTLDays: GetEnvInt(EnvJWTRefreshTTLDays, 7), JWTIssuer: GetEnv(EnvJWTIssuer, "omega-server"), PasswordMinLength: GetEnvInt("PASSWORD_MIN_LENGTH", DefaultPasswordMinLen), MaxLoginAttempts: GetEnvInt("MAX_LOGIN_ATTEMPTS", DefaultMaxLoginAttempts), LockoutDurationMins: GetEnvInt("LOCKOUT_DURATION_MINUTES", DefaultLockoutMinutes), // CORS configuration CORSAllowedOrigin: GetEnv(EnvCORSAllowedOrigin, "http://localhost:5173"), // Rate limiting RateLimitRequests: GetEnvInt("RATE_LIMIT_REQUESTS", DefaultRateLimitReqs), RateLimitWindow: GetEnvInt("RATE_LIMIT_WINDOW_MINUTES", DefaultRateLimitWindow), // Admin configuration DefaultAdminPassword: GetEnv(EnvDefaultAdminPassword, ""), } } // Validate validates the configuration func (c *Config) Validate() []string { var errors []string // Required security settings if c.JWTSecret == "" { errors = append(errors, "JWT_SECRET is required") } if c.AppSecret == "" { errors = append(errors, "APP_SECRET is required") } if c.AppSecretCode == "" { errors = append(errors, "APP_SECRET_CODE is required") } if c.EncryptionKey == "" { errors = append(errors, "ENCRYPTION_KEY is required") } // Validate encryption key length (must be 32 characters for AES-256) if len(c.EncryptionKey) != 32 { errors = append(errors, "ENCRYPTION_KEY must be exactly 32 characters long") } // Validate JWT settings if c.JWTAccessTTLHours <= 0 { errors = append(errors, "JWT_ACCESS_TTL_HOURS must be greater than 0") } if c.JWTRefreshTTLDays <= 0 { errors = append(errors, "JWT_REFRESH_TTL_DAYS must be greater than 0") } // Validate password settings if c.PasswordMinLength < 8 { errors = append(errors, "PASSWORD_MIN_LENGTH must be at least 8") } // Validate rate limiting if c.RateLimitRequests <= 0 { errors = append(errors, "RATE_LIMIT_REQUESTS must be greater than 0") } if c.RateLimitWindow <= 0 { errors = append(errors, "RATE_LIMIT_WINDOW_MINUTES must be greater than 0") } return errors } // IsProduction returns true if running in production mode func (c *Config) IsProduction() bool { env := GetEnv("GO_ENV", "development") return env == "production" } // IsDevelopment returns true if running in development mode func (c *Config) IsDevelopment() bool { return !c.IsProduction() } // GetJWTAccessTTL returns JWT access token TTL as duration func (c *Config) GetJWTAccessTTL() time.Duration { return time.Duration(c.JWTAccessTTLHours) * time.Hour } // GetJWTRefreshTTL returns JWT refresh token TTL as duration func (c *Config) GetJWTRefreshTTL() time.Duration { return time.Duration(c.JWTRefreshTTLDays) * 24 * time.Hour } // GetLockoutDuration returns account lockout duration func (c *Config) GetLockoutDuration() time.Duration { return time.Duration(c.LockoutDurationMins) * time.Minute } // GetRateLimitWindow returns rate limit window as duration func (c *Config) GetRateLimitWindow() time.Duration { return time.Duration(c.RateLimitWindow) * time.Minute }