import NextAuth from 'next-auth'; import { PrismaAdapter } from '@auth/prisma-adapter'; import { authConfig } from './auth.config'; import prisma from '@/lib/prisma'; import { buildAuthProviders } from '@/lib/auth-providers'; export const { auth, signIn, signOut, handlers } = NextAuth({ ...authConfig, adapter: PrismaAdapter(prisma), providers: buildAuthProviders(), events: { async createUser({ user }) { const adminEmail = process.env.ADMIN_EMAIL?.toLowerCase(); if (!adminEmail || !user.id || user.email?.toLowerCase() !== adminEmail) { return; } await prisma.user.update({ where: { id: user.id }, data: { role: 'ADMIN', emailVerified: new Date() }, }); }, async signOut(message) { const userId = 'token' in message && message.token?.sub ? message.token.sub : 'session' in message && message.session?.userId ? message.session.userId : null; if (!userId) return; await prisma.$transaction([ prisma.user.update({ where: { id: userId }, data: { sessionVersion: { increment: 1 } }, }), prisma.session.deleteMany({ where: { userId } }), ]); }, }, callbacks: { ...authConfig.callbacks, async signIn({ user, account }) { if (account?.provider === 'google' && user.email) { const email = user.email.toLowerCase(); const adminEmail = process.env.ADMIN_EMAIL?.toLowerCase(); const existing = await prisma.user.findUnique({ where: { email } }); if (existing && adminEmail && email === adminEmail && existing.role !== 'ADMIN') { await prisma.user.update({ where: { id: existing.id }, data: { role: 'ADMIN', emailVerified: new Date() }, }); } } return true; }, async jwt({ token, user }) { if (user?.id) { token.id = user.id; const dbUser = await prisma.user.findUnique({ where: { id: user.id }, select: { role: true, sessionVersion: true }, }); if (!dbUser) return null; token.role = dbUser.role; token.sessionVersion = dbUser.sessionVersion; } else if (token.sub) { const dbUser = await prisma.user.findUnique({ where: { id: token.sub }, select: { role: true, sessionVersion: true }, }); if (!dbUser) return null; if ( typeof token.sessionVersion === 'number' && token.sessionVersion !== dbUser.sessionVersion ) { return null; } token.id = token.sub; token.role = dbUser.role; token.sessionVersion = dbUser.sessionVersion; } return token; }, }, });