Microsoft Entra ID type incorrect #1642

Closed
opened 2026-03-13 08:53:02 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @budivoogt on GitHub (Aug 5, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

With this microsoft config, I found that the profile argument in the mapProfileToUser callback had the wrong types.

Image

I first failed to get the email to return on the profile.email field, to later find that this field isn't returned by Microsoft at all.

It's critical a user sets the right scopes to be returned. Once you've done that, I found the response type to have this format:

export interface MicrosoftOAuthProfile {
	aud: string
	iss: string
	iat: number
	nbf: number
	exp: number
	ctry?: string
	family_name: string
	given_name: string
	name: string
	oid: string
	preferred_username: string
	rh?: string
	sid: string
	sub: string
	tid: string
	uti: string
	ver: string
	picture?: string // May not always be present
}

It may make sense to update the following type in the lib:

interface MicrosoftEntraIDProfile extends Record<string, any> {
    sub: string;
    name: string;
    email: string;
    picture: string;
}

Current vs. Expected behavior

See above.

What version of Better Auth are you using?

1.2.10

Provide environment information

Not relevant.

Which area(s) are affected? (Select all that apply)

Types

Auth config (if applicable)


Additional context

No response

Originally created by @budivoogt on GitHub (Aug 5, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce With this microsoft config, I found that the `profile` argument in the `mapProfileToUser` callback had the wrong types. <img width="1656" height="930" alt="Image" src="https://github.com/user-attachments/assets/f6b77bac-c40a-490a-a42b-09da2a5d3d0f" /> I first failed to get the email to return on the `profile.email` field, to later find that this field isn't returned by Microsoft at all. It's critical a user sets the [right scopes](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc) to be returned. Once you've done that, I found the response type to have this format: ``` export interface MicrosoftOAuthProfile { aud: string iss: string iat: number nbf: number exp: number ctry?: string family_name: string given_name: string name: string oid: string preferred_username: string rh?: string sid: string sub: string tid: string uti: string ver: string picture?: string // May not always be present } ``` It may make sense to update the following type in the lib: ``` interface MicrosoftEntraIDProfile extends Record<string, any> { sub: string; name: string; email: string; picture: string; } ``` ### Current vs. Expected behavior See above. ### What version of Better Auth are you using? 1.2.10 ### Provide environment information ```bash Not relevant. ``` ### Which area(s) are affected? (Select all that apply) Types ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
Author
Owner

@dosubot[bot] commented on GitHub (Aug 5, 2025):

You're right—the current MicrosoftEntraIDProfile type in Better Auth only includes sub, name, email, and picture, but the actual Microsoft Entra ID idToken can return a much broader set of claims like aud, iss, iat, nbf, exp, family_name, given_name, oid, preferred_username, sid, tid, uti, ver, and more. Some fields (like email) are only present if the right scopes are set (e.g., "email" scope) see here.

The type definition in the library doesn't fully match the real Microsoft profile structure see code. For better type safety and DX, it would make sense to update MicrosoftEntraIDProfile to reflect the actual idToken claims, making fields like email and picture optional, and including the other standard claims.

Also, make sure your config requests the scopes you need (like "email" and "profile") to get those fields in the token. If you need a more accurate type right now, you can define your own interface based on the real Microsoft response and use it in your mapProfileToUser callback.

There are ongoing discussions about this mismatch and the need for more accurate typing in the library see discussion. Updating the type and adding documentation about required scopes would help avoid this confusion for others.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Aug 5, 2025): <!-- Answer --> You're right—the current MicrosoftEntraIDProfile type in Better Auth only includes sub, name, email, and picture, but the actual Microsoft Entra ID idToken can return a much broader set of claims like aud, iss, iat, nbf, exp, family_name, given_name, oid, preferred_username, sid, tid, uti, ver, and more. Some fields (like email) are only present if the right scopes are set (e.g., "email" scope) [see here](https://github.com/better-auth/better-auth/issues/611). The type definition in the library doesn't fully match the real Microsoft profile structure [see code](https://github.com/better-auth/better-auth/blob/669ce3e6b737ce7c1a9ce982bf092f00d7373fbc/packages/better-auth/src/social-providers/microsoft-entra-id.ts). For better type safety and DX, it would make sense to update MicrosoftEntraIDProfile to reflect the actual idToken claims, making fields like email and picture optional, and including the other standard claims. Also, make sure your config requests the scopes you need (like "email" and "profile") to get those fields in the token. If you need a more accurate type right now, you can define your own interface based on the real Microsoft response and use it in your mapProfileToUser callback. There are ongoing discussions about this mismatch and the need for more accurate typing in the library [see discussion](https://github.com/better-auth/better-auth/issues/2123). Updating the type and adding documentation about required scopes would help avoid this confusion for others. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/37432bf1-2e9b-4ff2-be22-b4124655ffca?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/3802)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1642