50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
"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");
|
|
}
|