import NextAuth from "next-auth" import Credentials from "next-auth/providers/credentials" import { PrismaAdapter } from "@auth/prisma-adapter" import { prisma } from "@/lib/db" import bcrypt from "bcryptjs" import { z } from "zod" // Validation schemas const loginSchema = z.object({ email: z.string().email(), password: z.string().min(1), }) export const { handlers, signIn, signOut, auth } = NextAuth({ adapter: PrismaAdapter(prisma), session: { strategy: "jwt", }, providers: [ Credentials({ name: "credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, }, async authorize(credentials) { try { // Validate credentials format const { email, password } = loginSchema.parse(credentials) // Query user from database const user = await prisma.user.findUnique({ where: { email }, }) // Check if user exists if (!user || !user.passwordHash) { return null } // Verify password with bcrypt const isPasswordValid = await bcrypt.compare(password, user.passwordHash) if (!isPasswordValid) { return null } // Return user object (without password hash) return { id: user.id, email: user.email, name: user.name, } } catch (error) { console.error("Authorization error:", error) return null } }, }), ], callbacks: { async jwt({ token, user }) { // Add user ID to token on sign in if (user) { token.id = user.id } return token }, async session({ session, token }) { // Add user ID to session from token if (session.user) { session.user.id = token.id as string } return session }, }, pages: { signIn: "/auth/login", signOut: "/auth/logout", error: "/auth/error", }, })