import { getBanList } from "../../roblox-open-cloud.js"; export default async function ( context: RequestContext, user: number, ): Promise<{ can_appeal?: boolean; error?: string; reason?: string; types?: string[]; }> { if ( await context.data.prisma.gameAppeal.findFirst({ select: { id: true, }, where: { roblox_id: user, }, }) ) return { can_appeal: false, reason: "You have already submitted an appeal", }; let banList; try { banList = (await getBanList(context)).value; } catch { return { error: "Failed to check your ban status", }; } if (!banList[user]?.BanType) return { can_appeal: false, reason: "You do not appear to be banned", }; const appealBlock = await context.env.DATA.get(`gameappealblock_${user}`); if (appealBlock) return { can_appeal: false, reason: `You must wait until ${new Date( parseInt(appealBlock), ).toLocaleString()} to submit another appeal`, }; const userLogs = await context.data.prisma.gameModLog.findMany({ select: { action: true, executed_at: true, }, where: { target: user, }, }); // Legacy bans if (!userLogs.length) return { can_appeal: true, reason: "", types: ["ban"] }; const allowedTime = new Date(userLogs[0].executed_at).getTime() + 2592000000; if (Date.now() < allowedTime) return { can_appeal: false, reason: `You must wait until ${new Date( allowedTime, ).toLocaleString()} to submit an appeal`, }; if (userLogs.find((r) => r.action.startsWith("accept appeal"))) return { can_appeal: false, reason: "We do not accept appeals from repeat offenders", }; const types: string[] = []; if (banList[user].BanType) types.push("ban"); if (banList[user].hidden_from_leaderboards) types.push("leaderboard"); if (banList[user].serverconfigurator_blacklist) types.push("server_configurator"); return { can_appeal: true, reason: "", types }; }