'use server'; import { auth } from "@/auth"; import { getFreshAccessToken } from "@/lib/auth-utils"; import { prisma } from "@/lib/prisma"; import { revalidatePath } from "next/cache"; export async function uploadFileAction(formData: FormData) { const session = await auth(); if (!session?.user?.id) throw new Error("Unauthorized"); const file = formData.get("file") as File; const folderName = "WebCalibre"; const accessToken = await getFreshAccessToken(session.user.id); // 1. Create/Check WebCalibre Folder const folderPath = `https://graph.microsoft.com/v1.0/me/drive/root:/${folderName}`; const folderCheck = await fetch(folderPath, { headers: { Authorization: `Bearer ${accessToken}` } }); if (folderCheck.status === 404) { await fetch(`https://graph.microsoft.com/v1.0/me/drive/root/children`, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" }, body: JSON.stringify({ name: folderName, folder: {} }) }); } // 2. Create Upload Session (Supports files > 4MB) const sessionUrl = `https://graph.microsoft.com/v1.0/me/drive/root:/${folderName}/${file.name}:/createUploadSession`; const sessionRes = await fetch(sessionUrl, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" }, body: JSON.stringify({ item: { "@microsoft.graph.conflictBehavior": "rename" } }) }); const { uploadUrl } = await sessionRes.json(); // 3. Upload File Data const buffer = Buffer.from(await file.arrayBuffer()); const uploadRes = await fetch(uploadUrl, { method: "PUT", headers: { "Content-Length": `${file.size}`, "Content-Range": `bytes 0-${file.size - 1}/${file.size}` }, body: buffer }); const driveItem = await uploadRes.json(); // 4. Record in PostgreSQL await prisma.fileNode.create({ data: { oneDriveId: driveItem.id, name: file.name, size: BigInt(file.size), isFolder: false, path: `/${folderName}/${file.name}`, ownerId: session.user.id, metadata: { type: file.name.split('.').pop()?.toUpperCase() } } }); revalidatePath("/dashboard"); return { success: true }; }