better-auth
Version:
The most comprehensive authentication framework for TypeScript.
1 lines • 4.04 kB
Source Map (JSON)
{"version":3,"file":"microsoft-entra-id.mjs","names":[],"sources":["../../../../src/plugins/generic-oauth/providers/microsoft-entra-id.ts"],"sourcesContent":["import type { OAuth2Tokens, OAuth2UserInfo } from \"@better-auth/core/oauth2\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport type { BaseOAuthProviderOptions, GenericOAuthConfig } from \"../index\";\n\nexport interface MicrosoftEntraIdOptions extends BaseOAuthProviderOptions {\n\t/**\n\t * Microsoft Entra ID tenant ID.\n\t * Can be a GUID, \"common\", \"organizations\", or \"consumers\"\n\t */\n\ttenantId: string;\n}\n\ninterface MicrosoftEntraIdProfile {\n\tsub: string;\n\tname?: string;\n\temail?: string;\n\tpreferred_username?: string;\n\tpicture?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\temail_verified?: boolean;\n}\n\n/**\n * Microsoft Entra ID (Azure AD) OAuth provider helper\n *\n * @example\n * ```ts\n * import { genericOAuth, microsoftEntraId } from \"better-auth/plugins/generic-oauth\";\n *\n * export const auth = betterAuth({\n * plugins: [\n * genericOAuth({\n * config: [\n * microsoftEntraId({\n * clientId: process.env.MS_APP_ID,\n * clientSecret: process.env.MS_CLIENT_SECRET,\n * tenantId: process.env.MS_TENANT_ID,\n * }),\n * ],\n * }),\n * ],\n * });\n * ```\n */\nexport function microsoftEntraId(\n\toptions: MicrosoftEntraIdOptions,\n): GenericOAuthConfig {\n\tconst defaultScopes = [\"openid\", \"profile\", \"email\"];\n\n\tconst tenantId = options.tenantId;\n\tconst authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;\n\tconst tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;\n\tconst userInfoUrl = \"https://graph.microsoft.com/oidc/userinfo\";\n\n\tconst getUserInfo = async (\n\t\ttokens: OAuth2Tokens,\n\t): Promise<OAuth2UserInfo | null> => {\n\t\tconst { data: profile, error } = await betterFetch<MicrosoftEntraIdProfile>(\n\t\t\tuserInfoUrl,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${tokens.accessToken}`,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (error || !profile) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tid: profile.sub,\n\t\t\tname:\n\t\t\t\tprofile.name ??\n\t\t\t\t(`${profile.given_name ?? \"\"} ${profile.family_name ?? \"\"}`.trim() ||\n\t\t\t\t\tundefined),\n\t\t\temail: profile.email ?? profile.preferred_username ?? undefined,\n\t\t\timage: profile.picture,\n\t\t\t// Note: Microsoft Entra ID does NOT include email_verified claim by default.\n\t\t\t// It must be configured as an optional claim in the app registration.\n\t\t\t// We default to false when not provided\n\t\t\t// The built-in provider hardcodes this to true, assuming Microsoft accounts are verified.\n\t\t\temailVerified: profile.email_verified ?? false,\n\t\t};\n\t};\n\n\treturn {\n\t\tproviderId: \"microsoft-entra-id\",\n\t\tauthorizationUrl,\n\t\ttokenUrl,\n\t\tuserInfoUrl,\n\t\tclientId: options.clientId,\n\t\tclientSecret: options.clientSecret,\n\t\tscopes: options.scopes ?? defaultScopes,\n\t\tredirectURI: options.redirectURI,\n\t\tpkce: options.pkce,\n\t\tdisableImplicitSignUp: options.disableImplicitSignUp,\n\t\tdisableSignUp: options.disableSignUp,\n\t\toverrideUserInfo: options.overrideUserInfo,\n\t\tgetUserInfo,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,iBACf,SACqB;CACrB,MAAM,gBAAgB;EAAC;EAAU;EAAW;EAAQ;CAEpD,MAAM,WAAW,QAAQ;CACzB,MAAM,mBAAmB,qCAAqC,SAAS;CACvE,MAAM,WAAW,qCAAqC,SAAS;CAC/D,MAAM,cAAc;CAEpB,MAAM,cAAc,OACnB,WACoC;EACpC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,aACA,EACC,SAAS,EACR,eAAe,UAAU,OAAO,eAChC,EACD,CACD;AAED,MAAI,SAAS,CAAC,QACb,QAAO;AAGR,SAAO;GACN,IAAI,QAAQ;GACZ,MACC,QAAQ,SACP,GAAG,QAAQ,cAAc,GAAG,GAAG,QAAQ,eAAe,KAAK,MAAM,IACjE;GACF,OAAO,QAAQ,SAAS,QAAQ,sBAAsB;GACtD,OAAO,QAAQ;GAKf,eAAe,QAAQ,kBAAkB;GACzC;;AAGF,QAAO;EACN,YAAY;EACZ;EACA;EACA;EACA,UAAU,QAAQ;EAClB,cAAc,QAAQ;EACtB,QAAQ,QAAQ,UAAU;EAC1B,aAAa,QAAQ;EACrB,MAAM,QAAQ;EACd,uBAAuB,QAAQ;EAC/B,eAAe,QAAQ;EACvB,kBAAkB,QAAQ;EAC1B;EACA"}