72 lines
2.5 KiB
JavaScript
72 lines
2.5 KiB
JavaScript
import NextAuth from "next-auth";
|
|
import MicrosoftEntraID from "next-auth/providers/microsoft-entra-id";
|
|
|
|
const DV = process.env.DATAVERSE_URL; // https://<org>.crm.dynamics.com
|
|
|
|
export const { handlers, auth, signIn, signOut } = NextAuth({
|
|
trustHost: true,
|
|
providers: [
|
|
MicrosoftEntraID({
|
|
clientId: process.env.AZURE_CLIENT_ID,
|
|
clientSecret: process.env.AZURE_CLIENT_SECRET,
|
|
issuer: `https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}/v2.0`,
|
|
authorization: {
|
|
params: {
|
|
scope: `openid profile email offline_access ${DV}/user_impersonation`,
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
callbacks: {
|
|
async jwt({ token, account }) {
|
|
if (account) {
|
|
token.accessToken = account.access_token;
|
|
token.refreshToken = account.refresh_token;
|
|
token.expiresAt = account.expires_at;
|
|
}
|
|
if (token.expiresAt && Date.now() / 1000 > token.expiresAt - 300 && token.refreshToken) {
|
|
try {
|
|
const r = await fetch(
|
|
`https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`,
|
|
{
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
body: new URLSearchParams({
|
|
client_id: process.env.AZURE_CLIENT_ID,
|
|
client_secret: process.env.AZURE_CLIENT_SECRET,
|
|
grant_type: "refresh_token",
|
|
refresh_token: token.refreshToken,
|
|
scope: `openid profile email offline_access ${DV}/user_impersonation`,
|
|
}),
|
|
}
|
|
);
|
|
if (r.ok) {
|
|
const d = await r.json();
|
|
token.accessToken = d.access_token;
|
|
token.expiresAt = Math.floor(Date.now() / 1000) + d.expires_in;
|
|
if (d.refresh_token) token.refreshToken = d.refresh_token;
|
|
} else {
|
|
token.error = "RefreshFailed";
|
|
}
|
|
} catch {
|
|
token.error = "RefreshFailed";
|
|
}
|
|
}
|
|
return token;
|
|
},
|
|
async session({ session, token }) {
|
|
session.accessToken = token.accessToken;
|
|
session.error = token.error;
|
|
const email = (session.user?.email || "").toLowerCase();
|
|
session.email = email;
|
|
session.isAdmin = (process.env.ADMIN_EMAILS || "")
|
|
.toLowerCase()
|
|
.split(",")
|
|
.map((s) => s.trim())
|
|
.filter(Boolean)
|
|
.includes(email);
|
|
return session;
|
|
},
|
|
},
|
|
session: { strategy: "jwt" },
|
|
});
|