102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
import NextAuth, { type DefaultSession } from 'next-auth';
|
|
import type { NextAuthConfig } from 'next-auth';
|
|
import Google from "next-auth/providers/google";
|
|
import { db, admins, students } from '@workspace/db';
|
|
import { eq } from '@workspace/db/drizzle';
|
|
|
|
declare module 'next-auth' {
|
|
interface Session {
|
|
user: {
|
|
role?: 'ADMIN' | 'USER';
|
|
adminId?: number;
|
|
studentId?: number;
|
|
completedProfile?: boolean;
|
|
[key: string]: any;
|
|
} & DefaultSession["user"];
|
|
}
|
|
|
|
interface JWT {
|
|
role?: 'ADMIN' | 'USER';
|
|
adminId?: number;
|
|
studentId?: number;
|
|
// completedProfile?: boolean; // Removed from JWT
|
|
}
|
|
}
|
|
|
|
declare module 'next/server' {
|
|
interface NextRequest {
|
|
auth: import('next-auth').Session | null;
|
|
}
|
|
}
|
|
|
|
const authConfig: NextAuthConfig = {
|
|
providers: [Google],
|
|
callbacks: {
|
|
async jwt({ token, account, user }) {
|
|
// Only set role, adminId, studentId, and email in JWT
|
|
const email = user?.email || token?.email;
|
|
if (!email) return token;
|
|
|
|
const admin = await db.select().from(admins).where(eq(admins.email, email)).limit(1);
|
|
if (admin.length > 0 && admin[0]) {
|
|
token.role = 'ADMIN';
|
|
token.adminId = admin[0].id;
|
|
token.email = email;
|
|
return token;
|
|
}
|
|
|
|
let student = await db.select().from(students).where(eq(students.email, email)).limit(1);
|
|
if (student.length > 0 && student[0]) {
|
|
token.role = 'USER';
|
|
token.studentId = student[0].id;
|
|
token.email = email;
|
|
return token;
|
|
}
|
|
|
|
if (user) {
|
|
const nameParts = user.name?.split(' ') ?? [];
|
|
const firstName = nameParts[0] || '';
|
|
const lastName = nameParts.slice(1).join(' ') || '';
|
|
const newStudent = await db
|
|
.insert(students)
|
|
.values({
|
|
email: email,
|
|
firstName: firstName,
|
|
lastName: lastName,
|
|
profilePicture: user.image,
|
|
})
|
|
.returning({ id: students.id });
|
|
if (newStudent[0]) {
|
|
token.role = 'USER';
|
|
token.studentId = newStudent[0].id;
|
|
token.email = email;
|
|
}
|
|
}
|
|
return token;
|
|
},
|
|
async session({ session, token }) {
|
|
if (token?.role) {
|
|
session.user.role = token.role as 'ADMIN' | 'USER';
|
|
}
|
|
if (token?.adminId) {
|
|
session.user.adminId = token.adminId as number;
|
|
}
|
|
if (token?.studentId) {
|
|
session.user.studentId = token.studentId as number;
|
|
}
|
|
// Fetch completedProfile from DB for students only
|
|
if (token?.role === 'USER' && token?.studentId) {
|
|
const student = await db.select().from(students).where(eq(students.id, token.studentId as number)).limit(1);
|
|
session.user.completedProfile = student[0]?.rollNumber ? true : false;
|
|
} else if (token?.role === 'ADMIN') {
|
|
session.user.completedProfile = true;
|
|
}
|
|
return session;
|
|
},
|
|
},
|
|
};
|
|
|
|
// Note: TypeScript warnings about inferred types are expected with NextAuth v5 beta
|
|
// These warnings don't affect functionality
|
|
export const { handlers, signIn, signOut, auth } = NextAuth(authConfig);
|