Skip to content

Commit

Permalink
Improve error checking for NextAuth configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielMajeri committed Jan 16, 2024
1 parent 2d3aced commit 01c2de5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 43 deletions.
100 changes: 58 additions & 42 deletions src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
import { NextAuthOptions } from "next-auth";
import NextAuth from "next-auth/next";
import AzureAD from "next-auth/providers/azure-ad";
import type { Provider } from "next-auth/providers/index";
// import prisma from "@/db/prisma";

const providers: Provider[] = [];

const tenantId = process.env.AZURE_AD_TENANT_ID;
if (typeof tenantId !== "string" || !tenantId) {
throw Error(
"Required environment variable `AZURE_AD_TENANT_ID` is not defined",
);
}

const clientId = process.env.AZURE_AD_CLIENT_ID;
if (typeof clientId !== "string" || !clientId) {
throw Error(
"Required environment variable `AZURE_AD_CLIENT_ID` is not defined",
);
}

const clientSecret = process.env.AZURE_AD_CLIENT_SECRET;
if (typeof clientSecret !== "string" || !clientSecret) {
throw Error(
"Required environment variable `AZURE_AD_CLIENT_SECRET` is not defined",
);
}

providers.push(
AzureAD({
tenantId,
clientId,
clientSecret,
authorization: {
params: {},
},
profile(profile) {
return {
id: profile.sub,
azureAdObjectId: profile.oid,
name: profile.name,
email: profile.email,
image: profile.picture ?? null,
};
},
}),
);

export const authOptions: NextAuthOptions = {
providers: [
AzureAD({
clientId: process.env.AZURE_AD_CLIENT_ID as string,
clientSecret: process.env.AZURE_AD_CLIENT_SECRET as string,
tenantId: process.env.AZURE_AD_TENANT_ID as string,
authorization: {
params: {},
},
profile(profile) {
return {
id: profile.sub,
azureAdObjectId: profile.oid,
name: profile.name,
email: profile.email,
image: profile.picture ?? null,
};
},
}),
],
providers,

callbacks: {
async signIn({ user }) {
Expand All @@ -37,35 +63,23 @@ export const authOptions: NextAuthOptions = {

return true;
},
async jwt({ token, user, account, profile }) {
if (account) {
token.accessToken = account.access_token;
} else {
throw new Error("Access Token was not present in the account");
jwt({ token, user, account }) {
if (!account) {
throw new Error("Cannot create JWT, received account object is null");
}
if (user) {
token.azureAdObjectId = user.azureAdObjectId;
} else {
throw new Error(
"Azure Active Directory id of was not present in the user",
);

if (!account.access_token) {
throw new Error("Access token was not present in account object");
}

token.accessToken = account.access_token;
token.azureAdObjectId = user.azureAdObjectId;

return token;
},
session({ session, token }) {
if (token.accessToken && typeof token.accessToken === "string") {
session.accessToken = token.accessToken;
} else {
throw new Error("Access Token was not present in the token");
}
if (token.azureAdObjectId && typeof token.azureAdObjectId === "string") {
session.user.azureAdObjectId = token.azureAdObjectId;
} else {
throw new Error(
"Azure Active Directory id of was not present in the token",
);
}
session.accessToken = token.accessToken;
session.user.azureAdObjectId = token.azureAdObjectId;

return session;
},
Expand All @@ -74,5 +88,7 @@ export const authOptions: NextAuthOptions = {
signIn: "/auth/signin",
},
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
11 changes: 10 additions & 1 deletion src/types/next-auth.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultSession, Profile } from "next-auth";
import { DefaultSession, Profile, JWT } from "next-auth";

declare module "next-auth" {
interface Session {
Expand All @@ -7,8 +7,17 @@ declare module "next-auth" {
azureAdObjectId: string;
} & DefaultSession["user"];
}

interface User {
id: number;
azureAdObjectId: string;
}
}

declare module "next-auth/jwt" {
/** Returned by the `jwt` callback and `getToken`, when using JWT sessions */
interface JWT {
accessToken: string;
azureAdObjectId: string;
}
}

0 comments on commit 01c2de5

Please sign in to comment.