Skip to content

fix(auth0): map given_name/family_name to User (#430)#643

Open
yabanci wants to merge 1 commit into
markbates:masterfrom
yabanci:fix/auth0-name-fields
Open

fix(auth0): map given_name/family_name to User (#430)#643
yabanci wants to merge 1 commit into
markbates:masterfrom
yabanci:fix/auth0-name-fields

Conversation

@yabanci
Copy link
Copy Markdown

@yabanci yabanci commented May 17, 2026

What

Closes #430.

providers/auth0/auth0.go:userFromReader only extracted a subset of the OIDC claims returned by Auth0's /userinfo endpoint:

type auth0UserResp struct {
    Name      string `json:"name"`
    NickName  string `json:"nickname"`
    Email     string `json:"email"`
    UserID    string `json:"sub"`
    AvatarURL string `json:"picture"`
}

given_name and family_name — standard OIDC claims that Auth0 returns alongside name/email/sub — were silently dropped, even though goth.User has FirstName and LastName fields ready for them. The reporter (@justman00) hit this while wiring Auth0 to a goth.User consumer.

Change

Add the two fields to auth0UserResp and map them in userFromReader. Matches how the Google provider already handles the same OIDC claims (providers/google/google.go:googleUser):

FirstName string `json:"given_name"`
LastName  string `json:"family_name"`
user.FirstName = u.FirstName
user.LastName  = u.LastName

Scope

The reporter also listed email_verified, locale, and updated_at as unmapped. None of these has a typed slot on goth.User (no EmailVerified, no Locale), so promoting them to typed fields would require adding fields to the shared goth.User struct — out of scope for an Auth0-specific bug fix, and visible to every provider. Those claims already land in user.RawData and remain readable from there. I added an assertion to Test_FetchUser to lock that contract in so future refactors don't silently drop them.

Backward compatibility

Strictly additive — no existing field's mapping is touched. Callers that read user.FirstName / user.LastName from Auth0 used to get empty strings and now get the real values. Callers that don't read them are unaffected.

Tests

Extended Test_FetchUser to:

  1. Include given_name/family_name in the sample /userinfo response.
  2. Differentiate name from given_name/family_name so each assertion exercises a distinct claim (the existing sample used the email address for name, which hid this exact class of bug).
  3. Assert u.FirstName == "Test", u.LastName == "User".
  4. Assert u.RawData["email_verified"] == false to lock the RawData fallback contract.

Verified the new assertions fail on master (FirstName/LastName come back empty), pass with the fix applied. Full go test ./... is green across all 50+ providers; go vet ./... is clean.

The auth0 provider's userFromReader only extracted name, nickname,
email, sub, and picture from the /userinfo response, dropping the
OIDC-standard given_name and family_name claims that Auth0 returns
alongside them. goth.User.FirstName and goth.User.LastName ended up
empty even though the data was right there in the response.

Add the two fields to auth0UserResp and map them in userFromReader,
matching how the Google provider already handles the same OIDC claims
(providers/google/google.go). Other Auth0-specific fields without a
typed slot on goth.User (email_verified, locale, updated_at) remain
accessible via user.RawData as before.

Extended Test_FetchUser to assert both the new mapping and that
unmapped fields stay readable via RawData.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auth0 provider doesn't attribute all the values to goth.User

1 participant