import { jsonError, jsonResponse } from "../../common.js"; export async function onRequestPost(context: RequestContext) { let formData: FormData; try { formData = await context.request.formData(); } catch { return jsonError("Malformed form data", 400); } const files: File[] = []; for (const file of formData.getAll("file")) { if (typeof file === "string") { return jsonError("'file' must be a file", 400); } if (file.type === "image") { } files.push(file); } let bytes = 0; for (const file of files) { bytes += new Blob([file]).size; } if (bytes > 26214400) return jsonError("Files too large (max 25MB)", 413); const type = formData.get("type"); if ( typeof type !== "string" || ["purchase", "reset", "transfer"].includes(type) ) return jsonError( "'type' must be one of ('purchase', 'reset', 'transfer')", 400, ); const { R2 } = context.env; const { prisma } = context.data; const requestId = `${Date.now()}${crypto.randomUUID().replaceAll("-", "")}`; await prisma.dataRequest.create({ data: { id: requestId, status: type === "transfer" ? "verification_required" : "pending", target_user: 0, type, }, }); const attachmentIds = []; for (let i = 0; i < files.length; i++) { attachmentIds.push( `${Date.now()}${crypto.randomUUID().replaceAll("-", "")}`, ); } const uploadPromises = []; for (let i = 0; i < attachmentIds.length; i++) { uploadPromises.push(R2.put(`dt/${attachmentIds[i]}`, files[i])); } const settledUploads = (await Promise.allSettled(uploadPromises)).filter( (p) => p.status === "fulfilled", ); const attachmentList = settledUploads.map((u) => (u.value as R2Object).key.replace("dt/", ""), ); if (attachmentList.length > 0) { await prisma.dataRequest.update({ data: { attachments: attachmentList, }, where: { id: requestId, }, }); const url = new URL(context.request.url); url.pathname = "/data-transfers/verify"; return jsonResponse( JSON.stringify({ url: `https://apis.roblox.com/oauth/v1/authorize?client_id=${context.env.ROBLOX_OAUTH_CLIENT_ID}&redirect_uri=${encodeURIComponent(url.href)}&response_type=code&scope=openid&state=${requestId}`, }), ); } return new Response("{}", { headers: { "Content-Type": "application/json", Location: `/data-request/status/${requestId}`, }, status: 201, }); }