Skip to content
Snippets Groups Projects
auth.ts 4.1 KiB
Newer Older
Yusuf Akgül's avatar
Yusuf Akgül committed
import { env } from "@/env.mjs"
import { db } from "@/lib/db"
import { PrismaAdapter } from "@auth/prisma-adapter"
Yusuf Akgül's avatar
Yusuf Akgül committed
import { compare } from "bcrypt"
import { NextAuthOptions } from "next-auth"
Yusuf Akgül's avatar
Yusuf Akgül committed
import { Adapter } from "next-auth/adapters"
Yusuf Akgül's avatar
Yusuf Akgül committed
import CredentialsProvider from 'next-auth/providers/credentials'
Yusuf Akgül's avatar
Yusuf Akgül committed
import GitHubProvider from "next-auth/providers/github"
import { normalize } from "normalize-diacritics"
Yusuf Akgül's avatar
Yusuf Akgül committed

export const authOptions: NextAuthOptions = {
Yusuf Akgül's avatar
Yusuf Akgül committed
    adapter: PrismaAdapter(db as any) as Adapter,
Yusuf Akgül's avatar
Yusuf Akgül committed
    session: {
        strategy: 'jwt'
    },
Yusuf Akgül's avatar
Yusuf Akgül committed
    pages: {
        signIn: "/login",
    },
Yusuf Akgül's avatar
Yusuf Akgül committed
    providers: [
Yusuf Akgül's avatar
Yusuf Akgül committed
        GitHubProvider({
Yusuf Akgül's avatar
Yusuf Akgül committed
            clientId: env.GITHUB_CLIENT_ID,
            clientSecret: env.GITHUB_CLIENT_SECRET,
Yusuf Akgül's avatar
Yusuf Akgül committed
        }),

Yusuf Akgül's avatar
Yusuf Akgül committed
        CredentialsProvider({
Yusuf Akgül's avatar
Yusuf Akgül committed
            name: 'Login',
Yusuf Akgül's avatar
Yusuf Akgül committed
            credentials: {
Yusuf Akgül's avatar
Yusuf Akgül committed
                usernameOrEmail: { label: 'Username or Email', type: 'text' },
Yusuf Akgül's avatar
Yusuf Akgül committed
                password: { label: 'Password', type: 'password' }
            },
            async authorize(credentials) {
Yusuf Akgül's avatar
Yusuf Akgül committed
                if (!credentials?.usernameOrEmail || !credentials?.password) {
Yusuf Akgül's avatar
Yusuf Akgül committed
                    return null
                }

Yusuf Akgül's avatar
Yusuf Akgül committed
                const user = await db.user.findFirst({
Yusuf Akgül's avatar
Yusuf Akgül committed
                    where: {
Yusuf Akgül's avatar
s  
Yusuf Akgül committed
                        OR: [{
                            username: credentials.usernameOrEmail.toLowerCase()
                        },
                        {
                            email: credentials.usernameOrEmail.toLowerCase()
                        }],
Yusuf Akgül's avatar
Yusuf Akgül committed
                    },
Yusuf Akgül's avatar
Yusuf Akgül committed

Yusuf Akgül's avatar
Yusuf Akgül committed
                if (!user || !user.password) {
                    throw new Error('user not found')
Yusuf Akgül's avatar
Yusuf Akgül committed
                }

                const isPasswordValid = await compare(
                    credentials.password,
                    user.password
                )

Yusuf Akgül's avatar
s  
Yusuf Akgül committed
                if (!user.emailVerified) {
Caner's avatar
Caner committed
                    throw new Error('Email is not verified')
Yusuf Akgül's avatar
s  
Yusuf Akgül committed
                }
Caner's avatar
Caner committed

Yusuf Akgül's avatar
Yusuf Akgül committed
                if (!isPasswordValid) {
                    throw new Error('invalid password')
Yusuf Akgül's avatar
Yusuf Akgül committed
                }

                return {
Yusuf Akgül's avatar
Yusuf Akgül committed
                    id: user.id,
                    username: user.username,
Yusuf Akgül's avatar
Yusuf Akgül committed
                    email: user.email,
                }
            }
        })
    ],
Yusuf Akgül's avatar
Yusuf Akgül committed
    secret: env.NEXTAUTH_SECRET,
Yusuf Akgül's avatar
Yusuf Akgül committed
    callbacks: {
Yusuf Akgül's avatar
Yusuf Akgül committed
        async session({ token, session }) {
            if (token) {
Yusuf Akgül's avatar
Yusuf Akgül committed
                session.user.id = token.id
Yusuf Akgül's avatar
Yusuf Akgül committed
                session.user.name = token.name
                session.user.username = token.username
Yusuf Akgül's avatar
Yusuf Akgül committed
                session.user.email = token.email
                session.user.image = token.picture
Yusuf Akgül's avatar
Yusuf Akgül committed
            }
Yusuf Akgül's avatar
Yusuf Akgül committed

            return session
Yusuf Akgül's avatar
Yusuf Akgül committed
        },
Yusuf Akgül's avatar
Yusuf Akgül committed
        async jwt({ token, user }) {
            const dbUser = await db.user.findFirst({
                where: {
                    email: token.email,
                },
            })

            if (!dbUser) {
                if (user) {
                    token.id = user?.id
Yusuf Akgül's avatar
Yusuf Akgül committed
                }
Yusuf Akgül's avatar
Yusuf Akgül committed
                return token
            }

Yusuf Akgül's avatar
Yusuf Akgül committed
            if (!dbUser.username) {
                let username = await normalize(dbUser.name?.toLowerCase().replace(/\s/g, ''))
                const email = dbUser.email?.toLowerCase()
Yusuf Akgül's avatar
Yusuf Akgül committed

Yusuf Akgül's avatar
Yusuf Akgül committed
                while (!isUnique) {
                    const existingUserName = await db.user.findFirst({
                        where: {
                            username,
                            NOT: { email },
                        },
Yusuf Akgül's avatar
Yusuf Akgül committed

                    if (existingUserName) {
                        username = `${username}${Math.floor(Math.random() * 1000)}`
Yusuf Akgül's avatar
Yusuf Akgül committed
                    } else {
Yusuf Akgül's avatar
Yusuf Akgül committed

                await db.user.update({
                    where: { email },
                    data: { username },
Yusuf Akgül's avatar
Yusuf Akgül committed
            return {
                id: dbUser.id,
                name: dbUser.name,
                username: dbUser.username,
Yusuf Akgül's avatar
Yusuf Akgül committed
                email: dbUser.email,
                picture: dbUser.image,