Add rtbf webhook
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { jsonError } from "../common.js";
|
||||
import { Report } from "../../generated/prisma/client.js";
|
||||
import { getBanList, setBanList } from "../roblox-open-cloud.js";
|
||||
|
||||
export async function onRequestPost(context: RequestContext) {
|
||||
const body = await context.request.text();
|
||||
const secret = context.env.ROBLOX_WEBHOOK_SECRET;
|
||||
|
||||
if (!secret) return jsonError("This endpoint is currently disabled", 503);
|
||||
|
||||
const sigHeader = context.request.headers.get("roblox-signature");
|
||||
|
||||
if (!sigHeader) return jsonError("Missing signature", 401);
|
||||
|
||||
const [timestamp, sig] = sigHeader.split(",");
|
||||
|
||||
if (
|
||||
parseInt(timestamp.replace("t=", "")) <
|
||||
Math.floor(Date.now() / 1000) - 600
|
||||
)
|
||||
return jsonError("This request is stale", 406);
|
||||
|
||||
const textEncode = (text: string) => new TextEncoder().encode(text);
|
||||
const key = await crypto.subtle.importKey(
|
||||
"raw",
|
||||
textEncode(secret),
|
||||
{
|
||||
hash: "SHA-256",
|
||||
name: "HMAC",
|
||||
},
|
||||
false,
|
||||
["verify"],
|
||||
);
|
||||
|
||||
if (
|
||||
!(await crypto.subtle.verify(
|
||||
"HMAC",
|
||||
key,
|
||||
Uint8Array.from(atob(sig.replace("v1=", "")), (c) => c.charCodeAt(0)),
|
||||
textEncode(`${timestamp.replace("t=", "")}.${body}`),
|
||||
))
|
||||
)
|
||||
return jsonError("Invalid signature", 403);
|
||||
|
||||
const data = JSON.parse(body);
|
||||
|
||||
if (data.EventType === "SampleNotification")
|
||||
return new Response(null, {
|
||||
status: 204,
|
||||
});
|
||||
|
||||
if (data.EventType !== "RightToErasureRequest")
|
||||
return jsonError("Invalid event type", 400);
|
||||
|
||||
const { prisma } = context.data;
|
||||
const userId = data.EventPrisma.UserId;
|
||||
|
||||
if (typeof userId !== "number") return jsonError("Invalid user id", 400);
|
||||
|
||||
await prisma.gameModLog.deleteMany({
|
||||
where: {
|
||||
target: userId,
|
||||
},
|
||||
});
|
||||
|
||||
const associatedReports = await prisma.$queryRaw<
|
||||
Report[]
|
||||
>`SELECT attachments, id FROM reports WHERE EXISTS (SELECT 1 FROM json_each(target_ids) WHERE VALUE = ${userId});`;
|
||||
|
||||
const idsToDelete: string[] = [];
|
||||
for (const report of associatedReports) {
|
||||
for (const attachment of report.attachments as string[]) {
|
||||
await context.env.R2.delete(attachment);
|
||||
}
|
||||
idsToDelete.push(report.id);
|
||||
}
|
||||
|
||||
await prisma.report.deleteMany({
|
||||
where: {
|
||||
id: {
|
||||
in: idsToDelete,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { etag, value } = await getBanList(context);
|
||||
|
||||
delete value[userId];
|
||||
|
||||
await setBanList(context, value, etag);
|
||||
|
||||
return new Response(null, {
|
||||
status: 204,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user