Skip to content
Permalink
55817306d2
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
178 lines (152 sloc) 4.44 KB
import { GenerateUploadURL } from "../../gcloud.js";
function errorResponse(error: string, status: number): Response {
return new Response(JSON.stringify({ error }), {
headers: {
"content-type": "application/json",
},
status,
});
}
export async function onRequestPost(context: RequestContext) {
const { filename, filesize, turnstileResponse, usernames } =
context.data.body;
if (!context.data.current_user) {
if (typeof turnstileResponse !== "string")
return errorResponse("You must complete the captcha", 401);
const turnstileAPIResponse = await fetch(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
{
body: JSON.stringify({
response: turnstileResponse,
secret: context.env.TURNSTILE_SECRETKEY,
}),
headers: {
"content-type": "application/json",
},
method: "POST",
}
);
const { success }: { success: boolean } = await turnstileAPIResponse.json();
if (!success) return errorResponse("Captcha test failed", 403);
}
if (!Array.isArray(usernames))
return errorResponse("Usernames must be type of array", 400);
if (typeof filename !== "string")
return errorResponse("Invalid file name", 400);
if (typeof filesize !== "number" || filesize < 0 || filesize > 536870912)
return errorResponse("Invalid file size", 400);
if (!usernames.length || usernames.length > 20)
return errorResponse(
"Number of usernames provided must be between 1 and 20",
400
);
for (const username of usernames) {
if (
username.length < 3 ||
username.length > 20 ||
username.match(/_/g)?.length > 1
)
return errorResponse(`Username "${username}" is invalid`, 400);
}
const rbxSearchReq = await fetch(
"https://users.roblox.com/v1/usernames/users",
{
body: JSON.stringify({
usernames,
excludeBannedUsers: true,
}),
headers: {
"content-type": "application/json",
},
method: "POST",
}
);
if (!rbxSearchReq.ok)
return errorResponse(
"Failed to locate Roblox users due to upstream error",
500
);
const rbxSearchData: { data: { [k: string]: any }[] } =
await rbxSearchReq.json();
if (rbxSearchData.data.length < usernames.length) {
const missingUsers = [];
for (const userData of rbxSearchData.data) {
if (!usernames.includes(userData.requestedUsername))
missingUsers.push(userData.requestedUsername);
}
return errorResponse(
`The following users do not exist or are banned from Roblox: ${missingUsers.toString()}`,
400
);
}
const metaIDs = [];
const metaNames = [];
for (const data of rbxSearchData.data) {
metaIDs.push(data.id);
metaNames.push(data.name);
}
const fileParts = filename.split(".");
let fileExt = fileParts[fileParts.length - 1];
if (
fileParts.length < 2 ||
![
"mkv",
"mp4",
"wmv",
"jpg",
"png",
"m4v",
"jpeg",
"jfif",
"gif",
"webm",
"heif",
"heic",
"webp",
"mov",
].includes(fileExt.toLowerCase())
)
return errorResponse("This type of file cannot be uploaded", 415);
const fileKey = `${crypto.randomUUID().replaceAll("-", "")}/${crypto
.randomUUID()
.replaceAll("-", "")}${context.request.headers.get("cf-ray")}${Date.now()}`;
const reportId = `${Date.now()}${context.request.headers.get(
"cf-ray"
)}${crypto.randomUUID().replaceAll("-", "")}`;
const uploadUrl = await GenerateUploadURL(
context.env,
fileKey,
filesize,
fileExt
);
await context.env.DATA.put(
`reportprocessing_${reportId}`,
context.data.current_user.id,
{ expirationTtl: 3600 }
);
await context.env.DATA.put(
`report_${reportId}`,
JSON.stringify({
attachment: `${fileKey}.${
["mkv", "mov", "wmv"].includes(fileExt.toLowerCase()) ? "mp4" : fileExt
}`,
reporter: context.data.current_user,
target_ids: metaIDs,
target_usernames: metaNames,
}),
{
metadata: {
i: context.data.current_user.id,
r: metaIDs.toString(),
p: true,
s: `${context.data.current_user.username}#${context.data.current_user.discriminator}`,
u: metaNames.toString(),
},
}
);
return new Response(JSON.stringify({ id: reportId, upload_url: uploadUrl }), {
headers: {
"content-type": "application/json",
},
});
}