// app/api/auth/login/route.ts import { NextRequest, NextResponse } from "next/server"; import { emailForUsername, loginDirectus } from "@/lib/directus"; export const runtime = "nodejs"; const secure = process.env.NODE_ENV === "production"; export async function POST(req: NextRequest) { try { const body = await req.json().catch(() => ({} as any)); const identifier = String(body?.identifier ?? body?.email ?? body?.username ?? "").trim(); const password = String(body?.password ?? "").trim(); if (!identifier || !password) { return NextResponse.json({ error: "Missing credentials" }, { status: 400 }); } // 1) Try Directus directly with the identifier (email OR username) // Directus expects the field name "email" for both. const tryIds: string[] = [identifier]; // 2) Fallback: if it doesn’t look like an email, try the canonical email (if any) if (!identifier.includes("@")) { try { const em = await emailForUsername(identifier); // returns string|null if (em && em !== identifier) tryIds.push(em); } catch { // ignore lookup errors, we'll just rely on the first attempt } } let tokens: any = null; let lastErr: any = null; for (const id of tryIds) { try { tokens = await loginDirectus(id, password); // { access_token, refresh_token, expires? } if (tokens) break; } catch (e) { lastErr = e; } } if (!tokens?.access_token) { const msg = lastErr?.response?.data?.errors?.[0]?.message || lastErr?.response?.data?.error || lastErr?.message || "Invalid credentials."; return NextResponse.json({ error: msg }, { status: 401 }); } // Set HttpOnly cookies for your middleware const maxAge = 60 * 60; // 1h const res = NextResponse.json({ ok: true }); res.cookies.set("ma_at", tokens.access_token, { path: "/", httpOnly: true, sameSite: "lax", secure, maxAge, }); if (tokens.refresh_token) { res.cookies.set("ma_rt", tokens.refresh_token, { path: "/", httpOnly: true, sameSite: "lax", secure, maxAge: 60 * 60 * 24 * 30, // 30d }); } return res; } catch (err: any) { const message = err?.response?.data?.errors?.[0]?.message || err?.response?.data?.error || err?.message || "Login failed"; const status = /unauth|invalid|credential/i.test(message) ? 401 : 400; return NextResponse.json({ error: message }, { status }); } }