// app/app/api/auth/login/route.ts import { NextRequest, NextResponse } from "next/server"; import { setAuthCookies } from "@/lib/auth-cookies"; const BASE = process.env.DIRECTUS_URL!; const ADMIN_TOKEN = process.env.DIRECTUS_TOKEN_ADMIN_REGISTER!; // for username→email lookup type DirectusList = { data: T[] }; type LoginResp = { data: { access_token: string; refresh_token: string; expires: number } }; type MeResp = { data: { id: string; email: string | null; username?: string | null } }; async function adminFetch(path: string, init?: RequestInit): Promise { const res = await fetch(`${BASE}${path}`, { ...init, headers: { "Accept": "application/json", "Content-Type": "application/json", "Authorization": `Bearer ${ADMIN_TOKEN}`, ...(init?.headers || {}), }, }); const text = await res.text(); const json = text ? JSON.parse(text) : null; if (!res.ok) throw new Error(`Directus ${res.status}: ${text || res.statusText}`); return (json ?? {}) as T; } async function directusLogin(email: string, password: string): Promise { const res = await fetch(`${BASE}/auth/login`, { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); const text = await res.text(); const json = text ? JSON.parse(text) : null; if (!res.ok) throw new Error(`Login failed: ${text || res.statusText}`); return json.data; } function isEmailLike(s: string) { return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(s); } export async function POST(req: NextRequest) { try { const body = await req.json().catch(() => ({})); const identifier: string = (body?.identifier ?? "").trim(); // username OR email const password: string = (body?.password ?? "").trim(); if (!identifier || !password) { return NextResponse.json({ error: "Missing identifier or password." }, { status: 400 }); } let email = identifier; let username: string | undefined = undefined; if (!isEmailLike(identifier)) { // lookup email by username (custom field on directus_users) const q = `/users?limit=1&filter[username][_eq]=${encodeURIComponent(identifier)}&fields=id,email,username`; const found = await adminFetch>(q); const user = found.data?.[0]; if (!user?.email) return NextResponse.json({ error: "User not found." }, { status: 404 }); email = user.email; username = user.username || undefined; } const tokens = await directusLogin(email, password); // Fetch /users/me to confirm and obtain username (if email path) const meRes = await fetch(`${BASE}/users/me?fields=id,email,username`, { headers: { "Authorization": `Bearer ${tokens.access_token}`, "Accept": "application/json" }, }); const meText = await meRes.text(); const me: MeResp = meText ? JSON.parse(meText) : { data: { id: "", email: null, username: null } }; const user = { id: String(me?.data?.id || ""), email: me?.data?.email ?? null, username: (me?.data?.username as string | null) ?? username ?? email.split("@")[0], }; let res = NextResponse.json({ ok: true, user }); res = setAuthCookies(res, tokens, user); return res; } catch (err: any) { return NextResponse.json({ error: err?.message || "Login failed" }, { status: 401 }); } }