From 647b111d0bebca5b102f8fa88ff24edc35ca002d Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Tue, 2 Jun 2026 15:32:16 +0200 Subject: [PATCH] fix(server): serve /version on Lambda by excluding it from static-path fallback isStaticPath() only excluded /api/* and /health, so /version was falling through to the SPA file server on the Lambda Function URL path, returning index.html instead of the JSON build-metadata response added by PR #901. The HTTP/Cloud Run path was unaffected because mux.HandleFunc("/version", ...) is registered before the SPA catch-all in CreateHTTPServer. Add /version to the isStaticPath allowlist (same pattern as /health) so handleLambdaHTTPEvent routes it to app.API.HandleRequest, which already handles it correctly via the ExactPath:/version AuthPublic router entry. Also add test cases for /version and //version (double-slash normalised) to TestIsStaticPath. --- internal/server/static.go | 9 ++++++++- internal/server/static_test.go | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/server/static.go b/internal/server/static.go index aad2f468e..413f28966 100644 --- a/internal/server/static.go +++ b/internal/server/static.go @@ -170,7 +170,11 @@ func staticDirFromEnv() string { } // isStaticPath returns true if the path should be handled by the static file -// server rather than the API. API paths start with /api/ or are /health. +// server rather than the API. API paths start with /api/ or are /health or +// /version. /version is a public root-path endpoint (build metadata, no auth) +// registered in the API router table; it must not fall through to the SPA +// fallback on the Lambda path, matching the explicit mux.HandleFunc("/version") +// registration used on the HTTP/Cloud Run path in internal/server/http.go. // OIDC discovery paths (/.well-known/*) are intercepted earlier by the // transport layer via api.IsOIDCDiscoveryPath, so they never reach here. func isStaticPath(urlPath string) bool { @@ -183,6 +187,9 @@ func isStaticPath(urlPath string) bool { if clean == "/health" { return false } + if clean == "/version" { + return false + } return true } diff --git a/internal/server/static_test.go b/internal/server/static_test.go index b0de97288..c9480a2c2 100644 --- a/internal/server/static_test.go +++ b/internal/server/static_test.go @@ -94,6 +94,8 @@ func TestIsStaticPath(t *testing.T) { {"/app/dashboard", true}, {"//health", false}, // double-slash normalised to /health {"//api/test", false}, + {"/version", false}, // public build-metadata endpoint must reach API, not SPA + {"//version", false}, // double-slash normalised to /version } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) {