3.4 KiB
3.4 KiB
Plan: Fix CORS Configuration
Scope: Trivial — 3 files, ~20 lines
Goal: Ensure server-core CORS properly accepts requests from frontend origins, configurable via CORS_ALLOWED_ORIGINS env var, documented in .env.example.
Context
Current CORS config in main.go:114-130:
- Uses
CORS_ALLOWED_ORIGINSenv var (defaults to*) - Has BOTH
AllowOriginsANDAllowOriginFunc— redundant strings.Contains(corsOrigins, origin)is weak (substring match:"example.com"matches"notexample.com")AllowCredentials: trueis needed for JWTAuthorizationheaderCORS_ALLOWED_ORIGINSis NOT documented in any.env.examplefileSHARE_LINK_TTL(from Phase 5.0) also missing from.env.example
Task 1: Fix CORS config in main.go
- File:
apps/server-core/main.golines 114-130
Replace the current CORS block with:
// CORS Configuration
corsOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
if corsOrigins == "" {
corsOrigins = "*"
}
corsConfig := cors.Config{
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization", "X-Admin-Key", "X-Device-Token"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
}
if corsOrigins == "*" {
// Wildcard: allow all origins but use AllowOriginFunc so the response
// header echoes the actual origin (required when AllowCredentials=true).
corsConfig.AllowOriginFunc = func(origin string) bool {
return true
}
} else {
// Explicit list: split by comma, trim spaces, exact match only.
origins := strings.Split(corsOrigins, ",")
for i := range origins {
origins[i] = strings.TrimSpace(origins[i])
}
corsConfig.AllowOrigins = origins
}
r.Use(cors.New(corsConfig))
Key changes:
- Remove simultaneous
AllowOrigins+AllowOriginFunc(pick one based on*vs explicit) - When
*: useAllowOriginFuncreturningtrue→ gin-contrib/cors echoes the requesting origin (compatible withAllowCredentials: true) - When explicit: use
AllowOriginswith trimmed values, exact match (no morestrings.Containssubstring bug)
Verify: go build ./... passes
Task 2: Add CORS_ALLOWED_ORIGINS to root .env.example
- File:
.env.example
Add after VITE_API_BASE_URL line (section 5):
# 7. CORS Configuration
# Comma-separated list of allowed origins for the API.
# Use '*' to allow all origins (NOT recommended for production).
# Example: https://dash.yourdomain.com,https://admin.yourdomain.com
CORS_ALLOWED_ORIGINS=http://localhost:5173
# 8. Share Link Configuration
# TTL for peer config share links (Go duration format)
SHARE_LINK_TTL=24h
Task 3: Add CORS_ALLOWED_ORIGINS to server-core .env.example
- File:
apps/server-core/.env.example
Add at the end:
# CORS
# Comma-separated allowed origins. '*' = allow all (not recommended for production)
CORS_ALLOWED_ORIGINS=http://localhost:5173
# Share Link TTL (Go duration format)
SHARE_LINK_TTL=24h
Verify: all .env.example files contain CORS_ALLOWED_ORIGINS
Final Verification Wave
go build ./...passes inapps/server-core/CORS_ALLOWED_ORIGINSpresent in root.env.exampleCORS_ALLOWED_ORIGINSpresent inapps/server-core/.env.example- No other files reference
CORS_ALLOWED_ORIGINSthat need updating