2025-01-25 00:58:27 -05:00

151 lines
4.5 KiB
TypeScript

import { jsonError, jsonResponse } from "../../common.js";
import sendEmail from "../../email.js";
import { sendPushNotification } from "../../gcloud.js";
export async function onRequestDelete(context: RequestContext) {
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 (!result) return jsonError("No inactivity notice with that ID", 404);
if (
result.uid !== context.data.current_user.id &&
!(context.data.current_user.permissions & (1 << 0))
)
return jsonError(
"You do not have permission to delete this inactivity notice",
403,
);
await context.env.D1.prepare("DELETE FROM inactivity_notices WHERE id = ?;")
.bind(context.params.id)
.run();
return new Response(null, {
status: 204,
});
}
export async function onRequestGet(context: RequestContext) {
const { current_user: currentUser } = context.data;
if (
![1 << 0, 1 << 2, 1 << 3, 1 << 9, 1 << 10].find(
(p) => currentUser.permissions & p,
)
)
return jsonError("Forbidden", 403);
const result: Record<
string,
string | number | { [k: string]: string }
> | null = await context.env.D1.prepare(
"SELECT * FROM inactivity_notices WHERE id = ?;",
)
.bind(context.params.id)
.first();
if (!result) return jsonError("Inactivity notice does not exist", 404);
result.decisions = JSON.parse(result.decisions as string);
result.departments = JSON.parse(result.departments as string);
result.user = JSON.parse(result.user as string);
return jsonResponse(JSON.stringify(result));
}
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.keys(adminDepartments).filter(
(dept) => context.data.current_user.permissions & adminDepartments[dept],
);
if (!userAdminDepartments.length)
return jsonError("You are not a manager of any departments", 403);
const requestedNotice: { [k: string]: any } | null =
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 } = JSON.parse(
requestedNotice.decisions,
);
for (const department of userAdminDepartments)
decisions[department] = accepted;
const applicableDepartments = JSON.parse(requestedNotice.departments).length;
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();
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(context.params.id)
.first();
if (fcmTokenResult) {
let status = "Approved";
if (denied) status = "Denied";
else if (!approved) status = "Partially Approved";
await sendPushNotification(
context.env,
`Inactivity Request ${status}`,
accepted
? "Your inactivity request was approved."
: `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,
context.env.MAILGUN_API_KEY,
`Inactivity Request ${approved ? "Approved" : "Denied"}`,
`inactivity_${approved ? "approved" : "denied"}`,
{ username: requestedNotice.user.username },
);
}
}
return new Response(null, {
status: 204,
});
}