From 73419f468e95bd40e4b28cc6e74a4478e873c30f Mon Sep 17 00:00:00 2001 From: Linrador <68631622+Linrador@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:28:24 +0100 Subject: [PATCH] updated --- app/api/auth/[...nextauth]/route.ts | 82 ++++ app/layout.tsx | 3 +- app/login/page.tsx | 21 + app/providers.tsx | 14 + app/ui/Button.tsx | 52 --- app/ui/Tabs.tsx | 52 --- components/auth/LoginForm.tsx | 271 ++++++++++++ components/ui/Button.tsx | 138 ++++++ components/ui/Tabs.tsx | 62 +++ middleware.ts | 13 + package-lock.json | 417 ++++++++++++++++-- package.json | 9 +- prisma/create-test-user.ts | 41 ++ prisma/dev.db | Bin 12288 -> 114688 bytes .../migration.sql | 97 ++++ prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 128 +++++- 17 files changed, 1254 insertions(+), 149 deletions(-) create mode 100644 app/api/auth/[...nextauth]/route.ts create mode 100644 app/login/page.tsx create mode 100644 app/providers.tsx delete mode 100644 app/ui/Button.tsx delete mode 100644 app/ui/Tabs.tsx create mode 100644 components/auth/LoginForm.tsx create mode 100644 components/ui/Button.tsx create mode 100644 components/ui/Tabs.tsx create mode 100644 middleware.ts create mode 100644 prisma/create-test-user.ts create mode 100644 prisma/migrations/20251114101117_add_user_password/migration.sql create mode 100644 prisma/migrations/migration_lock.toml 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} +