"use server"; import { mkdir, writeFile } from "node:fs/promises"; import path from "node:path"; import { revalidatePath } from "next/cache"; import { redirect } from "next/navigation"; import { prisma } from "./prisma"; import { requireCurrentUser } from "./session"; import { getAppSettings } from "./settings"; const avatarTypes = new Map([ ["image/png", "png"], ["image/jpeg", "jpg"], ["image/webp", "webp"], ["image/gif", "gif"] ]); export async function updateProfile(formData: FormData) { const user = await requireCurrentUser(); const displayName = String(formData.get("displayName") || user.username).trim().slice(0, 80) || user.username; const avatar = formData.get("avatar"); const data: { displayName: string; avatarUrl?: string } = { displayName }; if (avatar instanceof File && avatar.size > 0) { const settings = await getAppSettings(); const extension = avatarTypes.get(avatar.type); const maxBytes = settings.maxAvatarUploadMb * 1024 * 1024; if (!extension || avatar.size > maxBytes) { redirect("/account/settings?error=avatar"); } const uploadsDir = path.join(process.cwd(), "public", "uploads", "avatars"); await mkdir(uploadsDir, { recursive: true }); const fileName = `${user.id}-${Date.now()}.${extension}`; await writeFile(path.join(uploadsDir, fileName), Buffer.from(await avatar.arrayBuffer())); data.avatarUrl = `/uploads/avatars/${fileName}`; } await prisma.user.update({ where: { id: user.id }, data }); revalidatePath("/account/profile"); revalidatePath("/account/settings"); revalidatePath("/dashboard"); redirect("/account/settings?saved=1"); }