import NextAuth from "next-auth" import Google from "next-auth/providers/google" import { PrismaAdapter } from "@auth/prisma-adapter" import { db } from "@/lib/db" import type { Adapter } from "next-auth/adapters" import Nodemailer from "next-auth/providers/nodemailer" export const { auth, handlers, signIn, signOut } = NextAuth({ adapter: PrismaAdapter(db) as Adapter, providers: [ Google({ clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, allowDangerousEmailAccountLinking: true, }), Nodemailer({ server: { host: process.env.SMTP_HOST, port: Number(process.env.SMTP_PORT), auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, }, from: process.env.SMTP_FROM, }), ], pages: { signIn: "/auth/signin", error: "/auth/error", }, events: { async linkAccount({ user, account, profile }) { if (profile?.email && user.id) { await db.user.update({ where: { id: user.id }, data: { email: profile.email, name: profile.name || user.name, image: (profile as any)?.picture || user.image, emailVerified: (profile as any)?.email_verified ? new Date() : null, }, }) } }, }, callbacks: { async signIn({ user, account, profile, email, credentials }) { if (!user.email) return false if (account?.provider === "nodemailer") { return true } if (account?.provider === "google" && user.email) { const existingUser = await db.user.findUnique({ where: { email: user.email }, include: { accounts: true }, }) if (existingUser) { const hasGoogleAccount = existingUser.accounts.some( acc => acc.provider === "google" ) if (!hasGoogleAccount) { await db.account.create({ data: { userId: existingUser.id, type: account.type, provider: account.provider, providerAccountId: account.providerAccountId, refresh_token: account.refresh_token as string | null, access_token: account.access_token as string | null, expires_at: account.expires_at, token_type: account.token_type, scope: account.scope, id_token: account.id_token as string | null, session_state: account.session_state as string | null, }, }) await db.user.update({ where: { id: existingUser.id }, data: { name: profile?.name || existingUser.name, image: (profile as any)?.picture || existingUser.image, emailVerified: (profile as any)?.email_verified ? new Date() : existingUser.emailVerified, }, }) } } } return true }, async session({ token, session }) { if (token) { session.user.id = token.id as string session.user.name = token.name as string session.user.email = token.email as string session.user.image = token.picture as string } return session }, async jwt({ user, token }) { const dbUser = await db.user.findFirst({ where: { email: token.email!, }, }) if (!dbUser) { if (user) { token.id = user?.id } return token } return { id: dbUser.id, name: dbUser.name, email: dbUser.email, picture: dbUser.image, } }, }, })