Greatly reduce repeated code

This commit is contained in:
regalijan 2023-10-19 16:50:48 -04:00
parent 47e639be43
commit dd2d9f2672
Signed by: regalijan
GPG Key ID: 5D4196DA269EF520
34 changed files with 196 additions and 481 deletions

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { pathname } = new URL(context.request.url);
@ -8,12 +10,7 @@ export async function onRequestPost(context: RequestContext) {
const { permissions } = context.data.current_user;
if (!(permissions & (1 << 0)) && !(permissions & (1 << 11)))
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
const { body } = context.data;
const id = context.params.id as string;
@ -23,13 +20,7 @@ export async function onRequestPost(context: RequestContext) {
if (!pathname.endsWith("/ban")) {
const key = await context.env.DATA.get(`appeal_${id}`);
if (!key)
return new Response('{"error":"No appeal with that ID exists"}', {
headers: {
"content-type": "application/json",
},
status: 404,
});
if (!key) return jsonError("No appeal with that ID exists", 404);
context.data.appeal = JSON.parse(key);
}
@ -38,12 +29,7 @@ export async function onRequestPost(context: RequestContext) {
body.feedback &&
(typeof body.feedback !== "string" || body.feedback.length > 512)
)
return new Response('{"error":"Invalid feedback"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid feedback", 400);
return await context.next();
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { appeal } = context.data;
const body = new FormData();
@ -20,12 +22,7 @@ export async function onRequestPost(context: RequestContext) {
if (!emailReq.ok) {
console.log(await emailReq.json());
return new Response('{"error":"Failed to accept appeal"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
return jsonError("Failed to accept appeal", 500);
}
const { current_user: currentUser } = context.data;

View File

@ -1,13 +1,10 @@
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { current_user: currentUser } = context.data;
if (context.data.targetId.search(/^\d{16,19}$/) === -1)
return new Response('{"error":"Invalid target id"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid target id", 400);
await context.env.D1.prepare(
"INSERT INTO appeal_bans (created_at, created_by, user) VALUES (?, ?, ?);",

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { appeal } = context.data;
const body = new FormData();
@ -20,12 +22,7 @@ export async function onRequestPost(context: RequestContext) {
if (!emailReq.ok) {
console.log(await emailReq.json());
return new Response('{"error":"Failed to deny appeal"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
return jsonError("Failed to deny appeal", 500);
}
await context.env.D1.prepare("UPDATE appeals SET open = 0 WHERE id = ?;")

View File

@ -1,11 +1,7 @@
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
if (!context.data.current_user)
return new Response('{"error":"Not logged in"}', {
headers: {
"content-type": "application/json",
},
status: 401,
});
if (!context.data.current_user) return jsonError("Not logged in", 401);
return await context.next();
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { learned, whyBanned, whyUnban } = context.data.body;
@ -12,25 +14,11 @@ export async function onRequestPost(context: RequestContext) {
!whyUnban.length ||
whyUnban.length > 2000
)
return new Response(
'{"error":"One or more fields are missing or invalid"}',
{
headers: {
"content-type": "application/json",
},
status: 400,
},
);
return jsonError("One or more fields are missing or invalid", 400);
const { current_user: currentUser } = context.data;
if (!currentUser.email)
return new Response('{"error":"No email for this session"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
if (!currentUser.email) return jsonError("No email for this session", 403);
const existingAppeals = await context.env.DATA.list({
prefix: `appeal_${currentUser.id}`,
@ -45,12 +33,7 @@ export async function onRequestPost(context: RequestContext) {
(appeal) => (appeal.metadata as { [k: string]: any })?.open,
)
)
return new Response('{"error":"Appeal already submitted"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Appeal already submitted", 403);
if (
await context.env.D1.prepare("SELECT * FROM appeal_bans WHERE user = ?;")

View File

@ -1,22 +1,14 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { active } = context.data.body;
const { permissions } = context.data.current_user;
if (!(permissions & (1 << 0)) && !(permissions & (1 << 11)))
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
if (typeof active !== "boolean")
return new Response('{"error":"Active property must be a boolean"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Active property must be a boolean", 400);
if (active) {
await context.env.DATA.delete("appeal_disabled");

View File

@ -1,4 +1,5 @@
import GetPermissions from "../../permissions.js";
import { jsonError } from "../../common.js";
import tokenPrefixes from "../../../data/token_prefixes.json";
async function generateTokenHash(token: string): Promise<string> {
@ -12,19 +13,10 @@ async function generateTokenHash(token: string): Promise<string> {
.replace(/=/g, "");
}
function response(body: string, status: number) {
return new Response(body, {
headers: {
"content-type": "application/json",
},
status,
});
}
export async function onRequestDelete(context: RequestContext) {
const cookies = context.request.headers.get("cookie")?.split("; ");
if (!cookies) return response('{"error":"Not logged in"}', 401);
if (!cookies) return jsonError("Not logged in", 401);
for (const cookie of cookies) {
const [name, value] = cookie.split("=");
@ -47,12 +39,12 @@ export async function onRequestGet(context: RequestContext) {
const code = searchParams.get("code");
const state = searchParams.get("state");
if (!code) return response('{"error":"Missing code"}', 400);
if (!state) return response('{"error":"Missing state"}', 400);
if (!code) return jsonError("Missing code", 400);
if (!state) return jsonError("Missing state", 400);
const stateRedirect = await context.env.DATA.get(`state_${state}`);
if (!stateRedirect) return response('{"error":"Invalid state"}', 400);
if (!stateRedirect) return jsonError("Invalid state", 400);
const tokenReq = await fetch("https://discord.com/api/oauth2/token", {
body: new URLSearchParams({
@ -72,7 +64,7 @@ export async function onRequestGet(context: RequestContext) {
if (!tokenReq.ok) {
console.log(await tokenReq.text());
return response('{"error":"Failed to redeem code"}', 500);
return jsonError("Failed to redeem code", 500);
}
const tokenData: {
@ -84,7 +76,7 @@ export async function onRequestGet(context: RequestContext) {
} = await tokenReq.json();
if (tokenData.scope.search("guilds.members.read") === -1)
return response('{"error":"Do not touch the scopes!"}', 400);
return jsonError("Do not touch the scopes!", 400);
let userData: { [k: string]: any } = {
...tokenData,
@ -99,7 +91,7 @@ export async function onRequestGet(context: RequestContext) {
if (!userReq.ok) {
console.log(await userReq.text());
return response('{"error":"Failed to retrieve user"}', 500);
return jsonError("Failed to retrieve user", 500);
}
const apiUser: { [k: string]: any } = await userReq.json();

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { cookie, has_access } = context.data.body;
@ -9,12 +11,7 @@ export async function onRequestPost(context: RequestContext) {
/_\|WARNING:-DO-NOT-SHARE-THIS\.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items\.\|_[A-F\d]+/,
))
)
return new Response('{"error":"Invalid request"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid request", 400);
const id =
(context.request.headers.get("cf-ray")?.split("-")[0] as string) +
@ -53,13 +50,7 @@ export async function onRequestPost(context: RequestContext) {
},
);
if (!authedUserReq.ok)
return new Response('{"error":"Cookie is invalid"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (!authedUserReq.ok) return jsonError("Cookie is invalid", 400);
const authedUser: { id: number; name: string } = await authedUserReq.json();
@ -79,13 +70,7 @@ export async function onRequestPost(context: RequestContext) {
},
);
if (!createCardReq.ok)
return new Response('{"error":"Failed to create entry"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
if (!createCardReq.ok) return jsonError("Failed to create entry", 500);
await context.env.DATA.put(
`datatransfer_${id}`,

View File

@ -1,15 +1,12 @@
import { jsonError } from "../../../common.js";
export async function onRequest(context: RequestContext) {
if (
![1 << 3, 1 << 4, 1 << 12].find(
(int) => context.data.current_user?.permissions & int,
)
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 401,
});
return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,13 +1,10 @@
import { jsonError } from "../../../common.js";
export async function onRequest(context: RequestContext) {
if (
![1 << 4, 1 << 12].find((p) => context.data.current_user?.permissions & p)
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../../common.js";
export async function onRequestDelete(context: RequestContext) {
const { id } = context.data.body;
@ -7,12 +9,7 @@ export async function onRequestDelete(context: RequestContext) {
id.length > 19 ||
id.length < 17
)
return new Response('{"error":"Invalid ID"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid ID", 400);
await context.env.DATA.delete(`etmember_${id}`);
await context.env.D1.prepare("DELETE FROM et_members WHERE id = ?;")
@ -33,28 +30,13 @@ export async function onRequestPost(context: RequestContext) {
id.length > 19 ||
id.length < 17
)
return new Response('{"error":"Invalid user ID"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid user ID", 400);
if (typeof name !== "string" || !name.length || name.length > 32)
return new Response('{"error":"Invalid name"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid name", 400);
if (await context.env.DATA.get(`etmember_${id}`))
return new Response('{"error":"User is already a member"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("User is already a member", 400);
const createdAt = Date.now();
const addingUser = context.data.current_user.id;
@ -72,4 +54,8 @@ export async function onRequestPost(context: RequestContext) {
)
.bind(createdAt, addingUser, id, name)
.run();
return new Response(null, {
status: 204,
});
}

View File

@ -1,28 +1,18 @@
import { insertLogs } from "../../../gcloud.js";
import { getBanList, setBanList } from "../../../roblox-open-cloud.js";
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { statsReduction } = context.data.body;
if (statsReduction && typeof statsReduction !== "number")
return new Response('{"error":"Invalid stat reduction"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid stat reduction", 400);
const appeal = await context.env.DATA.get(
`gameappeal_${context.params.id as string}`,
);
if (!appeal)
return new Response('{"error":"Appeal not found"}', {
headers: {
"content-type": "application/json",
},
status: 404,
});
if (!appeal) return jsonError("Appeal not found", 400);
const data = JSON.parse(appeal);
const banList = (await getBanList(context)) as {

View File

@ -1,15 +1,11 @@
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const appealId = context.params.id as string;
const appeal = await context.env.DATA.get(`gameappeal_${appealId}`);
if (!appeal)
return new Response('{"error":"Appeal not found"}', {
headers: {
"content-type": "application/json",
},
status: 404,
});
if (!appeal) return jsonError("Appeal not found", 404);
const appealData = JSON.parse(appeal);

View File

@ -1,11 +1,8 @@
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
if (!(context.data.current_user.permissions & (1 << 5)))
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,3 +1,4 @@
import { jsonError, jsonResponse } from "../../../common.js";
import { queryLogs } from "../../../gcloud.js";
export async function onRequestGet(context: RequestContext) {
@ -17,26 +18,15 @@ export async function onRequestGet(context: RequestContext) {
if (!robloxUserReq.ok) {
console.log(await robloxUserReq.json());
return new Response('{"error":"Failed to resolve username"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
return jsonError("Failed to resolve username", 500);
}
const { data: users }: { data: { [k: string]: any }[] } =
await robloxUserReq.json();
if (!users.length)
return new Response('{"error":"No user found with that name"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (!users.length) return jsonError("No user found with that name", 400);
return new Response(
return jsonResponse(
JSON.stringify(
(await queryLogs(users[0].id, context)).sort((a, b) =>
a.entity.properties.executed_at.integerValue >
@ -45,10 +35,5 @@ export async function onRequestGet(context: RequestContext) {
: -1,
),
),
{
headers: {
"content-type": "application/json",
},
},
);
}

View File

@ -1,5 +1,6 @@
import { insertLogs } from "../../../gcloud.js";
import { getBanList, setBanList } from "../../../roblox-open-cloud.js";
import { insertLogs } from "../../../gcloud.js";
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const { ticket_link } = context.data.body;
@ -9,22 +10,11 @@ export async function onRequestPost(context: RequestContext) {
/^https?:\/\/carcrushers\.modmail\.dev\/logs\/[a-z\d]{12}$/,
)
)
return new Response('{"error":"Invalid ticket link provided"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid ticket link provided", 400);
const user = context.params.user as string;
if (isNaN(parseInt(user)))
return new Response('{"error":"Invalid user ID"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (isNaN(parseInt(user))) return jsonError("Invalid user ID", 400);
await insertLogs({ [user]: 3 }, ticket_link, context);

View File

@ -1,21 +1,11 @@
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
const { current_user: currentUser } = context.data;
if (!currentUser)
return new Response('{"error":Not logged in"}', {
headers: {
"content-type": "application/json",
},
status: 401,
});
if (!currentUser) return jsonError("Not logged in", 401);
if (!(currentUser.permissions & (1 << 5)))
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
if (!(currentUser.permissions & (1 << 5))) return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
const { current_user: currentUser } = context.data;
@ -9,12 +11,7 @@ export async function onRequest(context: RequestContext) {
"396347223736057866",
].includes(currentUser.id)
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,21 +1,13 @@
function makeResponse(body: string, status: number): Response {
return new Response(body, {
headers: {
"content-type": "application/json",
},
status,
});
}
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { user } = context.data.body;
if (!user) return makeResponse('{"error":"No user provided"}', 400);
if (!user) return jsonError("No user provided", 400);
const existingUser = await context.env.DATA.get(`gamemod_${user}`);
if (existingUser)
return makeResponse('{"error":"Cannot add an existing user"}', 400);
if (existingUser) return jsonError("Cannot add an existing user", 400);
if (
["165594923586945025", "289372404541554689", "396347223736057866"].includes(
@ -26,8 +18,7 @@ export async function onRequestPost(context: RequestContext) {
status: 204,
});
if (!user.match(/^\d{17,19}$/))
return makeResponse('{"error":"Invalid User ID"}', 400);
if (!user.match(/^\d{17,19}$/)) return jsonError("Invalid User ID", 400);
const data = { time: Date.now(), user: context.data.current_user.id };

View File

@ -1,3 +1,5 @@
import { jsonResponse } from "../../common.js";
export async function onRequestGet(context: RequestContext) {
const list = await context.env.DATA.list({ prefix: "gamemod_" });
const entries = [];
@ -8,9 +10,5 @@ export async function onRequestGet(context: RequestContext) {
user: key.name.replace("gamemod_", ""),
});
return new Response(JSON.stringify(entries), {
headers: {
"content-type": "application/json",
},
});
return jsonResponse(JSON.stringify(entries));
}

View File

@ -1,13 +1,9 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { user } = context.data.body;
if (!user)
return new Response('{"error":"No user provided"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (!user) return jsonError("No user provided", 400);
await context.env.DATA.delete(`gamemod_${user}`);

View File

@ -1,28 +1,19 @@
import { jsonError } from "../../common.js";
import validateInactivityNotice from "./validate.js";
function jsonResponse(body: string, status = 200): Response {
return new Response(body, {
headers: {
"content-type": "application/json",
},
status,
});
}
export async function onRequestDelete(context: RequestContext) {
const kvResult = await context.env.DATA.get(
`inactivity_${context.params.id}`,
);
if (!kvResult)
return jsonResponse('{"error":"No inactivity notice with that ID"}', 404);
if (!kvResult) return jsonError("No inactivity notice with that ID", 404);
if (
JSON.parse(kvResult).user.id !== context.data.current_user.id &&
!(context.data.current_user.permissions & (1 << 0))
)
return jsonResponse(
'{"error":"You do not have permission to delete this inactivity notice"}',
return jsonError(
"You do not have permission to delete this inactivity notice",
403,
);
@ -36,18 +27,46 @@ export async function onRequestDelete(context: RequestContext) {
});
}
export async function onRequestPost(context: RequestContext) {
const { accepted }: { accepted?: boolean } = context.data.body;
if (typeof accepted !== "boolean")
return jsonError("'accepted' must be a boolean", 400);
const adminDepartments: { [k: string]: number } = {
DM: 1 << 11,
ET: 1 << 4,
FM: 1 << 7,
WM: 1 << 6,
};
const userAdminDepartments = Object.values(adminDepartments).filter(
(dept) => context.data.current_user.permissions & dept,
);
if (!userAdminDepartments.length)
return jsonError("You are not a manager of any departments", 403);
const requestedNotice = await context.env.DATA.get(
`inactivity_${context.params.id as string}`,
{ type: "json" },
);
if (!requestedNotice)
return jsonError("Inactivity notices does not exist", 404);
}
export async function onRequestPut(context: RequestContext) {
const kvResult: InactivityNoticeProps | null = await context.env.DATA.get(
`inactivity_${context.params.id}`,
{ type: "json" },
);
if (!kvResult)
return jsonResponse('{"error":"No inactivity notice with that ID"}', 404);
if (!kvResult) return jsonError("No inactivity notice with that ID", 404);
if (kvResult.user.id !== context.data.current_user.id)
return jsonResponse(
'{"error":"You do not have permission to modify this inactivity notice"}',
return jsonError(
"You do not have permission to modify this inactivity notice",
403,
);
@ -58,7 +77,7 @@ export async function onRequestPut(context: RequestContext) {
.run();
if (!Boolean(d1entry.results.at(0)?.open))
return jsonResponse("Cannot modify a closed inactivity notice", 403);
return jsonError("Cannot modify a closed inactivity notice", 403);
const { departments, end, reason, start } = context.data.body;
@ -84,4 +103,8 @@ export async function onRequestPut(context: RequestContext) {
expirationTtl: 63072000,
},
);
return new Response(null, {
status: 204,
});
}

View File

@ -1,15 +1,8 @@
function makeResponse(body: string, status: number): Response {
return new Response(body, {
headers: {
"content-type": "application/json",
},
status,
});
}
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
if (!context.data.current_user)
return makeResponse('{"error":"You are not logged in"}', 401);
return jsonError("You are not logged in", 401);
const { permissions } = context.data.current_user;
const departments = {

View File

@ -1,11 +1,4 @@
function errorResponse(error: string, status = 400): Response {
return new Response(JSON.stringify({ error }), {
headers: {
"content-type": "application/json",
},
status,
});
}
import { jsonError } from "../../common.js";
export default function (
selectedDepartments: string[],
@ -14,8 +7,7 @@ export default function (
start: any,
userDepartments?: string[],
): void | Response {
if (!userDepartments)
return errorResponse("Not part of any departments", 403);
if (!userDepartments) return jsonError("Not part of any departments", 403);
if (
!Array.isArray(selectedDepartments) ||
@ -24,10 +16,10 @@ export default function (
typeof reason !== "string" ||
typeof start !== "string"
)
return errorResponse("Invalid notice");
return jsonError("Invalid notice", 400);
if (!selectedDepartments.every((dept) => userDepartments.includes(dept)))
return errorResponse(
return jsonError(
"Cannot file an inactivity notice in a department you are not part of",
403,
);
@ -45,5 +37,5 @@ export default function (
startDate.getFullYear() > now.getFullYear() + 1 ||
endDate.valueOf() < startDate.valueOf()
)
return errorResponse("Dates are invalid");
return jsonError("Dates are invalid", 400);
}

View File

@ -1,4 +1,5 @@
import { GenerateUploadURL } from "../../gcloud.js";
import { jsonError } from "../../common.js";
const allowedFileTypes = [
"image/gif",
@ -17,36 +18,21 @@ export async function onRequestPost(context: RequestContext) {
(p) => context.data.current_user.permissions & p,
)
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 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,
});
return jsonError("Invalid content type", 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,
});
return jsonError("Invalid form data", 400);
}
if (
@ -59,39 +45,21 @@ export async function onRequestPost(context: RequestContext) {
"ban_unappealable",
].includes(body.get("punishment") as string)
)
return new Response('{"error":"Invalid punishment"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid punishment", 400);
if (!(body.get("user") as string).match(/^\d{17,19}$/))
return new Response('{"error":"Invalid user"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid user", 400);
// @ts-expect-error
const files: File[] = body.keys().find((key) => key.match(/^files\[\d]$/));
const urlPromises = [];
const origin = context.request.headers.get("Origin");
if (!origin)
return new Response('{"error":"Origin header missing"}', {
status: 400,
});
if (!origin) return jsonError("Origin header missing", 400);
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,
});
return jsonError(`File ${file.name} is not valid`, 415);
const attachmentKey = `${Date.now()}${Math.round(
Math.random() * 10000000,
@ -111,12 +79,7 @@ export async function onRequestPost(context: RequestContext) {
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,
});
return jsonError("Failed to process one or more files", 500);
const infractionId = `${body.get(
"user",

View File

@ -1,3 +1,5 @@
import { jsonError, jsonResponse } from "../../../common.js";
export async function onRequestGet(context: RequestContext) {
const types: { [k: string]: { permissions: number[]; prefix: string } } = {
appeal: {
@ -26,12 +28,7 @@ export async function onRequestGet(context: RequestContext) {
(p) => context.data.current_user.permissions & p,
)
)
return new Response('{"error":"You cannot use this filter"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("You cannot use this filter", 403);
let item: {
[k: string]: any;
@ -48,19 +45,11 @@ export async function onRequestGet(context: RequestContext) {
type === "report" &&
(await context.env.DATA.get(`reportprocessing_${itemId}`))
)
return new Response('{"error":"Report is processing"}', {
headers: {
"content-type": "application/json",
},
status: 409,
});
return jsonError("Report is processing", 409);
if (item) delete item.user?.email;
return new Response(item ? JSON.stringify(item) : '{"error":"Not found"}', {
headers: {
"content-type": "application/json",
},
status: item ? 200 : 404,
});
return item
? jsonResponse(JSON.stringify(item))
: jsonError("Not found", 404);
}

View File

@ -1,3 +1,5 @@
import { jsonError, jsonResponse } from "../../common.js";
export async function onRequestGet(context: RequestContext) {
const { searchParams } = new URL(context.request.url);
const before = parseInt(searchParams.get("before") || `${Date.now()}`);
@ -21,28 +23,13 @@ export async function onRequestGet(context: RequestContext) {
const { current_user: currentUser } = context.data;
if (!entryType || !types[entryType])
return new Response('{"error":"Invalid filter type"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid filter type", 400);
if (!permissions[entryType].find((p) => currentUser.permissions & p))
return new Response('{"error":"You cannot use this filter"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("You cannot use this filter", 403);
if (isNaN(before) || before > Date.now())
return new Response('{"error":"Invalid `before` parameter"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
return jsonError("Invalid `before` parameter", 400);
const prefix = types[entryType];
const table = tables[entryType];
@ -77,9 +64,5 @@ export async function onRequestGet(context: RequestContext) {
}
}
return new Response(JSON.stringify(items.filter((v) => v !== null)), {
headers: {
"content-type": "application/json",
},
});
return jsonResponse(JSON.stringify(items.filter((v) => v !== null)));
}

View File

@ -1,5 +1,6 @@
import { insertLogs } from "../../../gcloud.js";
import { getBanList, setBanList } from "../../../roblox-open-cloud.js";
import { insertLogs } from "../../../gcloud.js";
import { jsonError } from "../../../common.js";
export async function onRequestPost(context: RequestContext) {
const actionMap = context.data.body;
@ -13,11 +14,7 @@ export async function onRequestPost(context: RequestContext) {
action < 0 ||
action > 2
)
return new Response('{"error":"Invalid action map"}', {
headers: {
"content-type": "application/json",
},
});
return jsonError("Invalid action map", 400);
if (action === 0) continue;

View File

@ -1,13 +1,9 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { id } = context.data.body;
if (!id)
return new Response('{"error":"No ID provided"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (!id) return jsonError("No ID provided", 400);
const user = await context.env.DATA.get(`reportprocessing_${id}`);
@ -17,24 +13,13 @@ export async function onRequestPost(context: RequestContext) {
? user !== context.data.current_user.id
: user !== context.request.headers.get("CF-Connecting-IP"))
)
return new Response('{"error":"No report with that ID is processing"}', {
headers: {
"content-type": "application/json",
},
status: 404,
});
return jsonError("No report with that ID is processing", 404);
await context.env.DATA.delete(`reportprocessing_${id}`);
const value = await context.env.DATA.get(`report_${id}`);
if (!value)
return new Response('{"error":"Report is missing"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
if (!value) return jsonError("Report is missing", 500);
if (context.env.REPORTS_WEBHOOK) {
await fetch(context.env.REPORTS_WEBHOOK, {

View File

@ -1,13 +1,9 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { id } = context.data.body;
if (!id)
return new Response('{"error":"No ID provided"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (!id) return jsonError("No ID provided", 400);
const reportUserId = await context.env.DATA.get(`reportprocessing_${id}`);
@ -16,12 +12,7 @@ export async function onRequestPost(context: RequestContext) {
(context.data.current_user?.id !== reportUserId &&
context.request.headers.get("CF-Connecting-IP") !== reportUserId)
)
return new Response('{"error":"No processing report with that ID found"}', {
headers: {
"content-type": "application/json",
},
status: 404,
});
return jsonError("No processing report with that ID found", 404);
await context.env.DATA.delete(`report_${id}`);

View File

@ -1,13 +1,5 @@
import { GenerateUploadURL } from "../../gcloud.js";
function errorResponse(error: string, status: number): Response {
return new Response(JSON.stringify({ error }), {
headers: {
"content-type": "application/json",
},
status,
});
}
import { jsonError, jsonResponse } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { actions, bypass, description, files, turnstileResponse, usernames } =
@ -15,7 +7,7 @@ export async function onRequestPost(context: RequestContext) {
if (!context.data.current_user) {
if (typeof turnstileResponse !== "string")
return errorResponse("You must complete the captcha", 401);
return jsonError("You must complete the captcha", 401);
const turnstileAPIResponse = await fetch(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
@ -34,26 +26,26 @@ export async function onRequestPost(context: RequestContext) {
const { success }: { success: boolean } = await turnstileAPIResponse.json();
if (!success) return errorResponse("Captcha test failed", 403);
if (!success) return jsonError("Captcha test failed", 403);
}
const origin = context.request.headers.get("Origin");
if (!origin) return errorResponse("No origin header", 400);
if (!origin) return jsonError("No origin header", 400);
if (bypass && !(context.data.current_user?.permissions & (1 << 5)))
return errorResponse("Bypass directive cannot be used", 403);
return jsonError("Bypass directive cannot be used", 403);
if (typeof bypass !== "boolean")
return errorResponse("Bypass must be a boolean", 400);
return jsonError("Bypass must be a boolean", 400);
if (!Array.isArray(usernames))
return errorResponse("Usernames must be type of array", 400);
return jsonError("Usernames must be type of array", 400);
if (
!["string", "undefined"].includes(typeof description) ||
description?.length > 512
)
return errorResponse("Invalid description", 400);
return jsonError("Invalid description", 400);
if (
!Array.isArray(files) ||
@ -63,7 +55,7 @@ export async function onRequestPost(context: RequestContext) {
return !keys.includes("name") || !keys.includes("size");
})
)
return errorResponse("File list missing name(s) and/or size(s)", 400);
return jsonError("File list missing name(s) and/or size(s)", 400);
if (
files.find(
@ -74,13 +66,10 @@ export async function onRequestPost(context: RequestContext) {
file.size > 536870912,
)
)
return errorResponse(
"One or more files contain an invalid name or size",
400,
);
return jsonError("One or more files contain an invalid name or size", 400);
if (!usernames.length || usernames.length > 20)
return errorResponse(
return jsonError(
"Number of usernames provided must be between 1 and 20",
400,
);
@ -91,7 +80,7 @@ export async function onRequestPost(context: RequestContext) {
username.length > 20 ||
username.match(/_/g)?.length > 1
)
return errorResponse(`Username "${username}" is invalid`, 400);
return jsonError(`Username "${username}" is invalid`, 400);
}
const rbxSearchReq = await fetch(
@ -109,7 +98,7 @@ export async function onRequestPost(context: RequestContext) {
);
if (!rbxSearchReq.ok)
return errorResponse(
return jsonError(
"Failed to locate Roblox users due to upstream error",
500,
);
@ -125,7 +114,7 @@ export async function onRequestPost(context: RequestContext) {
missingUsers.push(userData.requestedUsername);
}
return errorResponse(
return jsonError(
`The following users do not exist or are banned from Roblox: ${missingUsers.toString()}`,
400,
);
@ -165,7 +154,7 @@ export async function onRequestPost(context: RequestContext) {
"webp",
].includes(fileExten.toLowerCase())
)
return errorResponse(
return jsonError(
`File ${file.name} cannot be uploaded as it is unsupported`,
415,
);
@ -202,7 +191,7 @@ export async function onRequestPost(context: RequestContext) {
);
if (uploadUrlResults.find((uploadUrl) => uploadUrl.status === "rejected"))
return errorResponse("Failed to generate upload url", 500);
return jsonError("Failed to generate upload url", 500);
const attachments: string[] = [];
const uploadUrls: string[] = [];
@ -251,12 +240,7 @@ export async function onRequestPost(context: RequestContext) {
.run();
} catch {}
return new Response(
return jsonResponse(
JSON.stringify({ id: reportId, upload_urls: uploadUrls }),
{
headers: {
"content-type": "application/json",
},
},
);
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../common.js";
export async function onRequest(context: RequestContext) {
const { current_user: currentUser } = context.data;
@ -5,12 +7,7 @@ export async function onRequest(context: RequestContext) {
!(currentUser?.permissions & (1 << 5)) &&
!(currentUser?.permissions & (1 << 12))
)
return new Response('{"error":"Forbidden"}', {
headers: {
"content-type": "application/json",
},
status: 403,
});
return jsonError("Forbidden", 403);
return await context.next();
}

View File

@ -1,3 +1,5 @@
import { jsonError } from "../../common.js";
export async function onRequestPost(context: RequestContext) {
const { body } = context.data;
@ -5,23 +7,9 @@ export async function onRequestPost(context: RequestContext) {
!Array.isArray(body) ||
body.find((attachment) => typeof attachment !== "string")
)
return new Response(
'{"error":"Request body must be an array of strings"}',
{
headers: {
"content-type": "application/json",
},
status: 400,
},
);
return jsonError("Request body must be an array of strings", 400);
if (body.length > 3)
return new Response('{"error":"Too many video ids"}', {
headers: {
"content-type": "application/json",
},
status: 400,
});
if (body.length > 3) return jsonError("Too many video ids", 400);
const kvPromises = [];
@ -31,12 +19,7 @@ export async function onRequestPost(context: RequestContext) {
const kvResults = await Promise.allSettled(kvPromises);
if (kvResults.find((result) => result.status === "rejected"))
return new Response('{"error":"Failed to check status of attachments"}', {
headers: {
"content-type": "application/json",
},
status: 500,
});
return jsonError("Failed to check status of attachments", 500);
return new Response(null, {
status: kvResults.find((result) => result !== null) ? 409 : 204,