// Package config charge la configuration depuis l'environnement. // Secure by design : aucun secret par défaut en dur, tout vient de l'env. package config import ( "errors" "os" "time" ) type Config struct { Addr string JWTSecret []byte // OMNEX_JWT_SECRET (min 32 octets) — signe les tokens SessionTTL time.Duration // durée de vie JWT + session Redis AllowedOrigins []string // CORS (vitrine + back-office) Env string // "dev" | "prod" DatabaseURL string // OMNEX_DATABASE_URL (DSN PostgreSQL GORM) RedisURL string // OMNEX_REDIS_URL (sessions), ex. redis://:pass@host:6379/0 DemoDomain string // domaine des démos RegistrationCode string // OMNEX_REGISTRATION_CODE (vide = inscription ouverte) Kubeconfig string FrontendImage string BackendImage string } // Load lit la config. Fail-secure : secret JWT obligatoire ; en prod base + Redis aussi. func Load() (Config, error) { secret := os.Getenv("OMNEX_JWT_SECRET") if len(secret) < 32 { return Config{}, errors.New("OMNEX_JWT_SECRET manquant ou < 32 octets") } cfg := Config{ Addr: getenv("OMNEX_ADDR", ":8080"), JWTSecret: []byte(secret), SessionTTL: 24 * time.Hour, AllowedOrigins: splitCSV(getenv("OMNEX_ALLOWED_ORIGINS", "http://localhost:5173")), Env: getenv("OMNEX_ENV", "dev"), DatabaseURL: os.Getenv("OMNEX_DATABASE_URL"), RedisURL: os.Getenv("OMNEX_REDIS_URL"), DemoDomain: getenv("OMNEX_DEMO_DOMAIN", "demo.omnex.app"), RegistrationCode: os.Getenv("OMNEX_REGISTRATION_CODE"), Kubeconfig: os.Getenv("KUBECONFIG"), FrontendImage: os.Getenv("FRONTEND_IMAGE_APP"), BackendImage: os.Getenv("BACKEND_IMAGE_APP"), } if cfg.Env == "prod" { if cfg.DatabaseURL == "" { return Config{}, errors.New("OMNEX_DATABASE_URL requis en prod") } if cfg.RedisURL == "" { return Config{}, errors.New("OMNEX_REDIS_URL requis en prod (sessions)") } } return cfg, nil } // Secure indique si les cookies doivent porter l'attribut Secure (HTTPS). func (c Config) Secure() bool { return c.Env == "prod" } func getenv(k, def string) string { if v := os.Getenv(k); v != "" { return v } return def } func splitCSV(s string) []string { var out []string start := 0 for i := 0; i <= len(s); i++ { if i == len(s) || s[i] == ',' { if seg := s[start:i]; seg != "" { out = append(out, seg) } start = i + 1 } } return out }