Files
car-crushers-portal/functions/api/data-requests/start.ts
T
regalijan 90525f9631
Test, Build, Deploy / Test, Build, and Deploy (push) Failing after 1m22s
Test, Build, Deploy / Create Sentry Release (push) Has been skipped
May as well push now
2026-06-30 21:56:15 -04:00

105 lines
2.5 KiB
TypeScript

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,
});
}