import { jsonError } from "../../../common.js"; export async function onRequestDelete(context: RequestContext) { const eventId = context.params.id as string; const eventData: | ({ [k: string]: number; } & { created_by: string }) | null = await context.env.D1.prepare( "SELECT created_by, day, month, performed_at, year FROM events WHERE id = ?;", ) .bind(eventId) .first(); if (!eventData) return jsonError("No event exists with that ID", 404); const { current_user: currentUser } = context.data; const isETM = [1 << 4, 1 << 12].find((int) => currentUser.permissions & int); if (eventData.created_by !== currentUser.id && !isETM) return jsonError("You are not authorized to delete that event", 403); const now = new Date(); now.setUTCHours(0, 0, 0, 0); const eventDate = new Date( eventData.year, eventData.month - 1, eventData.day, ); if (!isETM && now.getTime() >= eventDate.getTime()) return jsonError( "Event cannot be deleted on or after the scheduled date", 403, ); if (typeof eventData.performed_at === "number") return jsonError( "Event cannot be deleted because it has already been marked as completed or forgotten", 400, ); await context.env.D1.prepare("DELETE FROM events WHERE id = ?;") .bind(eventId) .run(); return new Response(null, { status: 204, }); } export async function onRequestPatch(context: RequestContext) { const eventId = context.params.id as string; const { body } = context.data; const eventData: | ({ [k: string]: number } & { created_by: string; type: string }) | null = await context.env.D1.prepare( "SELECT created_by, day, month, type, year FROM events WHERE id = ?;", ) .bind(eventId) .first(); if (!eventData) return jsonError("No event exists with that ID", 404); const { current_user: currentUser } = context.data; if ( eventData.created_by !== currentUser.id && ![1 << 4, 1 << 12].find((int) => currentUser.permissions & int) ) return jsonError("You are not authorized to modify this event", 403); const date = new Date(); const currentDay = date.getUTCDate(); date.setUTCDate(0); if ( typeof body.day !== "number" || body.day > date.getUTCDate() || body.day < 1 || // Check for non-integers Math.floor(body.day) !== body.day || currentDay >= body.day ) return jsonError("Invalid day", 400); if ( date.getUTCFullYear() !== eventData.year || date.getUTCMonth() !== eventData.month ) return jsonError( "Only events in the current month period can be rescheduled", 400, ); if (eventData.type === "rotw") { const weekRanges: { [k: number]: number } = { 0: 7, 1: 14, 2: 21, 3: 28, 4: 35, }; const weekRange = Math.floor(body.day / 7); const matchingROTW = await context.env.D1.prepare( "SELECT id FROM events WHERE (approved = 1 OR pending = 1) AND day BETWEEN ? AND ? AND month = ? AND type = 'rotw' AND year = ?;", ) .bind( weekRanges[weekRange] - 7, weekRanges[weekRange], eventData.month, eventData.year, ) .first(); if (matchingROTW) return jsonError("There is already an ROTW scheduled for that week", 400); } else { const matchingEvent = await context.env.D1.prepare( "SELECT id FROM events WHERE (approved = 1 OR pending = 1) AND day = ? AND month = ? AND type = ? AND year = ?;", ) .bind(body.day, eventData.month, eventData.type, eventData.year) .first(); if (matchingEvent) return jsonError( "There is already an event of that type scheduled for that day", 400, ); } await context.env.D1.prepare("UPDATE events SET day = ? WHERE id = ?;") .bind(body.day, eventId) .run(); await fetch(context.env.EVENTS_WEBHOOK, { body: JSON.stringify({ embeds: [ { title: "Event Rescheduled", color: 3756250, description: `${context.data.current_user.username} rescheduled their event for ${eventData.year}-${eventData.month.toString().padStart(2, "0")}-${eventData.day.toString().padStart(2, "0")} to ${eventData.year}-${eventData.month.toString().padStart(2, "0")}-${body.day}`, }, ], }), headers: { "content-type": "application/json", }, method: "POST", }); return new Response(null, { status: 204, }); } export async function onRequestPost(context: RequestContext) { const eventId = context.params.id as string; const eventData = await context.env.D1.prepare( "SELECT approved, performed_at FROM events WHERE id = ?;", ) .bind(eventId) .first(); if (!eventData) return jsonError("No event exists with that ID", 404); if (!eventData.approved) return jsonError("Cannot perform unapproved event", 403); await context.env.D1.prepare( "UPDATE events SET performed_at = ? WHERE id = ?;", ) .bind(Date.now(), eventId) .run(); return new Response(null, { status: 204, }); }