veza/veza-backend-api/internal/config/cors.go
senke 73eca4f6ad feat: backend, stream server & infra improvements
Backend (Go):
- Config: CORS, RabbitMQ, rate limit, main config updates
- Routes: core, distribution, tracks routing changes
- Middleware: rate limiter, endpoint limiter, response cache hardening
- Handlers: distribution, search handler fixes
- Workers: job worker improvements
- Upload validator and logging config additions
- New migrations: products, orders, performance indexes
- Seed tooling and data

Stream Server (Rust):
- Audio processing, config, routes, simple stream server updates
- Dockerfile improvements

Infrastructure:
- docker-compose.yml updates
- nginx-rtmp config changes
- Makefile improvements (config, dev, high, infra)
- Root package.json and lock file updates
- .env.example updates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:36:06 +01:00

132 lines
3.9 KiB
Go

package config
import (
"net/http"
"net/url"
"strings"
)
// 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 + ":18080",
}
}
// 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"}
}
}
// getOAuthAllowedRedirectDomains returns the whitelist of domains allowed for OAuth redirect (v0.902).
// If OAUTH_ALLOWED_REDIRECT_DOMAINS is set, use it. Otherwise derive from CORSOrigins or FrontendURL.
func getOAuthAllowedRedirectDomains(env string, explicit []string, corsOrigins []string, frontendURL string) []string {
if len(explicit) > 0 {
return explicit
}
if len(corsOrigins) > 0 {
return corsOrigins
}
if frontendURL != "" {
if u, err := url.Parse(frontendURL); err == nil {
origin := strings.TrimSuffix(u.String(), "/")
if u.Scheme != "" && u.Host != "" {
return []string{origin}
}
}
}
// Dev fallback
if env == EnvDevelopment || env == EnvStaging {
return []string{"http://localhost:5173", "http://localhost:3000", "http://127.0.0.1:5173", "http://127.0.0.1:3000"}
}
return []string{}
}