Files
Lageplan/src/app/api/auth/login/route.ts

66 lines
1.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { cookies } from 'next/headers'
import { login, createToken } from '@/lib/auth'
import { loginSchema } from '@/lib/validations'
import { prisma } from '@/lib/db'
import { loginLimiter, getClientIp, rateLimitResponse } from '@/lib/rate-limit'
export async function POST(request: NextRequest) {
try {
const ip = getClientIp(request)
const rl = loginLimiter.check(ip)
if (!rl.success) return rateLimitResponse(rl.resetAt)
const body = await request.json()
const validated = loginSchema.safeParse(body)
if (!validated.success) {
return NextResponse.json(
{ error: 'Ungültige Eingabedaten' },
{ status: 400 }
)
}
const { email, password } = validated.data
const rememberMe = body.rememberMe === true
const result = await login(email, password)
if (!result.success || !result.user) {
const remaining = rl.remaining
const warningText = remaining <= 3 && remaining > 0
? ` (Noch ${remaining} Versuch${remaining === 1 ? '' : 'e'})`
: ''
return NextResponse.json(
{ error: (result.error || 'Login fehlgeschlagen') + warningText, remaining },
{ status: 401 }
)
}
// Update lastLoginAt
try {
await (prisma as any).user.update({
where: { id: result.user.id },
data: { lastLoginAt: new Date() },
})
} catch {}
const token = await createToken(result.user, rememberMe)
;(await cookies()).set('auth-token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: rememberMe ? 60 * 60 * 24 * 30 : 60 * 60 * 24, // 30 days or 24 hours
path: '/',
})
return NextResponse.json({ user: result.user })
} catch (error) {
console.error('Login error:', error)
return NextResponse.json(
{ error: 'Interner Serverfehler' },
{ status: 500 }
)
}
}