import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'; import { z } from 'zod'; import { env } from '../config/env.js'; import { listServerCommands, restartServerCommand, serverCommandKeys } from '../services/server-command-service.js'; const serverCommandParamSchema = z.object({ key: z.enum(serverCommandKeys), }); function getRequestAccessToken(request: FastifyRequest) { const tokenHeader = request.headers['x-access-token']; return Array.isArray(tokenHeader) ? tokenHeader[0]?.trim() ?? '' : String(tokenHeader ?? '').trim(); } function ensureAuthorized(request: FastifyRequest, reply: FastifyReply) { if (getRequestAccessToken(request) === env.SERVER_COMMAND_ACCESS_TOKEN) { return true; } reply.status(403); void reply.send({ message: '권한 토큰이 필요합니다.', }); return false; } export async function registerServerCommandRoutes(app: FastifyInstance) { app.get('/api/server-commands', async (request, reply) => { if (!ensureAuthorized(request, reply)) { return; } return { ok: true, items: await listServerCommands(), }; }); app.post('/api/server-commands/:key/actions/restart', async (request, reply) => { if (!ensureAuthorized(request, reply)) { return; } const { key } = serverCommandParamSchema.parse(request.params); const result = await restartServerCommand(key); return { ok: true, item: result.server, commandOutput: result.commandOutput, restartState: result.restartState, }; }); }