KV to D1 migration (this is totally gonna break something)
This commit is contained in:
@ -1,17 +1,18 @@
|
||||
import { jsonError } from "../../common.js";
|
||||
import sendEmail from "../../email.js";
|
||||
import { sendPushNotification } from "../../gcloud.js";
|
||||
import validateInactivityNotice from "./validate.js";
|
||||
|
||||
export async function onRequestDelete(context: RequestContext) {
|
||||
const kvResult = await context.env.DATA.get(
|
||||
`inactivity_${context.params.id}`,
|
||||
);
|
||||
const result = await context.env.D1.prepare(
|
||||
"SELECT json_extract(user, '*.id') AS uid FROM inactivity_notices WHERE id = ?;",
|
||||
)
|
||||
.bind(context.params.id)
|
||||
.first();
|
||||
|
||||
if (!kvResult) return jsonError("No inactivity notice with that ID", 404);
|
||||
if (!result) return jsonError("No inactivity notice with that ID", 404);
|
||||
|
||||
if (
|
||||
JSON.parse(kvResult).user.id !== context.data.current_user.id &&
|
||||
result.uid !== context.data.current_user.id &&
|
||||
!(context.data.current_user.permissions & (1 << 0))
|
||||
)
|
||||
return jsonError(
|
||||
@ -19,7 +20,6 @@ export async function onRequestDelete(context: RequestContext) {
|
||||
403,
|
||||
);
|
||||
|
||||
await context.env.DATA.delete(`inactivity_${context.params.id}`);
|
||||
await context.env.D1.prepare("DELETE FROM inactivity_notices WHERE id = ?;")
|
||||
.bind(context.params.id)
|
||||
.run();
|
||||
@ -50,40 +50,61 @@ export async function onRequestPost(context: RequestContext) {
|
||||
return jsonError("You are not a manager of any departments", 403);
|
||||
|
||||
const requestedNotice: { [k: string]: any } | null =
|
||||
await context.env.DATA.get(`inactivity_${context.params.id as string}`, {
|
||||
type: "json",
|
||||
});
|
||||
await context.env.D1.prepare(
|
||||
"SELECT decisions, departments, user FROM inactivity_notices WHERE id = ?;",
|
||||
)
|
||||
.bind(context.params.id)
|
||||
.first();
|
||||
|
||||
if (!requestedNotice)
|
||||
return jsonError("Inactivity notices does not exist", 404);
|
||||
|
||||
const decisions: { [dept: string]: boolean } = {};
|
||||
const decisions: { [dept: string]: boolean } = JSON.parse(
|
||||
requestedNotice.decisions,
|
||||
);
|
||||
|
||||
for (const department of userAdminDepartments)
|
||||
decisions[department] = accepted;
|
||||
|
||||
requestedNotice.decisions = decisions;
|
||||
const applicableDepartments = JSON.parse(requestedNotice.departments).length;
|
||||
|
||||
if (Object.values(decisions).length === requestedNotice.departments.length) {
|
||||
requestedNotice.open = false;
|
||||
await context.env.D1.prepare(
|
||||
"UPDATE inactivity_notices SET decisions = ?, user = json_remove(user, '*.email') WHERE id = ?;",
|
||||
)
|
||||
.bind(JSON.stringify(decisions), context.params.id)
|
||||
.run();
|
||||
|
||||
const approved = !Object.values(decisions).filter((d) => !d).length;
|
||||
|
||||
await context.env.D1.prepare(
|
||||
"UPDATE inactivity_notices SET approved = ?, open = 0 WHERE id = ?;",
|
||||
if (Object.values(decisions).length === applicableDepartments) {
|
||||
const approved =
|
||||
Object.values(decisions).filter((d) => d).length ===
|
||||
applicableDepartments;
|
||||
const denied =
|
||||
Object.values(decisions).filter((d) => !d).length !==
|
||||
applicableDepartments;
|
||||
const fcmTokenResult: FCMTokenResult | null = await context.env.D1.prepare(
|
||||
"SELECT token FROM push_notifications WHERE event_id = ? AND event_type = 'inactivity';",
|
||||
)
|
||||
.bind(Number(approved), context.params.id)
|
||||
.run();
|
||||
.bind(context.params.id)
|
||||
.first();
|
||||
|
||||
if (fcmTokenResult) {
|
||||
let status = "Approved";
|
||||
|
||||
if (denied) status = "Denied";
|
||||
else if (!approved) status = "Partially Approved";
|
||||
|
||||
if (requestedNotice.fcm_token) {
|
||||
await sendPushNotification(
|
||||
context.env,
|
||||
`Inactivity Request ${approved ? "Approved" : "Denied"}`,
|
||||
`Inactivity Request ${status}`,
|
||||
accepted
|
||||
? "Your inactivity request was approved."
|
||||
: "Your inactivity request was denied, please reach out to management if you require more details.",
|
||||
requestedNotice.fcm_token,
|
||||
: `Your inactivity request was ${denied ? "denied" : "partially approved"}, please reach out to management if you require more details.`,
|
||||
fcmTokenResult.token,
|
||||
);
|
||||
|
||||
await context.env.D1.prepare(
|
||||
"DELETE FROM push_notifications WHERE event_id = ? AND event_type = 'inactivity';",
|
||||
).bind(context.params.id);
|
||||
} else {
|
||||
await sendEmail(
|
||||
requestedNotice.user.email,
|
||||
@ -93,96 +114,8 @@ export async function onRequestPost(context: RequestContext) {
|
||||
{ username: requestedNotice.user.username },
|
||||
);
|
||||
}
|
||||
|
||||
delete requestedNotice.fcm_token;
|
||||
delete requestedNotice.user.email;
|
||||
}
|
||||
|
||||
await context.env.DATA.put(
|
||||
`inactivity_${context.params.id as string}`,
|
||||
JSON.stringify(requestedNotice),
|
||||
{ expirationTtl: 63072000 },
|
||||
);
|
||||
|
||||
return new Response(null, {
|
||||
status: 204,
|
||||
});
|
||||
}
|
||||
|
||||
export async function onRequestPut(context: RequestContext) {
|
||||
const kvResult: InactivityNoticeProps | null = await context.env.DATA.get(
|
||||
`inactivity_${context.params.id}`,
|
||||
{ type: "json" },
|
||||
);
|
||||
|
||||
if (!kvResult) return jsonError("No inactivity notice with that ID", 404);
|
||||
|
||||
if (kvResult.user.id !== context.data.current_user.id)
|
||||
return jsonError(
|
||||
"You do not have permission to modify this inactivity notice",
|
||||
403,
|
||||
);
|
||||
|
||||
const d1entry = await context.env.D1.prepare(
|
||||
"SELECT open FROM inactivity_notices WHERE id = ?;",
|
||||
)
|
||||
.bind(context.params.id)
|
||||
.first();
|
||||
|
||||
if (!Boolean(d1entry?.open))
|
||||
return jsonError("Cannot modify a closed inactivity notice", 403);
|
||||
|
||||
const { departments, end, reason, start } = context.data.body;
|
||||
|
||||
const validationFailureResponse = validateInactivityNotice(
|
||||
departments,
|
||||
end,
|
||||
reason,
|
||||
start,
|
||||
context.data.departments,
|
||||
);
|
||||
|
||||
if (validationFailureResponse) return validationFailureResponse;
|
||||
|
||||
kvResult.departments = departments;
|
||||
kvResult.end = end;
|
||||
kvResult.reason = reason;
|
||||
kvResult.start = start;
|
||||
|
||||
await context.env.DATA.put(
|
||||
`inactivity_${context.params.id}`,
|
||||
JSON.stringify(kvResult),
|
||||
{
|
||||
expirationTtl: 63072000,
|
||||
},
|
||||
);
|
||||
|
||||
const departmentWebhooks = [];
|
||||
for (const department of departments)
|
||||
departmentWebhooks.push(context.env[`${department}_INACTIVITY_WEBHOOK`]);
|
||||
|
||||
const webhookPromises = [];
|
||||
for (const webhook of departmentWebhooks)
|
||||
webhookPromises.push(
|
||||
fetch(webhook, {
|
||||
body: JSON.stringify({
|
||||
embeds: [
|
||||
{
|
||||
title: "Inactivity Notice Modified",
|
||||
color: 37562560,
|
||||
description: `View the updated notice at https://carcrushers.cc/mod-queue?id=${context.params.id}&type=inactivity`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
}),
|
||||
);
|
||||
|
||||
await Promise.allSettled(webhookPromises);
|
||||
|
||||
return new Response(null, {
|
||||
status: 204,
|
||||
});
|
||||
|
Reference in New Issue
Block a user