@minecraft-docker/mcctl-api 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +5 -0
- package/dist/app.js.map +1 -1
- package/dist/routes/audit-logs.d.ts +10 -0
- package/dist/routes/audit-logs.d.ts.map +1 -0
- package/dist/routes/audit-logs.js +188 -0
- package/dist/routes/audit-logs.js.map +1 -0
- package/dist/routes/servers/config.d.ts +10 -0
- package/dist/routes/servers/config.d.ts.map +1 -0
- package/dist/routes/servers/config.js +208 -0
- package/dist/routes/servers/config.js.map +1 -0
- package/dist/schemas/audit-log.d.ts +180 -0
- package/dist/schemas/audit-log.d.ts.map +1 -0
- package/dist/schemas/audit-log.js +152 -0
- package/dist/schemas/audit-log.js.map +1 -0
- package/dist/schemas/config.d.ts +88 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +78 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/services/ConfigService.d.ts +38 -0
- package/dist/services/ConfigService.d.ts.map +1 -0
- package/dist/services/ConfigService.js +247 -0
- package/dist/services/ConfigService.js.map +1 -0
- package/dist/services/audit-log-service.d.ts +41 -0
- package/dist/services/audit-log-service.d.ts.map +1 -0
- package/dist/services/audit-log-service.js +259 -0
- package/dist/services/audit-log-service.js.map +1 -0
- package/package.json +2 -2
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAiBnD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoFtF;AAED,eAAe,QAAQ,CAAC"}
|
package/dist/app.js
CHANGED
|
@@ -6,12 +6,14 @@ import authPlugin from './plugins/auth.js';
|
|
|
6
6
|
import swaggerPlugin from './plugins/swagger.js';
|
|
7
7
|
import serversRoutes from './routes/servers.js';
|
|
8
8
|
import serverActionsRoutes from './routes/servers/actions.js';
|
|
9
|
+
import serverConfigRoutes from './routes/servers/config.js';
|
|
9
10
|
import consoleRoutes from './routes/console.js';
|
|
10
11
|
import worldsRoutes from './routes/worlds.js';
|
|
11
12
|
import authRoutes from './routes/auth.js';
|
|
12
13
|
import routerRoutes from './routes/router.js';
|
|
13
14
|
import playersRoutes from './routes/players.js';
|
|
14
15
|
import backupRoutes from './routes/backup.js';
|
|
16
|
+
import auditLogsRoutes from './routes/audit-logs.js';
|
|
15
17
|
export async function buildApp(options = {}) {
|
|
16
18
|
const app = Fastify({
|
|
17
19
|
logger: options.logger ?? config.nodeEnv !== 'test' ? {
|
|
@@ -44,6 +46,7 @@ export async function buildApp(options = {}) {
|
|
|
44
46
|
// Register server routes
|
|
45
47
|
await app.register(serversRoutes);
|
|
46
48
|
await app.register(serverActionsRoutes);
|
|
49
|
+
await app.register(serverConfigRoutes);
|
|
47
50
|
// Register router routes
|
|
48
51
|
await app.register(routerRoutes);
|
|
49
52
|
// Register player routes
|
|
@@ -52,6 +55,8 @@ export async function buildApp(options = {}) {
|
|
|
52
55
|
await app.register(backupRoutes);
|
|
53
56
|
// Register world routes
|
|
54
57
|
await app.register(worldsRoutes);
|
|
58
|
+
// Register audit log routes
|
|
59
|
+
await app.register(auditLogsRoutes);
|
|
55
60
|
// Health check endpoint
|
|
56
61
|
app.get('/health', async () => {
|
|
57
62
|
return {
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,OAA4B,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,eAAe,CAAC;AACjC,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,mBAAmB,MAAM,6BAA6B,CAAC;AAC9D,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,YAAY,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Audit log routes plugin
|
|
4
|
+
* Provides REST API for audit log management
|
|
5
|
+
*/
|
|
6
|
+
declare const auditLogsPlugin: FastifyPluginAsync;
|
|
7
|
+
declare const _default: FastifyPluginAsync;
|
|
8
|
+
export default _default;
|
|
9
|
+
export { auditLogsPlugin };
|
|
10
|
+
//# sourceMappingURL=audit-logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logs.d.ts","sourceRoot":"","sources":["../../src/routes/audit-logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,kBAAkB,EAAgC,MAAM,SAAS,CAAC;AAqC5F;;;GAGG;AACH,QAAA,MAAM,eAAe,EAAE,kBAyLtB,CAAC;;AAEF,wBAGG;AAEH,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import fp from 'fastify-plugin';
|
|
2
|
+
import { AuditLogListQuerySchema, AuditLogIdParamsSchema, AuditLogPurgeRequestSchema, AuditLogListResponseSchema, AuditLogStatsResponseSchema, AuditLogDetailResponseSchema, AuditLogPurgeResponseSchema, ErrorResponseSchema, } from '../schemas/audit-log.js';
|
|
3
|
+
import { getAuditLogs, getAuditLogStats, getAuditLogById, purgeAuditLogs, subscribeAuditLogs, } from '../services/audit-log-service.js';
|
|
4
|
+
/**
|
|
5
|
+
* Audit log routes plugin
|
|
6
|
+
* Provides REST API for audit log management
|
|
7
|
+
*/
|
|
8
|
+
const auditLogsPlugin = async (fastify) => {
|
|
9
|
+
/**
|
|
10
|
+
* GET /api/audit-logs
|
|
11
|
+
* List audit logs with filtering and pagination
|
|
12
|
+
*/
|
|
13
|
+
fastify.get('/api/audit-logs', {
|
|
14
|
+
schema: {
|
|
15
|
+
description: 'List audit logs with filtering and pagination',
|
|
16
|
+
tags: ['audit-logs'],
|
|
17
|
+
querystring: AuditLogListQuerySchema,
|
|
18
|
+
response: {
|
|
19
|
+
200: AuditLogListResponseSchema,
|
|
20
|
+
500: ErrorResponseSchema,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
}, async (request, reply) => {
|
|
24
|
+
try {
|
|
25
|
+
const data = await getAuditLogs(request.query);
|
|
26
|
+
return reply.send(data);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
fastify.log.error(error, 'Failed to list audit logs');
|
|
30
|
+
return reply.code(500).send({
|
|
31
|
+
error: 'InternalServerError',
|
|
32
|
+
message: 'Failed to list audit logs',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* GET /api/audit-logs/stats
|
|
38
|
+
* Get audit log statistics
|
|
39
|
+
*/
|
|
40
|
+
fastify.get('/api/audit-logs/stats', {
|
|
41
|
+
schema: {
|
|
42
|
+
description: 'Get audit log statistics',
|
|
43
|
+
tags: ['audit-logs'],
|
|
44
|
+
response: {
|
|
45
|
+
200: AuditLogStatsResponseSchema,
|
|
46
|
+
500: ErrorResponseSchema,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
}, async (_request, reply) => {
|
|
50
|
+
try {
|
|
51
|
+
const data = await getAuditLogStats();
|
|
52
|
+
return reply.send(data);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
fastify.log.error(error, 'Failed to get audit log stats');
|
|
56
|
+
return reply.code(500).send({
|
|
57
|
+
error: 'InternalServerError',
|
|
58
|
+
message: 'Failed to get audit log statistics',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* GET /api/audit-logs/stream
|
|
64
|
+
* Server-Sent Events stream for real-time audit log updates
|
|
65
|
+
*/
|
|
66
|
+
fastify.get('/api/audit-logs/stream', {
|
|
67
|
+
schema: {
|
|
68
|
+
description: 'Real-time audit log stream (SSE)',
|
|
69
|
+
tags: ['audit-logs'],
|
|
70
|
+
response: {
|
|
71
|
+
200: { type: 'string', description: 'SSE event stream' },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
}, async (request, reply) => {
|
|
75
|
+
// Set SSE headers
|
|
76
|
+
reply.raw.writeHead(200, {
|
|
77
|
+
'Content-Type': 'text/event-stream',
|
|
78
|
+
'Cache-Control': 'no-cache',
|
|
79
|
+
'Connection': 'keep-alive',
|
|
80
|
+
'Access-Control-Allow-Origin': '*',
|
|
81
|
+
});
|
|
82
|
+
// Send initial connected event
|
|
83
|
+
reply.raw.write(`event: connected\ndata: ${JSON.stringify({ timestamp: new Date().toISOString() })}\n\n`);
|
|
84
|
+
// Subscribe to new audit log events
|
|
85
|
+
const unsubscribe = subscribeAuditLogs((log) => {
|
|
86
|
+
reply.raw.write(`event: audit-log\ndata: ${JSON.stringify(log)}\n\n`);
|
|
87
|
+
});
|
|
88
|
+
// Heartbeat to keep connection alive (every 30 seconds)
|
|
89
|
+
const heartbeat = setInterval(() => {
|
|
90
|
+
reply.raw.write(`event: heartbeat\ndata: ${JSON.stringify({ timestamp: new Date().toISOString() })}\n\n`);
|
|
91
|
+
}, 30000);
|
|
92
|
+
// Cleanup on client disconnect
|
|
93
|
+
request.raw.on('close', () => {
|
|
94
|
+
clearInterval(heartbeat);
|
|
95
|
+
unsubscribe();
|
|
96
|
+
reply.raw.end();
|
|
97
|
+
});
|
|
98
|
+
// Don't return - keep connection open for SSE
|
|
99
|
+
return;
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* GET /api/audit-logs/:id
|
|
103
|
+
* Get single audit log entry with related logs
|
|
104
|
+
*/
|
|
105
|
+
fastify.get('/api/audit-logs/:id', {
|
|
106
|
+
schema: {
|
|
107
|
+
description: 'Get single audit log entry with related logs',
|
|
108
|
+
tags: ['audit-logs'],
|
|
109
|
+
params: AuditLogIdParamsSchema,
|
|
110
|
+
response: {
|
|
111
|
+
200: AuditLogDetailResponseSchema,
|
|
112
|
+
404: ErrorResponseSchema,
|
|
113
|
+
500: ErrorResponseSchema,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
}, async (request, reply) => {
|
|
117
|
+
const { id } = request.params;
|
|
118
|
+
try {
|
|
119
|
+
const data = await getAuditLogById(id);
|
|
120
|
+
if (!data) {
|
|
121
|
+
return reply.code(404).send({
|
|
122
|
+
error: 'NotFound',
|
|
123
|
+
message: `Audit log entry '${id}' not found`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return reply.send(data);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
fastify.log.error(error, 'Failed to get audit log detail');
|
|
130
|
+
return reply.code(500).send({
|
|
131
|
+
error: 'InternalServerError',
|
|
132
|
+
message: 'Failed to get audit log detail',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* DELETE /api/audit-logs
|
|
138
|
+
* Purge old audit log entries (admin only)
|
|
139
|
+
*/
|
|
140
|
+
fastify.delete('/api/audit-logs', {
|
|
141
|
+
schema: {
|
|
142
|
+
description: 'Purge old audit log entries (admin only)',
|
|
143
|
+
tags: ['audit-logs'],
|
|
144
|
+
body: AuditLogPurgeRequestSchema,
|
|
145
|
+
response: {
|
|
146
|
+
200: AuditLogPurgeResponseSchema,
|
|
147
|
+
400: ErrorResponseSchema,
|
|
148
|
+
403: ErrorResponseSchema,
|
|
149
|
+
500: ErrorResponseSchema,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
}, async (request, reply) => {
|
|
153
|
+
try {
|
|
154
|
+
// Check admin role from headers (set by BFF or API key auth)
|
|
155
|
+
const role = request.headers['x-role'];
|
|
156
|
+
if (role && role !== 'admin') {
|
|
157
|
+
return reply.code(403).send({
|
|
158
|
+
error: 'Forbidden',
|
|
159
|
+
message: 'Admin access required for audit log purge',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const { before, dryRun = false } = request.body;
|
|
163
|
+
// Validate date
|
|
164
|
+
const beforeDate = new Date(before);
|
|
165
|
+
if (isNaN(beforeDate.getTime())) {
|
|
166
|
+
return reply.code(400).send({
|
|
167
|
+
error: 'BadRequest',
|
|
168
|
+
message: 'Invalid date format for "before" parameter',
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const data = await purgeAuditLogs(before, dryRun);
|
|
172
|
+
return reply.send(data);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
fastify.log.error(error, 'Failed to purge audit logs');
|
|
176
|
+
return reply.code(500).send({
|
|
177
|
+
error: 'InternalServerError',
|
|
178
|
+
message: 'Failed to purge audit logs',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
export default fp(auditLogsPlugin, {
|
|
184
|
+
name: 'audit-logs-routes',
|
|
185
|
+
fastify: '5.x',
|
|
186
|
+
});
|
|
187
|
+
export { auditLogsPlugin };
|
|
188
|
+
//# sourceMappingURL=audit-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-logs.js","sourceRoot":"","sources":["../../src/routes/audit-logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Server configuration routes plugin
|
|
4
|
+
* Provides REST API for server configuration management
|
|
5
|
+
*/
|
|
6
|
+
declare const configPlugin: FastifyPluginAsync;
|
|
7
|
+
declare const _default: FastifyPluginAsync;
|
|
8
|
+
export default _default;
|
|
9
|
+
export { configPlugin };
|
|
10
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/routes/servers/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,kBAAkB,EAAgC,MAAM,SAAS,CAAC;AAqC5F;;;GAGG;AACH,QAAA,MAAM,YAAY,EAAE,kBA0MnB,CAAC;;AAMF,wBAGG;AAEH,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import fp from 'fastify-plugin';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { existsSync, readdirSync, rmSync } from 'fs';
|
|
4
|
+
import { serverExists, getContainerStatus } from '@minecraft-docker/shared';
|
|
5
|
+
import { ServerConfigResponseSchema, UpdateServerConfigRequestSchema, UpdateServerConfigResponseSchema, WorldResetResponseSchema, } from '../../schemas/config.js';
|
|
6
|
+
import { ErrorResponseSchema, ServerNameParamsSchema } from '../../schemas/server.js';
|
|
7
|
+
import { config } from '../../config/index.js';
|
|
8
|
+
import { createConfigService } from '../../services/ConfigService.js';
|
|
9
|
+
// ============================================================
|
|
10
|
+
// Plugin Definition
|
|
11
|
+
// ============================================================
|
|
12
|
+
/**
|
|
13
|
+
* Server configuration routes plugin
|
|
14
|
+
* Provides REST API for server configuration management
|
|
15
|
+
*/
|
|
16
|
+
const configPlugin = async (fastify) => {
|
|
17
|
+
const configService = createConfigService(config.platformPath);
|
|
18
|
+
/**
|
|
19
|
+
* GET /api/servers/:name/config
|
|
20
|
+
* Get server configuration
|
|
21
|
+
*/
|
|
22
|
+
fastify.get('/api/servers/:name/config', {
|
|
23
|
+
schema: {
|
|
24
|
+
description: 'Get server configuration from config.env',
|
|
25
|
+
tags: ['servers', 'config'],
|
|
26
|
+
params: ServerNameParamsSchema,
|
|
27
|
+
response: {
|
|
28
|
+
200: ServerConfigResponseSchema,
|
|
29
|
+
404: ErrorResponseSchema,
|
|
30
|
+
500: ErrorResponseSchema,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}, async (request, reply) => {
|
|
34
|
+
const { name } = request.params;
|
|
35
|
+
try {
|
|
36
|
+
// Check if server exists
|
|
37
|
+
if (!serverExists(name)) {
|
|
38
|
+
return reply.code(404).send({
|
|
39
|
+
error: 'NotFound',
|
|
40
|
+
message: `Server '${name}' not found`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Check if config exists
|
|
44
|
+
if (!configService.configExists(name)) {
|
|
45
|
+
return reply.code(404).send({
|
|
46
|
+
error: 'NotFound',
|
|
47
|
+
message: `Configuration for server '${name}' not found`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const serverConfig = configService.getConfig(name);
|
|
51
|
+
return reply.send({
|
|
52
|
+
config: serverConfig,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
fastify.log.error(error, 'Failed to get server configuration');
|
|
57
|
+
return reply.code(500).send({
|
|
58
|
+
error: 'InternalServerError',
|
|
59
|
+
message: 'Failed to get server configuration',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* PATCH /api/servers/:name/config
|
|
65
|
+
* Update server configuration
|
|
66
|
+
*/
|
|
67
|
+
fastify.patch('/api/servers/:name/config', {
|
|
68
|
+
schema: {
|
|
69
|
+
description: 'Update server configuration in config.env',
|
|
70
|
+
tags: ['servers', 'config'],
|
|
71
|
+
params: ServerNameParamsSchema,
|
|
72
|
+
body: UpdateServerConfigRequestSchema,
|
|
73
|
+
response: {
|
|
74
|
+
200: UpdateServerConfigResponseSchema,
|
|
75
|
+
404: ErrorResponseSchema,
|
|
76
|
+
500: ErrorResponseSchema,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
}, async (request, reply) => {
|
|
80
|
+
const { name } = request.params;
|
|
81
|
+
const updates = request.body;
|
|
82
|
+
try {
|
|
83
|
+
// Check if server exists
|
|
84
|
+
if (!serverExists(name)) {
|
|
85
|
+
return reply.code(404).send({
|
|
86
|
+
error: 'NotFound',
|
|
87
|
+
message: `Server '${name}' not found`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// Check if config exists
|
|
91
|
+
if (!configService.configExists(name)) {
|
|
92
|
+
return reply.code(404).send({
|
|
93
|
+
error: 'NotFound',
|
|
94
|
+
message: `Configuration for server '${name}' not found`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const result = configService.updateConfig(name, updates);
|
|
98
|
+
fastify.log.info({
|
|
99
|
+
server: name,
|
|
100
|
+
changedFields: result.changedFields,
|
|
101
|
+
restartRequired: result.restartRequired,
|
|
102
|
+
}, 'Server configuration updated');
|
|
103
|
+
return reply.send({
|
|
104
|
+
success: true,
|
|
105
|
+
config: result.config,
|
|
106
|
+
restartRequired: result.restartRequired,
|
|
107
|
+
changedFields: result.changedFields,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
fastify.log.error(error, 'Failed to update server configuration');
|
|
112
|
+
return reply.code(500).send({
|
|
113
|
+
error: 'InternalServerError',
|
|
114
|
+
message: 'Failed to update server configuration',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* POST /api/servers/:name/world/reset
|
|
120
|
+
* Reset server world data
|
|
121
|
+
* Precondition: Server must be stopped
|
|
122
|
+
*/
|
|
123
|
+
fastify.post('/api/servers/:name/world/reset', {
|
|
124
|
+
schema: {
|
|
125
|
+
description: 'Reset server world data (server must be stopped)',
|
|
126
|
+
tags: ['servers', 'world'],
|
|
127
|
+
params: ServerNameParamsSchema,
|
|
128
|
+
response: {
|
|
129
|
+
200: WorldResetResponseSchema,
|
|
130
|
+
404: ErrorResponseSchema,
|
|
131
|
+
409: ErrorResponseSchema,
|
|
132
|
+
500: ErrorResponseSchema,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
}, async (request, reply) => {
|
|
136
|
+
const { name } = request.params;
|
|
137
|
+
const containerName = `mc-${name}`;
|
|
138
|
+
try {
|
|
139
|
+
// Check if server exists
|
|
140
|
+
if (!serverExists(name)) {
|
|
141
|
+
return reply.code(404).send({
|
|
142
|
+
error: 'NotFound',
|
|
143
|
+
message: `Server '${name}' not found`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Check if server is stopped - must be fully stopped to reset world
|
|
147
|
+
const status = getContainerStatus(containerName);
|
|
148
|
+
if (status === 'running' || status === 'paused' || status === 'restarting' || status === 'created') {
|
|
149
|
+
return reply.code(409).send({
|
|
150
|
+
error: 'Conflict',
|
|
151
|
+
message: `Server must be stopped before resetting world (current status: ${status}). Please stop the server first.`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Get world name from configuration
|
|
155
|
+
const worldName = configService.getWorldName(name);
|
|
156
|
+
// Validate world path to prevent path traversal
|
|
157
|
+
const worldsBase = resolve(config.platformPath, 'worlds');
|
|
158
|
+
const worldPath = resolve(worldsBase, worldName);
|
|
159
|
+
if (!worldPath.startsWith(worldsBase + '/')) {
|
|
160
|
+
return reply.code(400).send({
|
|
161
|
+
error: 'BadRequest',
|
|
162
|
+
message: 'Invalid world name in server configuration',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (!existsSync(worldPath)) {
|
|
166
|
+
return reply.code(404).send({
|
|
167
|
+
error: 'NotFound',
|
|
168
|
+
message: `World '${worldName}' not found`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// Delete world directory contents, preserving .meta file
|
|
172
|
+
const entries = readdirSync(worldPath, { withFileTypes: true });
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
if (entry.name === '.meta') {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const entryPath = join(worldPath, entry.name);
|
|
178
|
+
rmSync(entryPath, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
fastify.log.info({
|
|
181
|
+
server: name,
|
|
182
|
+
worldName,
|
|
183
|
+
worldPath,
|
|
184
|
+
}, 'World reset completed');
|
|
185
|
+
return reply.send({
|
|
186
|
+
success: true,
|
|
187
|
+
message: 'World data has been reset. Start the server to generate a new world.',
|
|
188
|
+
worldName,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
fastify.log.error(error, 'Failed to reset world');
|
|
193
|
+
return reply.code(500).send({
|
|
194
|
+
error: 'InternalServerError',
|
|
195
|
+
message: 'Failed to reset world',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
// ============================================================
|
|
201
|
+
// Export
|
|
202
|
+
// ============================================================
|
|
203
|
+
export default fp(configPlugin, {
|
|
204
|
+
name: 'server-config-routes',
|
|
205
|
+
fastify: '5.x',
|
|
206
|
+
});
|
|
207
|
+
export { configPlugin };
|
|
208
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/routes/servers/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAgB,WAAW,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,wBAAwB,GAEzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAyB,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAmBtE,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,YAAY,GAAuB,KAAK,EAAE,OAAwB,EAAE,EAAE;IAC1E,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAE/D;;;OAGG;IACH,OAAO,CAAC,GAAG,CAAiB,2BAA2B,EAAE;QACvD,MAAM,EAAE;YACN,WAAW,EAAE,0CAA0C;YACvD,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;YAC3B,MAAM,EAAE,sBAAsB;YAC9B,QAAQ,EAAE;gBACR,GAAG,EAAE,0BAA0B;gBAC/B,GAAG,EAAE,mBAAmB;gBACxB,GAAG,EAAE,mBAAmB;aACzB;SACF;KACF,EAAE,KAAK,EAAE,OAAuC,EAAE,KAAmB,EAAE,EAAE;QACxE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEhC,IAAI,CAAC;YACH,yBAAyB;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,WAAW,IAAI,aAAa;iBACtC,CAAC,CAAC;YACL,CAAC;YAED,yBAAyB;YACzB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,6BAA6B,IAAI,aAAa;iBACxD,CAAC,CAAC;YACL,CAAC;YAED,MAAM,YAAY,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAEnD,OAAO,KAAK,CAAC,IAAI,CAAC;gBAChB,MAAM,EAAE,YAAY;aACrB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,oCAAoC,CAAC,CAAC;YAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,qBAAqB;gBAC5B,OAAO,EAAE,oCAAoC;aAC9C,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAoB,2BAA2B,EAAE;QAC5D,MAAM,EAAE;YACN,WAAW,EAAE,2CAA2C;YACxD,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;YAC3B,MAAM,EAAE,sBAAsB;YAC9B,IAAI,EAAE,+BAA+B;YACrC,QAAQ,EAAE;gBACR,GAAG,EAAE,gCAAgC;gBACrC,GAAG,EAAE,mBAAmB;gBACxB,GAAG,EAAE,mBAAmB;aACzB;SACF;KACF,EAAE,KAAK,EAAE,OAA0C,EAAE,KAAmB,EAAE,EAAE;QAC3E,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAChC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;QAE7B,IAAI,CAAC;YACH,yBAAyB;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,WAAW,IAAI,aAAa;iBACtC,CAAC,CAAC;YACL,CAAC;YAED,yBAAyB;YACzB,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,6BAA6B,IAAI,aAAa;iBACxD,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAEzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,IAAI;gBACZ,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,eAAe,EAAE,MAAM,CAAC,eAAe;aACxC,EAAE,8BAA8B,CAAC,CAAC;YAEnC,OAAO,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,uCAAuC,CAAC,CAAC;YAClE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,qBAAqB;gBAC5B,OAAO,EAAE,uCAAuC;aACjD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,OAAO,CAAC,IAAI,CAAkB,gCAAgC,EAAE;QAC9D,MAAM,EAAE;YACN,WAAW,EAAE,kDAAkD;YAC/D,IAAI,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;YAC1B,MAAM,EAAE,sBAAsB;YAC9B,QAAQ,EAAE;gBACR,GAAG,EAAE,wBAAwB;gBAC7B,GAAG,EAAE,mBAAmB;gBACxB,GAAG,EAAE,mBAAmB;gBACxB,GAAG,EAAE,mBAAmB;aACzB;SACF;KACF,EAAE,KAAK,EAAE,OAAwC,EAAE,KAAmB,EAAE,EAAE;QACzE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAChC,MAAM,aAAa,GAAG,MAAM,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC;YACH,yBAAyB;YACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,WAAW,IAAI,aAAa;iBACtC,CAAC,CAAC;YACL,CAAC;YAED,oEAAoE;YACpE,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;YACjD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACnG,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,kEAAkE,MAAM,kCAAkC;iBACpH,CAAC,CAAC;YACL,CAAC;YAED,oCAAoC;YACpC,MAAM,SAAS,GAAG,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAEnD,gDAAgD;YAChD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACjD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC;gBAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,YAAY;oBACnB,OAAO,EAAE,4CAA4C;iBACtD,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,KAAK,EAAE,UAAU;oBACjB,OAAO,EAAE,UAAU,SAAS,aAAa;iBAC1C,CAAC,CAAC;YACL,CAAC;YAED,yDAAyD;YACzD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAEhE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,SAAS;gBACX,CAAC;gBAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBACf,MAAM,EAAE,IAAI;gBACZ,SAAS;gBACT,SAAS;aACV,EAAE,uBAAuB,CAAC,CAAC;YAE5B,OAAO,KAAK,CAAC,IAAI,CAAC;gBAChB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,sEAAsE;gBAC/E,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;YAClD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,qBAAqB;gBAC5B,OAAO,EAAE,uBAAuB;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,+DAA+D;AAC/D,SAAS;AACT,+DAA+D;AAE/D,eAAe,EAAE,CAAC,YAAY,EAAE;IAC9B,IAAI,EAAE,sBAAsB;IAC5B,OAAO,EAAE,KAAK;CACf,CAAC,CAAC;AAEH,OAAO,EAAE,YAAY,EAAE,CAAC"}
|