2026-01-08 05:41:31 +00:00
|
|
|
'use server';
|
|
|
|
|
import { auth } from "@/auth";
|
|
|
|
|
import { prisma } from "@/lib/prisma";
|
|
|
|
|
import { revalidatePath } from "next/cache";
|
2026-01-11 13:41:54 +00:00
|
|
|
import { getFreshAccessToken } from "@/lib/auth-utils";
|
2026-01-08 05:41:31 +00:00
|
|
|
|
|
|
|
|
export async function syncOneDrive() {
|
|
|
|
|
const session = await auth();
|
|
|
|
|
if (!session?.user?.id) throw new Error("Unauthorized");
|
|
|
|
|
|
2026-01-11 13:41:54 +00:00
|
|
|
try {
|
|
|
|
|
const accessToken = await getFreshAccessToken(session.user.id);
|
|
|
|
|
const response = await fetch("https://graph.microsoft.com/v1.0/me/drive/root:/WebCalibre:/children", {
|
2026-01-13 13:17:40 +00:00
|
|
|
headers: { Authorization: `Bearer ${accessToken}` },
|
2026-01-08 05:41:31 +00:00
|
|
|
});
|
2026-01-11 13:41:54 +00:00
|
|
|
|
2026-01-13 13:17:40 +00:00
|
|
|
if (!response.ok) return { success: true, count: 0 };
|
2026-01-11 13:41:54 +00:00
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
let syncedCount = 0;
|
|
|
|
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
|
|
|
|
|
|
|
|
for (const item of data.value) {
|
|
|
|
|
const isFolder = !!item.folder;
|
|
|
|
|
|
2026-01-13 13:17:40 +00:00
|
|
|
// Only skip if it's a folder AND it's a UUID (storage container)
|
|
|
|
|
// If a user named a file with a UUID, we still want it.
|
2026-01-11 13:41:54 +00:00
|
|
|
if (isFolder && uuidRegex.test(item.name)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 13:17:40 +00:00
|
|
|
const extension = isFolder ? 'FOLDER' : (item.name.split('.').pop()?.toUpperCase() || 'UNKNOWN');
|
2026-01-11 13:41:54 +00:00
|
|
|
|
|
|
|
|
await prisma.fileNode.upsert({
|
2026-01-13 13:17:40 +00:00
|
|
|
where: { oneDriveId: item.id }, // Primary match
|
2026-01-11 13:41:54 +00:00
|
|
|
update: {
|
|
|
|
|
name: item.name,
|
2026-01-13 13:17:40 +00:00
|
|
|
size: BigInt(item.size || 0),
|
2026-01-11 13:41:54 +00:00
|
|
|
isFolder: isFolder,
|
|
|
|
|
path: item.parentReference?.path + '/' + item.name,
|
|
|
|
|
updatedAt: new Date(),
|
|
|
|
|
},
|
|
|
|
|
create: {
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
oneDriveId: item.id,
|
|
|
|
|
name: item.name,
|
2026-01-13 13:17:40 +00:00
|
|
|
size: BigInt(item.size || 0),
|
2026-01-11 13:41:54 +00:00
|
|
|
isFolder: isFolder,
|
|
|
|
|
path: item.parentReference?.path + '/' + item.name,
|
|
|
|
|
ownerId: session.user.id,
|
2026-01-13 13:17:40 +00:00
|
|
|
metadata: { type: extension, mimeType: item.file?.mimeType || null },
|
2026-01-11 13:41:54 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
syncedCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
revalidatePath('/dashboard');
|
|
|
|
|
return { success: true, count: syncedCount };
|
|
|
|
|
} catch (error: any) {
|
2026-01-13 13:17:40 +00:00
|
|
|
throw new Error(error.message);
|
2026-01-08 05:41:31 +00:00
|
|
|
}
|
|
|
|
|
}
|