@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 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;AAenD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,eAAe,CAAC,CAgFtF;AAED,eAAe,QAAQ,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":"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"}
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":"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"}