@fecommunity/reactpress-server 1.0.5-beta.0 → 3.0.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/LICENSE +21 -0
- package/README.md +278 -307
- package/bin/reactpress-server.js +175 -274
- package/dist/app.module.js +28 -3
- package/dist/app.module.js.map +1 -1
- package/dist/common/api-messages.d.ts +32 -0
- package/dist/common/api-messages.js +36 -0
- package/dist/common/api-messages.js.map +1 -0
- package/dist/generate-swagger.d.ts +1 -0
- package/dist/generate-swagger.js +73 -0
- package/dist/generate-swagger.js.map +1 -0
- package/dist/main.d.ts +5 -0
- package/dist/main.js +258 -39
- package/dist/main.js.map +1 -1
- package/dist/modules/api-key/api-key.controller.d.ts +14 -0
- package/dist/modules/api-key/api-key.controller.js +63 -0
- package/dist/modules/api-key/api-key.controller.js.map +1 -0
- package/dist/modules/api-key/api-key.entity.d.ts +11 -0
- package/dist/modules/api-key/api-key.entity.js +63 -0
- package/dist/modules/api-key/api-key.entity.js.map +1 -0
- package/dist/modules/api-key/api-key.guard.d.ts +7 -0
- package/dist/modules/api-key/api-key.guard.js +40 -0
- package/dist/modules/api-key/api-key.guard.js.map +1 -0
- package/dist/modules/api-key/api-key.module.d.ts +2 -0
- package/dist/modules/api-key/api-key.module.js +28 -0
- package/dist/modules/api-key/api-key.module.js.map +1 -0
- package/dist/modules/api-key/api-key.service.d.ts +15 -0
- package/dist/modules/api-key/api-key.service.js +81 -0
- package/dist/modules/api-key/api-key.service.js.map +1 -0
- package/dist/modules/article/article-revision.entity.d.ts +11 -0
- package/dist/modules/article/article-revision.entity.js +53 -0
- package/dist/modules/article/article-revision.entity.js.map +1 -0
- package/dist/modules/article/article.controller.d.ts +6 -1
- package/dist/modules/article/article.controller.js +45 -1
- package/dist/modules/article/article.controller.js.map +1 -1
- package/dist/modules/article/article.entity.d.ts +1 -0
- package/dist/modules/article/article.entity.js +5 -0
- package/dist/modules/article/article.entity.js.map +1 -1
- package/dist/modules/article/article.module.js +14 -2
- package/dist/modules/article/article.module.js.map +1 -1
- package/dist/modules/article/article.service.d.ts +9 -1
- package/dist/modules/article/article.service.js +59 -5
- package/dist/modules/article/article.service.js.map +1 -1
- package/dist/modules/article/scheduled-publish.service.d.ts +13 -0
- package/dist/modules/article/scheduled-publish.service.js +65 -0
- package/dist/modules/article/scheduled-publish.service.js.map +1 -0
- package/dist/modules/auth/auth.service.js +4 -3
- package/dist/modules/auth/auth.service.js.map +1 -1
- package/dist/modules/auth/jwt-auth.guard.js +2 -1
- package/dist/modules/auth/jwt-auth.guard.js.map +1 -1
- package/dist/modules/auth/jwt.strategy.js +2 -1
- package/dist/modules/auth/jwt.strategy.js.map +1 -1
- package/dist/modules/category/category.service.js +3 -2
- package/dist/modules/category/category.service.js.map +1 -1
- package/dist/modules/comment/comment.module.js +10 -1
- package/dist/modules/comment/comment.module.js.map +1 -1
- package/dist/modules/comment/comment.service.d.ts +3 -1
- package/dist/modules/comment/comment.service.js +15 -5
- package/dist/modules/comment/comment.service.js.map +1 -1
- package/dist/modules/health/health.controller.d.ts +11 -0
- package/dist/modules/health/health.controller.js +57 -0
- package/dist/modules/health/health.controller.js.map +1 -0
- package/dist/modules/health/health.module.d.ts +2 -0
- package/dist/modules/health/health.module.js +20 -0
- package/dist/modules/health/health.module.js.map +1 -0
- package/dist/modules/knowledge/knowledge.service.js +3 -2
- package/dist/modules/knowledge/knowledge.service.js.map +1 -1
- package/dist/modules/page/page.service.js +2 -1
- package/dist/modules/page/page.service.js.map +1 -1
- package/dist/modules/setting/setting.constant.d.ts +2 -3
- package/dist/modules/setting/setting.constant.js +4 -3
- package/dist/modules/setting/setting.constant.js.map +1 -1
- package/dist/modules/setting/setting.service.js +34 -11
- package/dist/modules/setting/setting.service.js.map +1 -1
- package/dist/modules/smtp/smtp.service.js +2 -1
- package/dist/modules/smtp/smtp.service.js.map +1 -1
- package/dist/modules/tag/tag.service.js +3 -2
- package/dist/modules/tag/tag.service.js.map +1 -1
- package/dist/modules/user/user.controller.js +4 -3
- package/dist/modules/user/user.controller.js.map +1 -1
- package/dist/modules/user/user.service.js +10 -9
- package/dist/modules/user/user.service.js.map +1 -1
- package/dist/modules/webhook/webhook.controller.d.ts +12 -0
- package/dist/modules/webhook/webhook.controller.js +63 -0
- package/dist/modules/webhook/webhook.controller.js.map +1 -0
- package/dist/modules/webhook/webhook.entity.d.ts +9 -0
- package/dist/modules/webhook/webhook.entity.js +54 -0
- package/dist/modules/webhook/webhook.entity.js.map +1 -0
- package/dist/modules/webhook/webhook.module.d.ts +2 -0
- package/dist/modules/webhook/webhook.module.js +27 -0
- package/dist/modules/webhook/webhook.module.js.map +1 -0
- package/dist/modules/webhook/webhook.service.d.ts +16 -0
- package/dist/modules/webhook/webhook.service.js +97 -0
- package/dist/modules/webhook/webhook.service.js.map +1 -0
- package/dist/public/favicon.png +0 -0
- package/dist/public/index.html +439 -0
- package/dist/public/swagger/custom.css +11 -0
- package/dist/starter.d.ts +1 -0
- package/dist/starter.js +84 -0
- package/dist/starter.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +4963 -3719
- package/dist/utils/oss.util.js +2 -1
- package/dist/utils/oss.util.js.map +1 -1
- package/package.json +41 -32
- package/public/favicon.png +0 -0
- package/public/index.html +439 -0
- package/public/swagger/custom.css +11 -0
- package/dist/bootstrap.d.ts +0 -10
- package/dist/bootstrap.js +0 -57
- package/dist/bootstrap.js.map +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@nestjs/core");
|
|
4
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const app_module_1 = require("./app.module");
|
|
8
|
+
async function generateSwaggerJson() {
|
|
9
|
+
let app;
|
|
10
|
+
try {
|
|
11
|
+
console.log('🚀 Starting Swagger JSON generation...');
|
|
12
|
+
app = await core_1.NestFactory.createApplicationContext(app_module_1.AppModule, {
|
|
13
|
+
logger: ['error', 'warn'],
|
|
14
|
+
});
|
|
15
|
+
const configService = app.get('ConfigService');
|
|
16
|
+
const apiPrefix = configService.get('SERVER_API_PREFIX', '/api');
|
|
17
|
+
console.log('📝 Configuring Swagger documentation...');
|
|
18
|
+
const swaggerConfig = new swagger_1.DocumentBuilder()
|
|
19
|
+
.setTitle('ReactPress API Documentation')
|
|
20
|
+
.setDescription('Comprehensive API documentation for ReactPress - A modern content management system built with NestJS')
|
|
21
|
+
.setVersion('2.0')
|
|
22
|
+
.setContact('ReactPress Team', 'https://github.com/fecommunity/reactpress', 'admin@gaoredu.com')
|
|
23
|
+
.setLicense('MIT', 'https://github.com/fecommunity/reactpress/blob/main/LICENSE')
|
|
24
|
+
.addServer(configService.get('SERVER_SITE_URL', 'http://localhost:3002'), 'API Server')
|
|
25
|
+
.build();
|
|
26
|
+
console.log('🔨 Generating Swagger document...');
|
|
27
|
+
const document = swagger_1.SwaggerModule.createDocument(app, swaggerConfig);
|
|
28
|
+
const outputPath = path_1.join(__dirname, '../public/swagger.json');
|
|
29
|
+
const publicDir = path_1.join(__dirname, '../public');
|
|
30
|
+
if (!fs_1.existsSync(publicDir)) {
|
|
31
|
+
console.log('📁 Creating public directory...');
|
|
32
|
+
require('fs').mkdirSync(publicDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
if (fs_1.existsSync(outputPath)) {
|
|
35
|
+
console.log('🗑️ Removing existing swagger.json file...');
|
|
36
|
+
fs_1.unlinkSync(outputPath);
|
|
37
|
+
}
|
|
38
|
+
console.log('💾 Writing Swagger JSON to file...');
|
|
39
|
+
fs_1.writeFileSync(outputPath, JSON.stringify(document, null, 2));
|
|
40
|
+
console.log(`✅ Success! Swagger JSON generated at: ${outputPath}`);
|
|
41
|
+
console.log('🎉 Swagger generation process completed successfully');
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error('❌ Error during Swagger generation:', error.message);
|
|
46
|
+
const existingPath = path_1.join(__dirname, '../public/swagger.json');
|
|
47
|
+
if (fs_1.existsSync(existingPath)) {
|
|
48
|
+
console.log('ℹ️ Using existing swagger.json file');
|
|
49
|
+
console.log('🎉 Swagger generation process completed successfully');
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.error('❌ No existing swagger.json file found');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
generateSwaggerJson().catch(e => {
|
|
61
|
+
console.error('💥 Unhandled error in generateSwaggerJson:', e.message);
|
|
62
|
+
const existingPath = path_1.join(__dirname, '../public/swagger.json');
|
|
63
|
+
if (fs_1.existsSync(existingPath)) {
|
|
64
|
+
console.log('ℹ️ Using existing swagger.json file');
|
|
65
|
+
console.log('🎉 Swagger generation process completed successfully');
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error('❌ No existing swagger.json file found');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=generate-swagger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-swagger.js","sourceRoot":"","sources":["../src/generate-swagger.ts"],"names":[],"mappings":"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"}
|
package/dist/main.d.ts
CHANGED
package/dist/main.js
CHANGED
|
@@ -1,44 +1,263 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const swagger_1 = require("@nestjs/swagger");
|
|
5
|
-
const bodyParser = require("body-parser");
|
|
6
|
-
const compression = require("compression");
|
|
7
|
-
const express = require("express");
|
|
8
|
-
const rateLimit = require("express-rate-limit");
|
|
9
|
-
const helmet = require("helmet");
|
|
3
|
+
const fs = require("fs");
|
|
10
4
|
const path_1 = require("path");
|
|
5
|
+
const express = require("express");
|
|
6
|
+
const bodyParser = require("body-parser");
|
|
11
7
|
const open = require("open");
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
8
|
+
const net = require("net");
|
|
9
|
+
const INSTALLATION_PORT = 3002;
|
|
10
|
+
const MAX_PORT_ATTEMPTS = 10;
|
|
11
|
+
const serverState = {
|
|
12
|
+
server: null,
|
|
13
|
+
isClosing: false,
|
|
14
|
+
isListening: false
|
|
15
|
+
};
|
|
16
|
+
const checkPort = (port) => {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
const server = net.createServer();
|
|
19
|
+
server.once('error', (err) => {
|
|
20
|
+
if (err.code === 'EADDRINUSE') {
|
|
21
|
+
resolve(false);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
resolve(false);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
server.once('listening', () => {
|
|
28
|
+
server.once('close', () => resolve(true)).close();
|
|
29
|
+
});
|
|
30
|
+
server.listen(port);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
const findAvailablePort = async (startPort) => {
|
|
34
|
+
for (let port = startPort; port < startPort + MAX_PORT_ATTEMPTS; port++) {
|
|
35
|
+
if (await checkPort(port)) {
|
|
36
|
+
return port;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`No available ports found in range ${startPort}-${startPort + MAX_PORT_ATTEMPTS - 1}`);
|
|
40
|
+
};
|
|
41
|
+
const safelyCloseServer = async () => {
|
|
42
|
+
if (!serverState.server || serverState.isClosing) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
serverState.isClosing = true;
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
if (!serverState.isListening) {
|
|
48
|
+
serverState.server = null;
|
|
49
|
+
serverState.isClosing = false;
|
|
50
|
+
resolve();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const timeout = setTimeout(() => {
|
|
54
|
+
console.log('[ReactPress] Force closing server due to timeout');
|
|
55
|
+
serverState.server = null;
|
|
56
|
+
serverState.isClosing = false;
|
|
57
|
+
serverState.isListening = false;
|
|
58
|
+
resolve();
|
|
59
|
+
}, 3000);
|
|
60
|
+
serverState.server.close((err) => {
|
|
61
|
+
clearTimeout(timeout);
|
|
62
|
+
if (err && err.code !== 'ERR_SERVER_NOT_RUNNING') {
|
|
63
|
+
console.warn('[ReactPress] Server close warning:', err.message);
|
|
64
|
+
}
|
|
65
|
+
serverState.server = null;
|
|
66
|
+
serverState.isClosing = false;
|
|
67
|
+
serverState.isListening = false;
|
|
68
|
+
resolve();
|
|
69
|
+
});
|
|
70
|
+
if (serverState.server.closeAllConnections) {
|
|
71
|
+
serverState.server.closeAllConnections();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const startServerWithState = (app, port) => {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (serverState.server) {
|
|
78
|
+
reject(new Error('Server is already running'));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const server = app.listen(port, () => {
|
|
82
|
+
serverState.server = server;
|
|
83
|
+
serverState.isListening = true;
|
|
84
|
+
global.installationPort = port;
|
|
85
|
+
console.log(`[ReactPress] Installation server running on http://localhost:${port}`);
|
|
86
|
+
resolve();
|
|
87
|
+
});
|
|
88
|
+
server.on('error', (error) => {
|
|
89
|
+
serverState.isListening = false;
|
|
90
|
+
reject(error);
|
|
91
|
+
});
|
|
92
|
+
server.on('close', () => {
|
|
93
|
+
serverState.isListening = false;
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
const setupSignalHandlers = () => {
|
|
98
|
+
const shutdown = async (signal) => {
|
|
99
|
+
console.log(`\n[ReactPress] Received ${signal}, shutting down gracefully...`);
|
|
100
|
+
await safelyCloseServer();
|
|
101
|
+
process.exit(0);
|
|
102
|
+
};
|
|
103
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
104
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
105
|
+
process.on('SIGHUP', () => shutdown('SIGHUP'));
|
|
106
|
+
};
|
|
107
|
+
const main = async () => {
|
|
108
|
+
try {
|
|
109
|
+
setupSignalHandlers();
|
|
110
|
+
const projectRoot = getProjectRoot();
|
|
111
|
+
const envPath = path_1.join(projectRoot, '.env');
|
|
112
|
+
console.log(`[ReactPress] Checking for environment file at: ${envPath}`);
|
|
113
|
+
console.log(`[ReactPress] Project root determined to be: ${projectRoot}`);
|
|
114
|
+
if (fs.existsSync(envPath)) {
|
|
115
|
+
console.log('[ReactPress] Environment file exists, starting main application');
|
|
116
|
+
await startMainApplication();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
console.log('[ReactPress] Environment file not found, starting installation wizard');
|
|
120
|
+
console.log('[ReactPress] Current working directory:', process.cwd());
|
|
121
|
+
console.log('[ReactPress] __dirname:', __dirname);
|
|
122
|
+
await runInstallationWizard();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error('[ReactPress] Fatal error:', error);
|
|
126
|
+
await safelyCloseServer();
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const getProjectRoot = () => {
|
|
131
|
+
if (process.env.REACTPRESS_ORIGINAL_CWD) {
|
|
132
|
+
console.log(`[ReactPress] Using original working directory from npx execution: ${process.env.REACTPRESS_ORIGINAL_CWD}`);
|
|
133
|
+
return process.env.REACTPRESS_ORIGINAL_CWD;
|
|
134
|
+
}
|
|
135
|
+
const projectRoot = process.cwd();
|
|
136
|
+
console.log(`[ReactPress] Using current working directory as project root: ${projectRoot}`);
|
|
137
|
+
return projectRoot;
|
|
138
|
+
};
|
|
139
|
+
const runInstallationWizard = async () => {
|
|
140
|
+
try {
|
|
141
|
+
const port = await findAvailablePort(INSTALLATION_PORT);
|
|
142
|
+
const app = express();
|
|
143
|
+
app.use(bodyParser.json({ limit: '10mb' }));
|
|
144
|
+
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));
|
|
145
|
+
app.use('/public', express.static(path_1.join(__dirname, '../public')));
|
|
146
|
+
app.get('/', (req, res) => {
|
|
147
|
+
res.sendFile(path_1.join(__dirname, '../public/index.html'));
|
|
148
|
+
});
|
|
149
|
+
app.post('/test-db', async (req, res) => {
|
|
150
|
+
try {
|
|
151
|
+
const mysql = await Promise.resolve().then(() => require('mysql2/promise'));
|
|
152
|
+
const { host, port, user, password, database } = req.body;
|
|
153
|
+
const connection = await mysql.createConnection({
|
|
154
|
+
host: host || 'localhost',
|
|
155
|
+
port: parseInt(port) || 3306,
|
|
156
|
+
user,
|
|
157
|
+
password,
|
|
158
|
+
database
|
|
159
|
+
});
|
|
160
|
+
await connection.execute('SELECT 1');
|
|
161
|
+
await connection.end();
|
|
162
|
+
res.json({ success: true, message: 'Database connection successful!' });
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
res.status(400).json({
|
|
166
|
+
success: false,
|
|
167
|
+
message: `Database connection failed: ${error.message}`
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
app.post('/install', async (req, res) => {
|
|
172
|
+
try {
|
|
173
|
+
const { db, site } = req.body;
|
|
174
|
+
if (!db || !site) {
|
|
175
|
+
return res.status(400).json({
|
|
176
|
+
success: false,
|
|
177
|
+
message: 'Missing configuration data'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const mysql = await Promise.resolve().then(() => require('mysql2/promise'));
|
|
181
|
+
const connection = await mysql.createConnection({
|
|
182
|
+
host: db.host || 'localhost',
|
|
183
|
+
port: parseInt(db.port) || 3306,
|
|
184
|
+
user: db.user,
|
|
185
|
+
password: db.password,
|
|
186
|
+
database: db.database
|
|
187
|
+
});
|
|
188
|
+
await connection.execute('SELECT 1');
|
|
189
|
+
await connection.end();
|
|
190
|
+
const envContent = `# Database Config
|
|
191
|
+
DB_HOST=${db.host || '127.0.0.1'}
|
|
192
|
+
DB_PORT=${db.port || 3306}
|
|
193
|
+
DB_USER=${db.user}
|
|
194
|
+
DB_PASSWD=${db.password}
|
|
195
|
+
DB_DATABASE=${db.database}
|
|
196
|
+
|
|
197
|
+
# Client Config
|
|
198
|
+
CLIENT_SITE_URL=${site.clientUrl || 'http://localhost:3001'}
|
|
199
|
+
|
|
200
|
+
# Server Config
|
|
201
|
+
SERVER_SITE_URL=${site.serverUrl || 'http://localhost:3002'}
|
|
202
|
+
`.trim();
|
|
203
|
+
const projectRoot = getProjectRoot();
|
|
204
|
+
const envPath = path_1.join(projectRoot, '.env');
|
|
205
|
+
fs.writeFileSync(envPath, envContent, 'utf8');
|
|
206
|
+
res.json({
|
|
207
|
+
success: true,
|
|
208
|
+
message: 'Installation completed! Server will restart.',
|
|
209
|
+
serverUrl: site.serverUrl || 'http://localhost:3002'
|
|
210
|
+
});
|
|
211
|
+
res.on('finish', async () => {
|
|
212
|
+
try {
|
|
213
|
+
console.log('[ReactPress] Installation complete, restarting server...');
|
|
214
|
+
await safelyCloseServer();
|
|
215
|
+
await startMainApplication();
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
console.error('[ReactPress] Restart error:', error);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
res.status(400).json({
|
|
224
|
+
success: false,
|
|
225
|
+
message: `Installation failed: ${error.message}`
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
await startServerWithState(app, port);
|
|
230
|
+
try {
|
|
231
|
+
await open(`http://localhost:${port}`);
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
console.log(`[ReactPress] Please visit http://localhost:${port} manually`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
console.error('[ReactPress] Installation wizard failed:', error);
|
|
239
|
+
await safelyCloseServer();
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const startMainApplication = async () => {
|
|
244
|
+
try {
|
|
245
|
+
console.log('[ReactPress] Starting main application...');
|
|
246
|
+
await safelyCloseServer();
|
|
247
|
+
global.isInstalling = false;
|
|
248
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
249
|
+
const { bootstrap } = await Promise.resolve().then(() => require('./starter'));
|
|
250
|
+
if (typeof bootstrap === 'function') {
|
|
251
|
+
await bootstrap();
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
throw new Error('Bootstrap function not found');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error('[ReactPress] Failed to start main application:', error);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
main();
|
|
44
263
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ApiKeyService } from './api-key.service';
|
|
2
|
+
export declare class ApiKeyController {
|
|
3
|
+
private readonly apiKeyService;
|
|
4
|
+
constructor(apiKeyService: ApiKeyService);
|
|
5
|
+
list(): Promise<import("./api-key.entity").ApiKey[]>;
|
|
6
|
+
create(body: {
|
|
7
|
+
name: string;
|
|
8
|
+
scopes?: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
apiKey: import("./api-key.entity").ApiKey;
|
|
11
|
+
rawKey: string;
|
|
12
|
+
}>;
|
|
13
|
+
revoke(id: string): Promise<import("./api-key.entity").ApiKey>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ApiKeyController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
+
const jwt_auth_guard_1 = require("../auth/jwt-auth.guard");
|
|
19
|
+
const roles_guard_1 = require("../auth/roles.guard");
|
|
20
|
+
const api_key_service_1 = require("./api-key.service");
|
|
21
|
+
let ApiKeyController = class ApiKeyController {
|
|
22
|
+
constructor(apiKeyService) {
|
|
23
|
+
this.apiKeyService = apiKeyService;
|
|
24
|
+
}
|
|
25
|
+
list() {
|
|
26
|
+
return this.apiKeyService.findAll();
|
|
27
|
+
}
|
|
28
|
+
create(body) {
|
|
29
|
+
return this.apiKeyService.create(body.name, body.scopes || 'read');
|
|
30
|
+
}
|
|
31
|
+
revoke(id) {
|
|
32
|
+
return this.apiKeyService.revoke(id);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
__decorate([
|
|
36
|
+
common_1.Get(),
|
|
37
|
+
__metadata("design:type", Function),
|
|
38
|
+
__metadata("design:paramtypes", []),
|
|
39
|
+
__metadata("design:returntype", void 0)
|
|
40
|
+
], ApiKeyController.prototype, "list", null);
|
|
41
|
+
__decorate([
|
|
42
|
+
common_1.Post(),
|
|
43
|
+
__param(0, common_1.Body()),
|
|
44
|
+
__metadata("design:type", Function),
|
|
45
|
+
__metadata("design:paramtypes", [Object]),
|
|
46
|
+
__metadata("design:returntype", void 0)
|
|
47
|
+
], ApiKeyController.prototype, "create", null);
|
|
48
|
+
__decorate([
|
|
49
|
+
common_1.Delete(':id'),
|
|
50
|
+
__param(0, common_1.Param('id')),
|
|
51
|
+
__metadata("design:type", Function),
|
|
52
|
+
__metadata("design:paramtypes", [String]),
|
|
53
|
+
__metadata("design:returntype", void 0)
|
|
54
|
+
], ApiKeyController.prototype, "revoke", null);
|
|
55
|
+
ApiKeyController = __decorate([
|
|
56
|
+
swagger_1.ApiTags('ApiKey'),
|
|
57
|
+
common_1.Controller('api-key'),
|
|
58
|
+
common_1.UseGuards(roles_guard_1.RolesGuard, jwt_auth_guard_1.JwtAuthGuard),
|
|
59
|
+
roles_guard_1.Roles('admin'),
|
|
60
|
+
__metadata("design:paramtypes", [api_key_service_1.ApiKeyService])
|
|
61
|
+
], ApiKeyController);
|
|
62
|
+
exports.ApiKeyController = ApiKeyController;
|
|
63
|
+
//# sourceMappingURL=api-key.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.controller.js","sourceRoot":"","sources":["../../../src/modules/api-key/api-key.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAuF;AACvF,6CAA0C;AAE1C,2DAAsD;AACtD,qDAAwD;AACxD,uDAAkD;AAMlD,IAAa,gBAAgB,GAA7B,MAAa,gBAAgB;IAC3B,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAG7D,IAAI;QACF,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;IAGD,MAAM,CAAS,IAAuC;QACpD,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;IACrE,CAAC;IAGD,MAAM,CAAc,EAAU;QAC5B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;CACF,CAAA;AAbC;IADC,YAAG,EAAE;;;;4CAGL;AAGD;IADC,aAAI,EAAE;IACC,WAAA,aAAI,EAAE,CAAA;;;;8CAEb;AAGD;IADC,eAAM,CAAC,KAAK,CAAC;IACN,WAAA,cAAK,CAAC,IAAI,CAAC,CAAA;;;;8CAElB;AAhBU,gBAAgB;IAJ5B,iBAAO,CAAC,QAAQ,CAAC;IACjB,mBAAU,CAAC,SAAS,CAAC;IACrB,kBAAS,CAAC,wBAAU,EAAE,6BAAY,CAAC;IACnC,mBAAK,CAAC,OAAO,CAAC;qCAE+B,+BAAa;GAD9C,gBAAgB,CAiB5B;AAjBY,4CAAgB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ApiKey = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
let ApiKey = class ApiKey {
|
|
16
|
+
};
|
|
17
|
+
__decorate([
|
|
18
|
+
swagger_1.ApiProperty(),
|
|
19
|
+
typeorm_1.PrimaryGeneratedColumn('uuid'),
|
|
20
|
+
__metadata("design:type", String)
|
|
21
|
+
], ApiKey.prototype, "id", void 0);
|
|
22
|
+
__decorate([
|
|
23
|
+
swagger_1.ApiProperty(),
|
|
24
|
+
typeorm_1.Column(),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], ApiKey.prototype, "name", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
swagger_1.ApiProperty({ description: 'bcrypt hash of the raw key' }),
|
|
29
|
+
typeorm_1.Column({ select: false }),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], ApiKey.prototype, "keyHash", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
swagger_1.ApiProperty({ description: 'Comma-separated scopes: read, write' }),
|
|
34
|
+
typeorm_1.Column({ default: 'read' }),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], ApiKey.prototype, "scopes", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
swagger_1.ApiProperty(),
|
|
39
|
+
typeorm_1.Column({ type: 'varchar', length: 8, nullable: true }),
|
|
40
|
+
__metadata("design:type", String)
|
|
41
|
+
], ApiKey.prototype, "keyPrefix", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
swagger_1.ApiProperty(),
|
|
44
|
+
typeorm_1.Column({ default: true }),
|
|
45
|
+
__metadata("design:type", Boolean)
|
|
46
|
+
], ApiKey.prototype, "enabled", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
typeorm_1.CreateDateColumn({ name: 'create_at' }),
|
|
49
|
+
__metadata("design:type", Date)
|
|
50
|
+
], ApiKey.prototype, "createAt", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
typeorm_1.UpdateDateColumn({ name: 'update_at' }),
|
|
53
|
+
__metadata("design:type", Date)
|
|
54
|
+
], ApiKey.prototype, "updateAt", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
typeorm_1.Column({ type: 'datetime', nullable: true }),
|
|
57
|
+
__metadata("design:type", Date)
|
|
58
|
+
], ApiKey.prototype, "lastUsedAt", void 0);
|
|
59
|
+
ApiKey = __decorate([
|
|
60
|
+
typeorm_1.Entity('api_keys')
|
|
61
|
+
], ApiKey);
|
|
62
|
+
exports.ApiKey = ApiKey;
|
|
63
|
+
//# sourceMappingURL=api-key.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.entity.js","sourceRoot":"","sources":["../../../src/modules/api-key/api-key.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qCAAqG;AAGrG,IAAa,MAAM,GAAnB,MAAa,MAAM;CAiClB,CAAA;AA9BC;IAFC,qBAAW,EAAE;IACb,gCAAsB,CAAC,MAAM,CAAC;;kCACpB;AAIX;IAFC,qBAAW,EAAE;IACb,gBAAM,EAAE;;oCACI;AAIb;IAFC,qBAAW,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAC1D,gBAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;;uCACV;AAIhB;IAFC,qBAAW,CAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;IACnE,gBAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;;sCACb;AAIf;IAFC,qBAAW,EAAE;IACb,gBAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;yCACrC;AAIlB;IAFC,qBAAW,EAAE;IACb,gBAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;uCACT;AAGjB;IADC,0BAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BAC9B,IAAI;wCAAC;AAGf;IADC,0BAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;8BAC9B,IAAI;wCAAC;AAGf;IADC,gBAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BACjC,IAAI;0CAAC;AAhCN,MAAM;IADlB,gBAAM,CAAC,UAAU,CAAC;GACN,MAAM,CAiClB;AAjCY,wBAAM"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { ApiKeyService } from './api-key.service';
|
|
3
|
+
export declare class ApiKeyGuard implements CanActivate {
|
|
4
|
+
private readonly apiKeyService;
|
|
5
|
+
constructor(apiKeyService: ApiKeyService);
|
|
6
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ApiKeyGuard = void 0;
|
|
13
|
+
const api_messages_1 = require("../../common/api-messages");
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const api_key_service_1 = require("./api-key.service");
|
|
16
|
+
let ApiKeyGuard = class ApiKeyGuard {
|
|
17
|
+
constructor(apiKeyService) {
|
|
18
|
+
this.apiKeyService = apiKeyService;
|
|
19
|
+
}
|
|
20
|
+
async canActivate(context) {
|
|
21
|
+
const request = context.switchToHttp().getRequest();
|
|
22
|
+
const rawKey = request.headers['x-api-key'] ||
|
|
23
|
+
(request.headers.authorization || '').replace(/^Bearer\s+/i, '').trim();
|
|
24
|
+
if (!rawKey) {
|
|
25
|
+
throw new common_1.UnauthorizedException(api_messages_1.ApiMsg.MISSING_API_KEY);
|
|
26
|
+
}
|
|
27
|
+
const apiKey = await this.apiKeyService.validateRawKey(rawKey);
|
|
28
|
+
if (!apiKey) {
|
|
29
|
+
throw new common_1.UnauthorizedException(api_messages_1.ApiMsg.INVALID_API_KEY);
|
|
30
|
+
}
|
|
31
|
+
request.apiKey = apiKey;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
ApiKeyGuard = __decorate([
|
|
36
|
+
common_1.Injectable(),
|
|
37
|
+
__metadata("design:paramtypes", [api_key_service_1.ApiKeyService])
|
|
38
|
+
], ApiKeyGuard);
|
|
39
|
+
exports.ApiKeyGuard = ApiKeyGuard;
|
|
40
|
+
//# sourceMappingURL=api-key.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-key.guard.js","sourceRoot":"","sources":["../../../src/modules/api-key/api-key.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4DAAmD;AACnD,2CAAkG;AAElG,uDAAkD;AAGlD,IAAa,WAAW,GAAxB,MAAa,WAAW;IACtB,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;YAC5B,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1E,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,8BAAqB,CAAC,qBAAM,CAAC,eAAe,CAAC,CAAC;SACzD;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,8BAAqB,CAAC,qBAAM,CAAC,eAAe,CAAC,CAAC;SACzD;QAED,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AArBY,WAAW;IADvB,mBAAU,EAAE;qCAEiC,+BAAa;GAD9C,WAAW,CAqBvB;AArBY,kCAAW"}
|