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 DemoHTTPSPort string // port HTTPS public à afficher dans l'URL des démos (443 = omis, sinon ex. NodePort) Kubeconfig string FrontendImage string BackendImage string LBTelegramImage string AppDownloadsDir string // OMNEX_APP_DOWNLOADS_DIR : répertoire des .apk téléchargeables (voir internal/downloads) // DockerHubUsername/Password : compte Docker Hub authentifié (droits // lecture seule) injecté dans chaque namespace de démo (voir // deploy/chart-gestion/registry-credentials) pour passer le rate-limit // de pull anonyme (100/6h par IP) à 200/6h. "" = pull anonyme (défaut). DockerHubUsername string DockerHubPassword 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"), DemoHTTPSPort: getenv("OMNEX_DEMO_HTTPS_PORT", "443"), Kubeconfig: os.Getenv("KUBECONFIG"), FrontendImage: os.Getenv("FRONTEND_IMAGE_APP"), BackendImage: os.Getenv("BACKEND_IMAGE_APP"), LBTelegramImage: os.Getenv("LBTELEGRAM_IMAGE_APP"), AppDownloadsDir: getenv("OMNEX_APP_DOWNLOADS_DIR", "/app-downloads"), DockerHubUsername: os.Getenv("OMNEX_DOCKERHUB_USERNAME"), DockerHubPassword: os.Getenv("OMNEX_DOCKERHUB_PASSWORD"), } 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 }