import { NextRequest, NextResponse } from "next/server"; import { execSync } from "child_process"; import { auth } from "@/lib/auth"; export const dynamic = "force-dynamic"; const SCRIPT = "/home/minecraft/dashboard/scripts/scheduled-restart.sh"; const CRON_MARKER = "# mc-scheduled-restart"; function getCurrentSchedule(): { enabled: boolean; hour: number; minute: number } | null { try { const crontab = execSync("crontab -l 2>/dev/null", { encoding: "utf8" }); const match = crontab.match( new RegExp(`^(\\d+)\\s+(\\d+)\\s+\\*\\s+\\*\\s+\\*\\s+.*${CRON_MARKER.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`, "m") ); if (match) { return { enabled: true, minute: parseInt(match[1]), hour: parseInt(match[2]) }; } } catch {} return null; } export async function GET() { const session = await auth(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); } const schedule = getCurrentSchedule(); return NextResponse.json(schedule || { enabled: false, hour: 4, minute: 0 }); } export async function POST(req: NextRequest) { const session = await auth(); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); } const { enabled, hour, minute } = await req.json(); try { // Get existing crontab without our entry let crontab = ""; try { crontab = execSync("crontab -l 2>/dev/null", { encoding: "utf8" }); } catch {} // Remove old entry const lines = crontab.split("\n").filter((l) => !l.includes(CRON_MARKER)); if (enabled) { const h = Math.min(Math.max(parseInt(hour) || 4, 0), 23); const m = Math.min(Math.max(parseInt(minute) || 0, 0), 59); lines.push(`${m} ${h} * * * bash ${SCRIPT} ${CRON_MARKER}`); } const newCrontab = lines.filter(Boolean).join("\n") + "\n"; const { writeFileSync, unlinkSync } = require("fs"); const tmpFile = `/tmp/crontab-${Date.now()}.tmp`; writeFileSync(tmpFile, newCrontab, { mode: 0o600 }); execSync(`crontab ${tmpFile}`, { encoding: "utf8" }); unlinkSync(tmpFile); return NextResponse.json({ ok: true, enabled, hour: parseInt(hour) || 4, minute: parseInt(minute) || 0, }); } catch (e) { return NextResponse.json( { error: (e as Error).message }, { status: 500 } ); } }