Files
vereinskalender/lib/auth.ts
2026-01-13 18:08:59 +01:00

75 lines
1.8 KiB
TypeScript

import { PrismaAdapter } from "@next-auth/prisma-adapter";
import bcrypt from "bcryptjs";
import type { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { prisma } from "./prisma";
export const authOptions: NextAuthOptions = {
adapter: PrismaAdapter(prisma),
session: { strategy: "jwt" },
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;
}
const user = await prisma.user.findUnique({
where: { email: credentials.email }
});
if (!user) {
return null;
}
const valid = await bcrypt.compare(
credentials.password,
user.passwordHash
);
if (!valid) {
return null;
}
return {
id: user.id,
email: user.email,
name: user.name,
role: user.role
} as any;
}
})
],
callbacks: {
async jwt({ token, user }) {
if (user) {
token.role = (user as any).role;
}
return token;
},
async session({ session, token }) {
if (session.user) {
(session.user as any).role = token.role;
}
return session;
}
},
pages: {
signIn: "/login"
}
};
export const isAdminEmail = (email?: string | null) => {
if (!email) return false;
const list = (process.env.ADMIN_EMAILS || "")
.split(",")
.map((entry) => entry.trim().toLowerCase())
.filter(Boolean);
return list.includes(email.toLowerCase());
};