Make product API versions independently installable

This commit is contained in:
Stephan D committed 2026-09-13 10:26:06 +02:00
1 parent ce6583f454
commit d04c8b12ab
69 files changed
+755 -404

No files matched your search

+16 -3
View File
@@ -1,9 +1,9 @@
package browser
import (
"context"
"net/http"
"net/url"
"os"
"path"
"strings"
"time"
@@ -86,8 +86,10 @@ func ValidateCSRF(r *http.Request, allowedOrigins []string) error {
func cookiePath(r *http.Request) string {
const accountsSegment = "/accounts"
if apiEndpoint := strings.TrimSpace(os.Getenv("API_ENDPOINT")); apiEndpoint != "" {
return path.Join("/", apiEndpoint, accountsSegment)
if r != nil {
if mount, ok := r.Context().Value(scopeKey{}).(string); ok {
return path.Join(mount, accountsSegment)
}
}
if r != nil && r.URL != nil {
if index := strings.Index(r.URL.Path, accountsSegment); index >= 0 {
@@ -119,3 +121,14 @@ func originAllowed(origin string, allowedOrigins []string) bool {
}
return false
}
type scopeKey struct{}
// Scope binds cookie creation and deletion to a validated installed API mount.
func Scope(mount string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), scopeKey{}, mount)))
})
}
}
@@ -31,13 +31,15 @@ func TestSetRefreshCookieUsesHardenedHostOnlyPolicy(t *testing.T) {
require.Positive(t, cookie.MaxAge)
}
func TestSetRefreshCookieUsesConfiguredAPIPathOutsideAccountsRouter(t *testing.T) {
func TestSetRefreshCookieUsesInstalledScopeOutsideAccountsRouter(t *testing.T) {
t.Setenv("API_ENDPOINT", "/gateway/v2/")
req := httptest.NewRequest(http.MethodPost, "https://app.sendico.io/gateway/v2/verification/login", nil)
req.Header.Set(TransportHeader, TransportCookie)
recorder := httptest.NewRecorder()
SetRefreshCookie(recorder, req, "refresh", time.Now().Add(time.Hour))
Scope("/gateway/v2")(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
SetRefreshCookie(w, r, "refresh", time.Now().Add(time.Hour))
})).ServeHTTP(recorder, req)
require.Equal(t, "/gateway/v2/accounts", recorder.Result().Cookies()[0].Path)
}