yo-next-auth/config/auth.ts

75 lines
1.7 KiB
TypeScript

import NextAuth from 'next-auth'
import { UserRole } from '@prisma/client'
import { PrismaAdapter } from '@auth/prisma-adapter'
import db from '@/lib/db'
import authConfig from '@/auth.config'
import { getUserById } from '@/data/user'
import { AUTH_ERROR_URL, AUTH_LOGIN_URL } from '@/config/routes'
declare module 'next-auth' {
interface Session {
user: { role: UserRole }
}
}
export const VERIFICATION_TOKEN_EXPIRATION_DURATION = 3_600_000
export const {
handlers: { GET, POST },
auth,
signIn,
signOut,
} = NextAuth({
pages: {
signIn: AUTH_LOGIN_URL,
error: AUTH_ERROR_URL,
},
events: {
async linkAccount ({ user }) {
await db.user.update({
where: { id: user.id as string },
data: { emailVerified: new Date() },
})
},
},
callbacks: {
async signIn ({ user, account }) {
// Bypass email verification when Oauth are being used
if (account?.provider !== 'credentials') return true
const existingUser = await getUserById(user.id as string)
// Prevent sign in without email verification
if (!existingUser?.emailVerified) return false
// TODO: Add 2FA check
return true
},
async session ({ token, session }) {
if (token.sub && session.user) {
session.user.id = token.sub
}
if (token.role && session.user) {
session.user.role = token.role as UserRole
}
return session
},
async jwt ({ token }) {
if (!token.sub) return token
const existingUser = await getUserById(token.sub)
if (!existingUser) return token
token.role = existingUser.role
return token
},
},
adapter: PrismaAdapter(db),
session: { strategy: 'jwt' },
...authConfig,
})