import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/lib/auth"; import { sanitizeFilePath } from "@/lib/security/sanitize"; import { db } from "@/lib/db"; import { auditLogs } from "@/lib/db/schema"; import { nanoid } from "nanoid"; import { getClientIp } from "@/lib/security/rateLimit"; import * as fs from "node:fs"; import * as path from "node:path"; export async function DELETE(req: NextRequest) { const session = await auth.api.getSession({ headers: req.headers }); if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); if (!["superadmin", "admin"].includes(session.user.role ?? "")) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const mcBase = path.resolve(process.env.MC_SERVER_PATH ?? "/opt/minecraft/server"); const { filePath } = await req.json(); let resolvedPath: string; try { resolvedPath = sanitizeFilePath(filePath, mcBase); } catch { return NextResponse.json({ error: "Invalid path" }, { status: 400 }); } if (!fs.existsSync(resolvedPath)) { return NextResponse.json({ error: "File not found" }, { status: 404 }); } const stat = fs.statSync(resolvedPath); if (stat.isDirectory()) { fs.rmSync(resolvedPath, { recursive: true }); } else { fs.unlinkSync(resolvedPath); } const ip = getClientIp(req); await db.insert(auditLogs).values({ id: nanoid(), userId: session.user.id, action: "file.delete", target: "file", targetId: path.relative(mcBase, resolvedPath), details: null, ipAddress: ip, createdAt: Date.now(), }); return NextResponse.json({ success: true }); }