From adaa21a9c7fc1adefd38417e28b731657f420822 Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Thu, 23 Apr 2026 12:00:19 -0400 Subject: [PATCH] feat(google): populate given_name, family_name, and locale in user metadata Google's OIDC ID token includes given_name, family_name, and locale as standard claims, but the Google provider was silently dropping them. The Claims struct already has fields for these (used by LinkedIn), but the googleUser struct lacked the corresponding JSON fields and parseGoogleIDToken never mapped them. This adds the missing fields to googleUser and maps them in both the ID token path (parseGoogleIDToken) and the legacy userinfo endpoint fallback (GetUserData), matching the pattern used by the LinkedIn provider. Co-Authored-By: Claude Opus 4.6 (1M context) --- internal/api/external_google_test.go | 6 +++--- internal/api/provider/google.go | 6 ++++++ internal/api/provider/oidc.go | 13 +++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/internal/api/external_google_test.go b/internal/api/external_google_test.go index 2ed5cb1975..d3f63891d4 100644 --- a/internal/api/external_google_test.go +++ b/internal/api/external_google_test.go @@ -12,9 +12,9 @@ import ( ) const ( - googleUser string = `{"id":"googleTestId","name":"Google Test","picture":"http://example.com/avatar","email":"google@example.com","verified_email":true}}` - googleUserWrongEmail string = `{"id":"googleTestId","name":"Google Test","picture":"http://example.com/avatar","email":"other@example.com","verified_email":true}}` - googleUserNoEmail string = `{"id":"googleTestId","name":"Google Test","picture":"http://example.com/avatar","verified_email":false}}` + googleUser string = `{"id":"googleTestId","name":"Google Test","given_name":"Google","family_name":"Test","picture":"http://example.com/avatar","email":"google@example.com","verified_email":true,"locale":"en"}` + googleUserWrongEmail string = `{"id":"googleTestId","name":"Google Test","given_name":"Google","family_name":"Test","picture":"http://example.com/avatar","email":"other@example.com","verified_email":true,"locale":"en"}` + googleUserNoEmail string = `{"id":"googleTestId","name":"Google Test","given_name":"Google","family_name":"Test","picture":"http://example.com/avatar","verified_email":false}` ) func (ts *ExternalTestSuite) TestSignupExternalGoogle() { diff --git a/internal/api/provider/google.go b/internal/api/provider/google.go index 0d7f3fd28c..dd4f33372f 100644 --- a/internal/api/provider/google.go +++ b/internal/api/provider/google.go @@ -15,11 +15,14 @@ type googleUser struct { Subject string `json:"sub"` Issuer string `json:"iss"` Name string `json:"name"` + GivenName string `json:"given_name"` + FamilyName string `json:"family_name"` AvatarURL string `json:"picture"` Email string `json:"email"` VerifiedEmail bool `json:"verified_email"` EmailVerified bool `json:"email_verified"` HostedDomain string `json:"hd"` + Locale string `json:"locale"` } func (u googleUser) IsEmailVerified() bool { @@ -122,9 +125,12 @@ func (g googleProvider) GetUserData(ctx context.Context, tok *oauth2.Token) (*Us Issuer: internalUserInfoEndpointGoogle, Subject: u.ID, Name: u.Name, + GivenName: u.GivenName, + FamilyName: u.FamilyName, Picture: u.AvatarURL, Email: u.Email, EmailVerified: u.IsEmailVerified(), + Locale: u.Locale, // To be deprecated AvatarURL: u.AvatarURL, diff --git a/internal/api/provider/oidc.go b/internal/api/provider/oidc.go index daadf5456e..c4682e2280 100644 --- a/internal/api/provider/oidc.go +++ b/internal/api/provider/oidc.go @@ -105,10 +105,15 @@ func parseGoogleIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, } data.Metadata = &Claims{ - Issuer: claims.Issuer, - Subject: claims.Subject, - Name: claims.Name, - Picture: claims.AvatarURL, + Issuer: claims.Issuer, + Subject: claims.Subject, + Name: claims.Name, + GivenName: claims.GivenName, + FamilyName: claims.FamilyName, + Picture: claims.AvatarURL, + Email: claims.Email, + EmailVerified: claims.IsEmailVerified(), + Locale: claims.Locale, // To be deprecated AvatarURL: claims.AvatarURL,