mirror of
https://github.com/GMWalletApp/epusdt.git
synced 2026-07-07 18:26:16 +00:00
fix(server): prevent SPA fallback from swallowing API routes
- add ShouldSkipSPAFallback() deny prefixes: /api, /admin/api, /payments, /pay - apply StaticWithConfig Skipper in both main http server and install server - add unit tests for fallback skip matching behavior
This commit is contained in:
@@ -6,6 +6,25 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var spaFallbackDenyPrefixes = []string{
|
||||
"/api",
|
||||
"/admin/api",
|
||||
"/payments",
|
||||
"/pay",
|
||||
}
|
||||
|
||||
// ShouldSkipSPAFallback reports whether a request path should bypass
|
||||
// server-side SPA fallback to index.html and continue normal backend routing.
|
||||
func ShouldSkipSPAFallback(requestPath string) bool {
|
||||
for _, prefix := range spaFallbackDenyPrefixes {
|
||||
if requestPath == prefix || strings.HasPrefix(requestPath, prefix+"/") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ResolveSPAFilePath normalizes a wildcard SPA path and maps it under wwwRoot.
|
||||
// It strips any leading slash and blocks path traversal outside wwwRoot.
|
||||
// The second return value indicates whether the caller should try os.Stat
|
||||
|
||||
@@ -66,3 +66,32 @@ func TestResolveSPAFilePath(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldSkipSPAFallback(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
want bool
|
||||
}{
|
||||
{name: "api root", path: "/api", want: true},
|
||||
{name: "api sub path", path: "/api/install/defaults", want: true},
|
||||
{name: "admin api root", path: "/admin/api", want: true},
|
||||
{name: "admin api sub path", path: "/admin/api/v1/orders", want: true},
|
||||
{name: "payments root", path: "/payments", want: true},
|
||||
{name: "payments sub path", path: "/payments/gmpay/v1/order/create-transaction", want: true},
|
||||
{name: "pay root", path: "/pay", want: true},
|
||||
{name: "pay sub path", path: "/pay/checkout-counter/abc", want: true},
|
||||
{name: "not exact prefix", path: "/apiary", want: false},
|
||||
{name: "normal spa route", path: "/install", want: false},
|
||||
{name: "normal asset route", path: "/assets/index.js", want: false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ShouldSkipSPAFallback(tt.path)
|
||||
if got != tt.want {
|
||||
t.Fatalf("ShouldSkipSPAFallback(%q) = %v, want %v", tt.path, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user