export async function onRequestPost(context: RequestContext) { const { learned, whyBanned, whyUnban } = context.data.body; if ( typeof learned !== "string" || typeof whyBanned !== "string" || typeof whyUnban !== "string" || !learned.length || learned.length > 2000 || !whyBanned.length || whyBanned.length > 500 || !whyUnban.length || whyUnban.length > 2000 ) return new Response( '{"error":"One or more fields are missing or invalid"}', { headers: { "content-type": "application/json", }, status: 400, }, ); const { current_user: currentUser } = context.data; if (!currentUser.email) return new Response('{"error":"No email for this session"}', { headers: { "content-type": "application/json", }, status: 403, }); const existingAppeals = await context.env.DATA.list({ prefix: `appeal_${currentUser.id}`, }); const existingBlockedAppeal = await context.env.DATA.get( `blockedappeal_${currentUser.id}`, ); if ( existingBlockedAppeal || existingAppeals.keys.find( (appeal) => (appeal.metadata as { [k: string]: any })?.open, ) ) return new Response('{"error":"Appeal already submitted"}', { headers: { "content-type": "application/json", }, status: 403, }); if (await context.env.DATA.get(`appealban_${currentUser.id}`)) { await context.env.DATA.put(`blockedappeal_${currentUser.id}`, "1", { metadata: { email: currentUser.email }, }); return new Response(null, { status: 204, }); } const appealId = `${currentUser.id}${Date.now()}${crypto .randomUUID() .replaceAll("-", "")}`; await context.env.DATA.put( `appeal_${appealId}`, JSON.stringify({ ban_reason: whyBanned, createdAt: Date.now(), learned, id: appealId, reason_for_unban: whyUnban, user: { email: currentUser.email, id: currentUser.id, username: currentUser.username, }, }), { expirationTtl: 94608000, }, ); await context.env.D1.prepare( "INSERT INTO appeals (created_at, id, open, user) VALUES (?, ?, ?, ?)", ) .bind(Date.now(), appealId, 1, currentUser.id) .run(); await fetch(context.env.APPEALS_WEBHOOK, { body: JSON.stringify({ embeds: [ { title: "Appeal Submitted", color: 3756250, description: `View this appeal at https://carcrushers.cc/mod-queue?id=${appealId}&type=appeal`, fields: [ { name: "Submitter", value: `${currentUser.username} (${currentUser.id})`, }, ], }, ], }), headers: { "content-type": "application/json", }, method: "POST", }); return new Response(null, { status: 204, }); }