import { NextRequest, NextResponse } from "next/server" import { comparePassword, getUserByEmail, getUserByUsername, mapDbUserToSessionUser, recordLoginAttempt, incrementFailedAttempts, resetFailedAttempts, isAccountLocked, createSession, } from "@/lib/auth" export async function POST(request: NextRequest) { try { const { email, username, password } = await request.json() const credential = email || username if (!credential || !password) { return NextResponse.json( { error: "Email/Username and password are required." }, { status: 400 } ) } if (credential.trim().length === 0 || password.trim().length === 0) { return NextResponse.json( { error: "Credentials cannot be empty." }, { status: 400 } ) } const ipAddress = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || request.headers.get("x-real-ip") || "127.0.0.1" const userAgent = request.headers.get("user-agent") || null // Try to find user by email first, then by username let dbUser = email || credential.includes("@") ? await getUserByEmail(credential) : null if (!dbUser) { dbUser = await getUserByUsername(credential) } if (!dbUser) { await recordLoginAttempt( null, credential, ipAddress, userAgent, false, "User not found" ) return NextResponse.json( { error: "Invalid email/username or password." }, { status: 401 } ) } const lockStatus = await isAccountLocked(dbUser) if (lockStatus.locked) { await recordLoginAttempt( dbUser.id, credential, ipAddress, userAgent, false, lockStatus.reason ) return NextResponse.json( { error: lockStatus.reason }, { status: 423 } ) } const valid = await comparePassword(password, dbUser.password_hash) if (!valid) { await incrementFailedAttempts(dbUser.id) await recordLoginAttempt( dbUser.id, credential, ipAddress, userAgent, false, "Invalid password" ) return NextResponse.json( { error: "Invalid email/username or password." }, { status: 401 } ) } await resetFailedAttempts(dbUser.id) await recordLoginAttempt( dbUser.id, credential, ipAddress, userAgent, true ) await createSession(dbUser.id, dbUser.role_name) const user = mapDbUserToSessionUser(dbUser) return NextResponse.json({ user }, { status: 200 }) } catch (error) { console.error("Login error:", error) return NextResponse.json( { error: "Authentication service unavailable. Please ensure PostgreSQL is running and configured." }, { status: 503 } ) } }