first version
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import NextAuth, { type DefaultSession } from "next-auth"
|
||||
import Credentials from "next-auth/providers/credentials"
|
||||
import { ZodError } from "zod"
|
||||
|
||||
import { UserRole } from "@/generated/prisma/client"
|
||||
import { SIGN_IN_URL, TOKEN_EXPIRATION_SECONDS } from "@/lib/constants"
|
||||
import { signInSchema } from "@/lib/schemas/auth.schemas"
|
||||
import { verifyPassword } from "@/lib/security"
|
||||
import { getUserByUsername } from "@/services/user.service"
|
||||
|
||||
declare module "next-auth" {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface Session {
|
||||
user: {
|
||||
id: string
|
||||
role: UserRole
|
||||
} & DefaultSession["user"]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface User {
|
||||
role: UserRole
|
||||
}
|
||||
}
|
||||
|
||||
export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
maxAge: TOKEN_EXPIRATION_SECONDS,
|
||||
},
|
||||
providers: [
|
||||
Credentials({
|
||||
credentials: {
|
||||
username: {},
|
||||
password: {},
|
||||
},
|
||||
authorize: async (credentials) => {
|
||||
try {
|
||||
const { data, success } = signInSchema.safeParse(credentials)
|
||||
|
||||
if (!success) throw new Error("Invalid username or password")
|
||||
|
||||
const user = await getUserByUsername(data.username)
|
||||
|
||||
if (!user) {
|
||||
throw new Error("Invalid username or password")
|
||||
}
|
||||
|
||||
if (!(await verifyPassword(data.password, user.password)))
|
||||
throw new Error("Invalid username or password")
|
||||
|
||||
return {
|
||||
...user,
|
||||
role: user.role,
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof ZodError) {
|
||||
return null
|
||||
}
|
||||
throw new Error("Invalid username or password")
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
pages: {
|
||||
signIn: SIGN_IN_URL,
|
||||
},
|
||||
callbacks: {
|
||||
async session({ session, token }) {
|
||||
if (!token) return session
|
||||
session.user.id = token.sub as string
|
||||
session.user.name = token.name as string
|
||||
session.user.email = token.email as string
|
||||
session.user.role = token.role as UserRole
|
||||
return session
|
||||
},
|
||||
async jwt({ token, user }) {
|
||||
if (user) {
|
||||
token.sub = user.id
|
||||
token.name = user.name
|
||||
token.email = user.email
|
||||
token.role = user.role
|
||||
}
|
||||
return token
|
||||
},
|
||||
authorized: async ({ auth }) => {
|
||||
return !!auth
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user