makearmy-app/app/api/account/avatar/route.ts
2025-09-30 17:04:37 -04:00

60 lines
2.1 KiB
TypeScript

// app/api/account/avatar/route.ts
export const runtime = "nodejs";
import { NextResponse } from "next/server";
import { requireBearer } from "@/app/api/_lib/auth";
const API = (process.env.NEXT_PUBLIC_API_BASE_URL || "").replace(/\/$/, "");
const AVATAR_FOLDER_ID = process.env.DIRECTUS_AVATAR_FOLDER_ID || "";
function bad(msg: string, code = 400) {
return NextResponse.json({ error: msg }, { status: code });
}
export async function POST(req: Request) {
try {
if (!AVATAR_FOLDER_ID) {
return bad("Server misconfiguration: DIRECTUS_AVATAR_FOLDER_ID is not set", 500);
}
const bearer = requireBearer(req);
const form = await req.formData();
const file = form.get("file");
if (!(file instanceof Blob)) return bad("Missing file");
// Upload directly into the configured avatars folder
const up = new FormData();
up.set("file", file, (file as any).name || "avatar.bin");
up.set("folder", AVATAR_FOLDER_ID);
const r1 = await fetch(`${API}/files`, {
method: "POST",
headers: { Authorization: `Bearer ${bearer}` },
body: up,
});
const j1 = await r1.json().catch(() => ({}));
if (!r1.ok) {
const msg = j1?.errors?.[0]?.message || "Upload failed";
return bad(msg, r1.status);
}
const fileId: string = j1?.data?.id ?? j1?.id;
// Link file to the current user
const r2 = await fetch(`${API}/users/me`, {
method: "PATCH",
headers: { Authorization: `Bearer ${bearer}`, "Content-Type": "application/json" },
body: JSON.stringify({ avatar: fileId }),
});
const j2 = await r2.json().catch(() => ({}));
if (!r2.ok) {
const msg = j2?.errors?.[0]?.message || "Link avatar failed";
return bad(msg, r2.status);
}
// Respond with the updated avatar reference
return NextResponse.json({ ok: true, avatar: j2?.data?.avatar ?? { id: fileId } });
} catch (e: any) {
return bad(e?.message || "Upload error", e?.status || 500);
}
}