From faa63dbba444b3145a453f6f0d3a08a52c245797 Mon Sep 17 00:00:00 2001 From: Muzzaiyyan Hussain Date: Sat, 15 Nov 2025 13:15:44 +0530 Subject: [PATCH] fix(auth): preserve query params in emailRedirectTo and redirect_to URLs --- internal/tokens/service.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/internal/tokens/service.go b/internal/tokens/service.go index 8650351d9..f57ac96ef 100644 --- a/internal/tokens/service.go +++ b/internal/tokens/service.go @@ -68,16 +68,36 @@ type RefreshTokenGrantParams struct { ClientID *uuid.UUID // OAuth2 server client ID if applicable } -// AsRedirectURL encodes the AccessTokenResponse as a redirect URL that -// includes the access token response data in a URL fragment. func (r *AccessTokenResponse) AsRedirectURL(redirectURL string, extraParams url.Values) string { + // Add Supabase’s internal params extraParams.Set("access_token", r.Token) extraParams.Set("token_type", r.TokenType) extraParams.Set("expires_in", strconv.Itoa(r.ExpiresIn)) extraParams.Set("expires_at", strconv.FormatInt(r.ExpiresAt, 10)) extraParams.Set("refresh_token", r.RefreshToken) - return redirectURL + "#" + extraParams.Encode() + // Parse original redirect URL + u, err := url.Parse(redirectURL) + if err != nil { + // fallback to previous behavior for malformed URLs + return redirectURL + "#" + extraParams.Encode() + } + + // Get existing query params from the original URL + origQuery := u.Query() + + // Merge user-provided params with Supabase-added params + for key, vals := range extraParams { + for _, v := range vals { + origQuery.Set(key, v) // overwrite if exists to avoid duplicates + } + } + + // Update the query params in the URL + u.RawQuery = origQuery.Encode() + + // Return the updated full URL + return u.String() } // HookManager interface for access token hooks