Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Create initial new infraction endpoint
  • Loading branch information
regalijan committed Oct 19, 2023
1 parent 58822f8 commit 98f00d5
Showing 1 changed file with 139 additions and 0 deletions.
139 changes: 139 additions & 0 deletions functions/api/infractions/new.ts
@@ -0,0 +1,139 @@
import { GenerateUploadURL } from "../../gcloud.js";

const allowedFileTypes = [
"image/gif",
"image/heic",
"image/heif",
"image/jpeg",
"image/png",
"video/mp4",
"video/webm",
];

export async function onRequestPost(context: RequestContext) {
if (
!context.data.current_user?.permissions ||
![1 << 0, 1 << 2, 1 << 11].find(
(p) => context.data.current_user.permissions & p
)
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});

if (
context.request.headers
.get("content-type")
?.startsWith("multipart/form-data; boundary=")
)
return new Response('{"error":"Invalid content type"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});

let body: FormData;

try {
body = await context.request.formData();
} catch {
return new Response('{"error":"Invalid form data"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
}

if (
![
"verbal",
"warn",
"mute",
"ban_temp",
"ban_perm",
"ban_unappealable",
].includes(body.get("punishment") as string)
)
return new Response('{"error":"Invalid punishment"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});

if (!(body.get("user") as string).match(/^\d{17,19}$/))
return new Response('{"error":"Invalid user"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});

// @ts-expect-error
const files: File[] = body.keys().find((key) => key.match(/^files\[\d]$/));
const urlPromises = [];

for (const file of files) {
if (!allowedFileTypes.includes(file.type))
return new Response(`{"error":"File ${file.name} is not valid"}`, {
headers: {
"content-type": "application/json",
},
status: 415,
});

const attachmentKey = `${Date.now()}${Math.round(
Math.random() * 10000000
).toString()}/${file.name}`;

urlPromises.push(
GenerateUploadURL(
context.env,
attachmentKey,
file.size,
(allowedFileTypes.find((t) => t === file.type) as string).split("/")[1]
)
);
}

const settledURLPromises = await Promise.allSettled(urlPromises);

if (settledURLPromises.find((p) => p.status === "rejected"))
return new Response('{"error":"Failed to process one or more files"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});

const infractionId = `${body.get("user")}${Date.now()}${
context.request.headers.get("cf-ray")?.split("-")[0]
}`;
const uploadReqs = [];

for (let i = 0; i < files.length; i++) {
uploadReqs.push(
fetch(settledURLPromises[i] as unknown as string, {
body: files[i],
method: "PUT",
})
);
}

await context.env.DATA.put(
infractionId,
JSON.stringify({
created_at: Date.now(),
moderator: context.data.current_user.id,
})
);

return new Response(null, {
status: 204,
});
}

0 comments on commit 98f00d5

Please sign in to comment.