Files
app
components
data
functions
api
admin-apps
appeals
auth
data-transfers
events-team
game-appeals
game-bans
gme
inactivity
infractions
me
mod-queue
reports
[id]
action.ts
complete.ts
recall.ts
submit.ts
short-links
uploads
[[path]].ts
coconut.ts
events.ts
webview-captcha.ts
_middleware.ts
common.ts
email.ts
gcloud.ts
permissions.ts
roblox-open-cloud.ts
upload.ts
public
.gitignore
.node-version
.prettierignore
OFL.txt
README.md
emotion-server.js
index.css
index.d.ts
package-lock.json
package.json
remix.config.js
server.ts
theme.ts
tsconfig.json
car-crushers-portal/functions/api/reports/[id]/action.ts

112 lines
3.0 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 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 } } = {};
const logMap: { [k: string]: number } = {};
const user = JSON.parse(report.user);
for (const [user, action] of Object.entries(actionMap)) {
if (
isNaN(parseInt(user)) ||
typeof action !== "number" ||
action < 0 ||
action > 2
)
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",
};
for (const [k, v] of Object.entries(logMap)) {
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),
),
);
}
await context.env.D1.batch(batchedQueries);
const banList = (await getBanList(context)) as {
[k: string]: { BanType: number };
};
await setBanList(context, Object.assign(banList, newActions));
}
const pushNotificationData: Record<string, string> | null =
await context.env.D1.prepare(
"SELECT token FROM push_notifications WHERE event_id = ? AND event_type = 'report';",
)
.bind(reportId)
.first();
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,
);
delete (report.user as { email?: string; id: string; username: string })
?.email;
await context.env.D1.prepare("UPDATE reports SET open = 0 WHERE id = ?;")
.bind(reportId)
.run();
await context.env.D1.prepare(
"DELETE FROM push_notifications WHERE event_id = ? AND event_type = 'report';",
)
.bind(reportId)
.run();
return new Response(null, {
status: 204,
});
}