Files
car-crushers-portal/functions/api/reports/[id]/action.ts
Regalijan 5457898ff9
All checks were successful
Test, Build, Deploy / Test, Build, and Deploy (push) Successful in 55s
Test, Build, Deploy / Create Sentry Release (push) Successful in 6s
Get almost everything else
2026-04-11 04:49:02 -04:00

139 lines
3.4 KiB
TypeScript

import { getBanList, setBanList } from "../../../roblox-open-cloud.js";
import { jsonError } from "../../../common.js";
import sendEmail from "../../../email.js";
import { sendPushNotification } from "../../../gcloud.js";
export async function onRequestPost(context: RequestContext) {
const { prisma } = context.data;
const reportId = context.params.id as string;
const report: {
[k: string]: any;
} | null = await context.env.D1.prepare("SELECT * FROM reports WHERE id = ?")
.bind(reportId)
.first();
if (!report) return jsonError("Report does not exist", 404);
const actionMap = context.data.body;
const newActions: {
[k: string]: {
BanType: number;
hidden_from_leaderboards?: boolean;
serverconfigurator_blacklist?: boolean;
};
} = {};
const logMap: { [k: string]: number } = {};
const user = JSON.parse(report.user);
for (let [user, action] of Object.entries(actionMap)) {
if (
isNaN(parseInt(user)) ||
typeof action !== "number" ||
action < 0 ||
action > 3
)
return jsonError("Invalid action map", 400);
if (action === 0) continue;
newActions[user] = {
BanType: action,
};
logMap[user] = action;
}
if (Object.values(logMap).length) {
const batchedQueries = [];
const statement = context.env.D1.prepare(
"INSERT INTO game_mod_logs (action, evidence, executed_at, executor, id, target) VALUES (?, ?, ?, ?, ?, ?);",
);
const actionMap: { [k: number]: string } = {
1: "blacklist",
2: "ban",
3: "server config block",
};
for (const [k, v] of Object.entries(logMap)) {
// If ignore action
if (v === 0) continue;
batchedQueries.push(
statement.bind(
actionMap[v],
`https://carcrushers.cc/mod-queue?type=report&id=${context.params.id}`,
Date.now(),
context.data.current_user.id,
crypto.randomUUID(),
parseInt(k),
),
);
// If not a ban action
if (v === 1) {
newActions[k].hidden_from_leaderboards = true;
} else if (v === 3) {
newActions[k].serverconfigurator_blacklist = true;
newActions[k].BanType = 1;
}
}
await context.env.D1.batch(batchedQueries);
const { etag, value: banList } = await getBanList(context);
await setBanList(context, Object.assign(banList, newActions), etag);
}
const pushNotificationData = await prisma.pushNotification.findUnique({
select: {
token: true,
},
where: {
event_id: reportId,
event_type: "report",
},
});
if (user?.email)
await sendEmail(
user.email,
context.env.MAILGUN_API_KEY,
"Report Processed",
"report_processed",
{
username: user.username as string,
},
);
else if (pushNotificationData) {
await sendPushNotification(
context.env,
"Report Processed",
`Your report for ${JSON.parse(report.target_usernames).toString()} has been reviewed.`,
pushNotificationData.token,
);
await prisma.pushNotification.delete({
where: {
event_id: reportId,
event_type: "report",
},
});
}
delete (report.user as { email?: string; id: string; username: string })
?.email;
await prisma.report.update({
data: {
open: false,
user: report.user,
},
where: {
id: reportId,
},
});
return new Response(null, {
status: 204,
});
}