From 1f342042c92a3741799378915e9b44129af1c28e Mon Sep 17 00:00:00 2001 From: makearmy Date: Tue, 30 Sep 2025 01:14:10 -0400 Subject: [PATCH] account login with username --- app/api/auth/login/route.ts | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/app/api/auth/login/route.ts b/app/api/auth/login/route.ts index 37578f41..f3d95725 100644 --- a/app/api/auth/login/route.ts +++ b/app/api/auth/login/route.ts @@ -1,6 +1,6 @@ // app/api/auth/login/route.ts import { NextRequest, NextResponse } from "next/server"; -import { loginDirectus } from "@/lib/directus"; +import { emailForUsername, loginDirectus } from "@/lib/directus"; export const runtime = "nodejs"; @@ -18,7 +18,7 @@ export async function POST(req: NextRequest) { try { const body = await req.json().catch(() => ({} as any)); const password = String(body?.password ?? "").trim(); - const identifier = String( + let identifier = String( body?.identifier ?? body?.email ?? body?.username ?? "" ).trim(); @@ -26,8 +26,19 @@ export async function POST(req: NextRequest) { return NextResponse.json({ error: "Missing credentials" }, { status: 400 }); } - // Directus accepts username in the "email" field for /auth/login - const data = await loginDirectus(identifier, password); + // Resolve to an email for Directus login: + // - If identifier looks like an email, use it directly. + // - Otherwise treat it as a username and look up the email. + let email = identifier.includes("@") ? identifier : null; + if (!email) { + email = await emailForUsername(identifier); + if (!email) { + return NextResponse.json({ error: "User not found" }, { status: 404 }); + } + } + + // Login against Directus; helper returns { access_token, expires } (root or .data) + const data = await loginDirectus(email, password); const access = data?.access_token ?? data?.data?.access_token ?? null; @@ -43,7 +54,7 @@ export async function POST(req: NextRequest) { const res = NextResponse.json({ ok: true }); - // Max-Age from Directus if provided; else fallback to 8h + // Use provider TTL if present, else fallback to 8h const maxAge = typeof expiresSec === "number" ? Math.max(0, Math.floor(expiresSec)) : 60 * 60 * 8; @@ -60,10 +71,11 @@ export async function POST(req: NextRequest) { 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|credentials/i.test(message) ? 401 : 400; + const status = /unauth|invalid|credential/i.test(message) ? 401 : 400; return NextResponse.json({ error: message }, { status }); } }