Skip to content

Commit 9a70f75

Browse files
committed
Update cors
1 parent e7029c2 commit 9a70f75

2 files changed

Lines changed: 73 additions & 1 deletion

File tree

backend/internal/middleware/cors.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ func TrackingCORSMiddleware() gin.HandlerFunc {
3333
}
3434

3535
c.Writer.Header().Set("Access-Control-Allow-Origin", origin) // dynamic origin
36+
c.Writer.Header().Set("Vary", "Origin")
3637
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
3738
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-API-Key")
38-
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
39+
40+
if origin != "*" {
41+
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
42+
}
43+
3944
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
4045

4146
if c.Request.Method == http.MethodOptions {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package middleware
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"testing"
7+
8+
"github.com/gin-gonic/gin"
9+
)
10+
11+
func TestTrackingCORSMiddleware(t *testing.T) {
12+
gin.SetMode(gin.TestMode)
13+
14+
t.Run("Origin header present", func(t *testing.T) {
15+
router := gin.New()
16+
router.Use(TrackingCORSMiddleware())
17+
router.POST("/api/track", func(c *gin.Context) {
18+
c.Status(http.StatusOK)
19+
})
20+
21+
w := httptest.NewRecorder()
22+
req, _ := http.NewRequest("POST", "/api/track", nil)
23+
req.Header.Set("Origin", "https://example.com")
24+
router.ServeHTTP(w, req)
25+
26+
if w.Header().Get("Access-Control-Allow-Origin") != "https://example.com" {
27+
t.Errorf("expected Access-Control-Allow-Origin to be https://example.com, got %s", w.Header().Get("Access-Control-Allow-Origin"))
28+
}
29+
if w.Header().Get("Access-Control-Allow-Credentials") != "true" {
30+
t.Errorf("expected Access-Control-Allow-Credentials to be true, got %s", w.Header().Get("Access-Control-Allow-Credentials"))
31+
}
32+
})
33+
34+
t.Run("Origin header missing", func(t *testing.T) {
35+
router := gin.New()
36+
router.Use(TrackingCORSMiddleware())
37+
router.POST("/api/track", func(c *gin.Context) {
38+
c.Status(http.StatusOK)
39+
})
40+
41+
w := httptest.NewRecorder()
42+
req, _ := http.NewRequest("POST", "/api/track", nil)
43+
router.ServeHTTP(w, req)
44+
45+
// This is the problematic case: Origin is * while Credentials is true
46+
if w.Header().Get("Access-Control-Allow-Origin") == "*" && w.Header().Get("Access-Control-Allow-Credentials") == "true" {
47+
t.Log("reproduced: Origin is * while Credentials is true, which causes browser errors")
48+
}
49+
})
50+
51+
t.Run("Vary header missing", func(t *testing.T) {
52+
router := gin.New()
53+
router.Use(TrackingCORSMiddleware())
54+
router.POST("/api/track", func(c *gin.Context) {
55+
c.Status(http.StatusOK)
56+
})
57+
58+
w := httptest.NewRecorder()
59+
req, _ := http.NewRequest("POST", "/api/track", nil)
60+
req.Header.Set("Origin", "https://example.com")
61+
router.ServeHTTP(w, req)
62+
63+
if w.Header().Get("Vary") != "Origin" {
64+
t.Log("reproduced: Vary: Origin header is missing")
65+
}
66+
})
67+
}

0 commit comments

Comments
 (0)