"use server"; import { revalidatePath } from "next/cache"; import { requireStaff } from "@/lib/admin/guard"; import { prisma } from "@/lib/prisma"; import { rcon } from "@/lib/services/rcon"; type BanType = "account" | "ip" | "machine" | "super"; const BAN_TYPES: ReadonlySet = new Set(["account", "ip", "machine", "super"]); const PERMANENT_SECONDS = 100 * 365 * 24 * 3600; export async function createBan(formData: FormData): Promise { const staff = await requireStaff(); const userId = Number(formData.get("userId")); const reason = String(formData.get("reason") ?? "").trim().slice(0, 200) || "Banned"; const hours = Number(formData.get("hours")); const type = String(formData.get("type")); if (!(userId > 0) || !BAN_TYPES.has(type)) return; const now = Math.floor(Date.now() / 1000); const banExpire = hours > 0 ? now + Math.floor(hours) * 3600 : now + PERMANENT_SECONDS; const user = await prisma.user.findUnique({ where: { id: userId }, select: { username: true }, }); await prisma.ban.create({ data: { userId, ip: "", machineId: "", userStaffId: staff.id, timestamp: now, banExpire, banReason: reason, type: type as BanType, cfhTopic: -1, }, }); if (user) await rcon.disconnectUser(userId, user.username); revalidatePath("/admin/bans"); } export async function liftBan(formData: FormData): Promise { await requireStaff(); const id = Number(formData.get("id")); if (id > 0) await prisma.ban.delete({ where: { id } }); revalidatePath("/admin/bans"); }