veza/veza-backend-api/internal/config/cors.go
senke bbd8ed54de refactor(config): découper config.go par domaine (audit 2.7)
- env_helpers.go: getEnv*, parseLogAggregationLabels
- db_init.go: initDatabaseWithRetry
- redis_init.go: initRedis, filteredRedisLogger
- rabbitmq.go: getRabbitMQURL
- cors.go: CORS, cookies
- rate_limit.go: rate limit defaults
- services_init.go: initServices
- middlewares_init.go: initMiddlewares, SetupMiddleware
- config.go réduit de ~1487 à ~550 LOC
2026-02-15 14:44:33 +01:00

106 lines
3.1 KiB
Go

package config
import (
"net/http"
)
// getCookieSecure détermine si les cookies doivent être Secure
// Auto-detect: secure en production, insecure en développement
// Peut être forcé via COOKIE_SECURE=true/false
func getCookieSecure(env string) bool {
cookieSecureEnv := getEnv("COOKIE_SECURE", "")
if cookieSecureEnv != "" {
return getEnvBool("COOKIE_SECURE", false)
}
// Auto-detect: secure en production, insecure en développement
return (env == EnvProduction)
}
// getCookieSameSite détermine la politique SameSite pour les cookies
// strict par défaut pour sécurité maximale, lax en développement local
func getCookieSameSite(env string) string {
cookieSameSite := getEnv("COOKIE_SAME_SITE", "strict")
if env == EnvDevelopment && cookieSameSite == "strict" {
// En dev local, utiliser "lax" pour permettre le domaine local (APP_DOMAIN)
return "lax"
}
return cookieSameSite
}
// GetCookieSameSite retourne la valeur http.SameSite correspondante
func (c *Config) GetCookieSameSite() http.SameSite {
switch c.CookieSameSite {
case "lax":
return http.SameSiteLaxMode
case "none":
return http.SameSiteNoneMode
default:
return http.SameSiteStrictMode
}
}
// ShouldUseSecureCookies détermine si les cookies doivent être Secure
// Prend en compte la configuration explicite et l'environnement
func (c *Config) ShouldUseSecureCookies() bool {
return c.CookieSecure
}
// devDefaultCORSOrigins returns origins always allowed in development/staging.
// Generated from APP_DOMAIN so that changing the domain propagates everywhere.
func devDefaultCORSOrigins(appDomain string) []string {
return []string{
"http://" + appDomain,
"http://" + appDomain + ":3000",
"http://" + appDomain + ":5173",
"http://" + appDomain + ":8080",
}
}
// mergeCORSOrigins merges custom with base and deduplicates (order: base then custom).
func mergeCORSOrigins(base, custom []string) []string {
seen := make(map[string]bool)
out := make([]string, 0, len(base)+len(custom))
for _, o := range base {
if !seen[o] {
seen[o] = true
out = append(out, o)
}
}
for _, o := range custom {
if !seen[o] {
seen[o] = true
out = append(out, o)
}
}
return out
}
// getCORSOrigins charge les origines CORS avec defaults sécurisés selon l'environnement (P0-SECURITY)
// - development/staging: si CORS_ALLOWED_ORIGINS est défini, on le fusionne avec les defaults (APP_DOMAIN)
// pour que $APP_DOMAIN:5173 reste autorisé même avec une config partielle
// - production: CORS_ALLOWED_ORIGINS obligatoire, pas de merge
// - test: liste vide par défaut
func getCORSOrigins(env string, appDomain string) []string {
custom := getEnvStringSlice("CORS_ALLOWED_ORIGINS", nil)
switch env {
case EnvProduction:
if len(custom) > 0 {
return custom
}
return []string{}
case EnvTest:
if len(custom) > 0 {
return custom
}
return []string{}
case EnvDevelopment, EnvStaging:
base := devDefaultCORSOrigins(appDomain)
if len(custom) > 0 {
return mergeCORSOrigins(base, custom)
}
return base
default:
return []string{"http://" + appDomain + ":3000", "http://" + appDomain + ":5173"}
}
}