diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..c76160b --- /dev/null +++ b/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,82 @@ +// app/api/auth/[...nextauth]/route.ts +import NextAuth from 'next-auth'; +import CredentialsProvider from 'next-auth/providers/credentials'; +import { PrismaClient } from '@prisma/client'; +import { compare } from 'bcryptjs'; + +const prisma = new PrismaClient(); + +const handler = NextAuth({ + providers: [ + CredentialsProvider({ + name: 'Credentials', + credentials: { + email: { + label: 'Benutzername oder E-Mail', + type: 'text', + }, + password: { + label: 'Passwort', + type: 'password', + }, + }, + async authorize(credentials) { + if (!credentials?.email || !credentials.password) { + return null; + } + + const identifier = credentials.email.trim(); + + // User per E-Mail ODER Benutzername suchen + const user = await prisma.user.findFirst({ + where: { + OR: [ + { email: identifier }, + { username: identifier }, + ], + }, + }); + + if (!user || !user.passwordHash) { + return null; + } + + const isValid = await compare(credentials.password, user.passwordHash); + if (!isValid) { + return null; + } + + // Minimal-Userobjekt für NextAuth zurückgeben + return { + id: user.id, + name: user.name ?? user.username ?? user.email, + email: user.email, + }; + }, + }), + ], + pages: { + signIn: '/login', + }, + session: { + strategy: 'jwt', + }, + callbacks: { + async jwt({ token, user }) { + // beim Login User-ID in den Token schreiben + if (user) { + token.id = user.id; + } + return token; + }, + async session({ session, token }) { + // ID aus dem Token wieder in die Session kopieren + if (session.user && token.id) { + (session.user as any).id = token.id; + } + return session; + }, + }, +}); + +export { handler as GET, handler as POST }; diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..aa9f3f1 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; +import Providers from "./providers"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -27,7 +28,7 @@ export default function RootLayout({
- {children} +