karbe/src/auth.ts
Karbé Architect 88a7d01d55 feat(auth): add multi-role NextAuth with role guards
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-29 10:46:54 +00:00

75 lines
1.8 KiB
TypeScript

import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { prisma } from "@/lib/prisma";
import { verifyPassword } from "@/lib/password";
export const { handlers, auth, signIn, signOut } = NextAuth({
session: {
strategy: "jwt",
},
providers: [
Credentials({
name: "Email et mot de passe",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Mot de passe", type: "password" },
},
async authorize(credentials) {
const email = credentials?.email?.toString().trim().toLowerCase();
const password = credentials?.password?.toString() ?? "";
if (!email || !password) {
return null;
}
const user = await prisma.user.findUnique({
where: { email },
select: {
id: true,
email: true,
firstName: true,
lastName: true,
role: true,
isActive: true,
passwordHash: true,
},
});
if (!user || !user.isActive) {
return null;
}
const isValid = await verifyPassword(password, user.passwordHash);
if (!isValid) {
return null;
}
return {
id: user.id,
email: user.email,
name: `${user.firstName} ${user.lastName}`.trim(),
role: user.role,
};
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user?.role) {
token.role = user.role;
}
return token;
},
async session({ session, token }) {
if (session.user) {
session.user.id = token.sub ?? "";
session.user.role = token.role;
}
return session;
},
},
pages: {
signIn: "/connexion",
},
});