124_webcalibre2/src/app/dashboard/upload-actions.ts

68 lines
2.2 KiB
TypeScript
Raw Normal View History

'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 };
}