mirror of
https://github.com/rmoren97/mc-manager.git
synced 2026-02-10 17:40:30 -08:00
91 lines
2.9 KiB
TypeScript
91 lines
2.9 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { validateSession, hasPermission } from '@/lib/auth'
|
|
import connectToDatabase from '@/lib/mongodb'
|
|
import { Server } from '@/lib/models'
|
|
import { isValidObjectId } from '@/lib/input-validation'
|
|
import { createAuditLog, getClientIP } from '@/lib/audit'
|
|
import { getContainerByName } from '@/lib/docker'
|
|
|
|
export async function POST(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ id: string }> }
|
|
) {
|
|
const clientIP = getClientIP(request)
|
|
|
|
try {
|
|
const session = await validateSession(request)
|
|
if (!session) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
if (!hasPermission(session, 'servers:restart')) {
|
|
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
|
}
|
|
|
|
const { id } = await params
|
|
if (!isValidObjectId(id)) {
|
|
return NextResponse.json({ error: 'Invalid server ID' }, { status: 400 })
|
|
}
|
|
|
|
await connectToDatabase()
|
|
const server = await Server.findById(id)
|
|
|
|
if (!server) {
|
|
return NextResponse.json({ error: 'Server not found' }, { status: 404 })
|
|
}
|
|
|
|
// If the server is currently offline, check for port conflicts before restarting
|
|
if (server.status !== 'online' && server.status !== 'starting') {
|
|
const portConflict = await Server.findOne({
|
|
_id: { $ne: server._id },
|
|
port: server.port,
|
|
status: { $in: ['online', 'starting'] },
|
|
})
|
|
if (portConflict) {
|
|
return NextResponse.json(
|
|
{ error: `Port ${server.port} is already in use by "${portConflict.name}"` },
|
|
{ status: 409 }
|
|
)
|
|
}
|
|
}
|
|
|
|
const container = await getContainerByName(`mc-${server._id}`)
|
|
if (!container) {
|
|
return NextResponse.json({ error: 'Docker container not found' }, { status: 500 })
|
|
}
|
|
|
|
await Server.findByIdAndUpdate(id, { status: 'stopping' })
|
|
await container.restart({ t: 30 })
|
|
await Server.findByIdAndUpdate(id, { status: 'starting' })
|
|
|
|
// Poll for running state
|
|
setTimeout(async () => {
|
|
try {
|
|
const inspect = await container.inspect()
|
|
const status = inspect.State?.Running ? 'online' : 'offline'
|
|
await Server.findByIdAndUpdate(id, { status })
|
|
} catch {
|
|
await Server.findByIdAndUpdate(id, { status: 'crashed' })
|
|
}
|
|
}, 15000)
|
|
|
|
await createAuditLog({
|
|
action: 'server_restarted',
|
|
entityType: 'server',
|
|
entityId: server._id.toString(),
|
|
entityName: server.name,
|
|
userId: session._id,
|
|
userName: session.username,
|
|
userEmail: session.email,
|
|
clientIP,
|
|
status: 'success',
|
|
statusCode: 200,
|
|
})
|
|
|
|
return NextResponse.json({ success: true, message: 'Server restarting' })
|
|
} catch (error) {
|
|
console.error('Restart server error:', error)
|
|
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
|
|
}
|
|
}
|