aboutsummaryrefslogtreecommitdiff
path: root/src/lib/auth.ts
blob: 51c6c91587a312f49431af913b2ffdb52f56d544 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import NextAuth, { type NextAuthOptions } from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { MongoClient } from "mongodb"
import bcrypt from "bcryptjs"
import dbConnect from "./mongodb"
import User from "@/model/User"
import { loginSchema } from "./validation"

const client = new MongoClient(process.env.MONGODB_URI!)

export const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      name: "credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) {
          return null
        }

        // Validate and sanitize with Zod
        const result = loginSchema.safeParse(credentials)
        
        if (!result.success) {
          return null
        }

        const { email, password } = result.data

        await dbConnect()
        
        const user = await User.findOne({ email })
        if (!user) {
          return null
        }

        const isPasswordValid = await bcrypt.compare(password, user.password)
        if (!isPasswordValid) {
          return null
        }

        return {
          id: user._id.toString(),
          email: user.email,
          name: user.name,
          image: user.profileImage?.url || null,
        }
      }
    })
  ],
  session: {
    strategy: "jwt" as const
  },
  callbacks: {
    async jwt({ token, user }: { token: any; user: any }) {
      if (user) {
        token.id = user.id
      }
      return token
    },
    async session({ session, token }: { session: any; token: any }) {
      if (token) {
        session.user.id = token.id as string
        
        // Fetch latest user data from database to get current profile image
        await dbConnect()
        const currentUser = await User.findById(token.id)
        if (currentUser) {
          session.user.name = currentUser.name
          session.user.email = currentUser.email
          session.user.image = currentUser.profileImage?.url || null
        }
      }
      return session
    },
  },
  pages: {
    signIn: "/login",
  },
}

export default NextAuth(authOptions)