= + OAuthUserConfig
& {
+ /**
+ * https://learn.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0&tabs=http#examples
+ *
+ * @default 48
+ */
+ profilePhotoSize?: 48 | 64 | 96 | 120 | 240 | 360 | 432 | 504 | 648
+ /** @default "common" */
+ tenantId?: string
+ }
+
+/**
+ *
+ * Add Microsoft Entra ID login to your page.
+ *
+ * :::note
+ * Entra is the [new name](https://learn.microsoft.com/en-us/entra/fundamentals/new-name) Microsoft has given to what was previously known as "Azure AD"
+ * :::
+ *
+ * ## Setup
+ *
+ * ### Callback URL
+ * ```
+ * https://example.com/api/auth/callback/microsoft-entra-id
+ * ```
+ *
+ * ### Configuration
+ * ```ts
+ * import NextAuth from "next-auth"
+ * import Entra from "next-auth/providers/microsoft-entra-id"
+ *
+ * const { handlers, auth, signin, signout } = NextAuth({
+ * providers: [
+ * Entra({
+ * clientId: process.env.AUTH_MICROSOFT_ENTRA_ID_ID,
+ * clientSecret: process.env.AUTH_MICROSOFT_ENTRA_ID_SECRET
+ * })
+ * ],
+ * })
+ * ```
+ *
+ * ### Resources
+ *
+ * - [Microsoft Entra OAuth documentation](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow)
+ * - [Microsoft Entra OAuth apps](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)
+ *
+ * @example
+ *
+ * ### To allow specific Active Directory users access:
+ *
+ * - In https://entra.microsoft.com/ select Identity from the left bar menu.
+ * - Next, go to "App Registration" in the left menu, and create a new one.
+ * - Pay close attention to "Who can use this application or access this API?"
+ * - This allows you to scope access to specific types of user accounts
+ * - Only your tenant, all Microsoft tenants, or all Microsoft tenants and public Microsoft accounts (Skype, Xbox, Outlook.com, etc.)
+ * - When asked for a redirection URL, use `https://yourapplication.com/api/auth/callback/microsoft-entra-id` or for development `http://localhost:3000/api/auth/callback/microsoft-entra-id`.
+ * - After your App Registration is created, under "Client Credential" create your Client secret.
+ * - Now copy your:
+ * - Application (client) ID
+ * - Directory (tenant) ID
+ * - Client secret (value)
+ *
+ * In `.env.local` create the following entries:
+ *
+ * ```
+ * AUTH_MICROSOFT_ENTRA_ID_ID= (
+ options: MicrosoftEntraIDOptions
+): OAuthConfig {
+ const { tenantId = "common", profilePhotoSize = 48, ...rest } = options
+ rest.issuer ??= `https://login.microsoftonline.com/${tenantId}/v2.0`
+ return {
+ id: "microsoft-entra-id",
+ name: "Microsoft Entra ID",
+ type: "oidc",
+ wellKnown: `${rest.issuer}/.well-known/openid-configuration?appid=${options.clientId}`,
+ authorization: {
+ params: {
+ scope: "openid profile email User.Read",
+ },
+ },
+ async profile(profile, tokens) {
+ // https://learn.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0&tabs=http#examples
+ const response = await fetch(
+ `https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`,
+ { headers: { Authorization: `Bearer ${tokens.access_token}` } }
+ )
+
+ // Confirm that profile photo was returned
+ let image
+ // TODO: Do this without Buffer
+ if (response.ok && typeof Buffer !== "undefined") {
+ try {
+ const pictureBuffer = await response.arrayBuffer()
+ const pictureBase64 = Buffer.from(pictureBuffer).toString("base64")
+ image = `data:image/jpeg;base64, ${pictureBase64}`
+ } catch {}
+ }
+
+ return {
+ id: profile.sub,
+ name: profile.name,
+ email: profile.email,
+ image: image ?? null,
+ }
+ },
+ style: { text: "#fff", bg: "#0072c6" },
+ options: rest,
+ }
+}