underpost 2.8.87 → 2.8.88
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/.env.development +35 -3
- package/.env.production +39 -4
- package/.env.test +35 -3
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/npmpkg.ci.yml +1 -1
- package/.github/workflows/pwa-microservices-template-page.cd.yml +6 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +3 -3
- package/README.md +56 -2
- package/bin/build.js +4 -0
- package/bin/deploy.js +62 -8
- package/bin/file.js +3 -2
- package/cli.md +8 -2
- package/conf.js +30 -4
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +174 -0
- package/manifests/deployment/dd-test-development/proxy.yaml +51 -0
- package/package.json +6 -5
- package/src/api/core/core.router.js +2 -1
- package/src/api/default/default.controller.js +6 -1
- package/src/api/default/default.router.js +6 -2
- package/src/api/default/default.service.js +10 -1
- package/src/api/document/document.controller.js +66 -0
- package/src/api/document/document.model.js +51 -0
- package/src/api/document/document.router.js +24 -0
- package/src/api/document/document.service.js +125 -0
- package/src/api/file/file.controller.js +15 -1
- package/src/api/file/file.router.js +2 -1
- package/src/api/test/test.router.js +1 -1
- package/src/api/user/postman_collection.json +216 -0
- package/src/api/user/user.controller.js +25 -60
- package/src/api/user/user.model.js +29 -7
- package/src/api/user/user.router.js +9 -3
- package/src/api/user/user.service.js +84 -32
- package/src/cli/baremetal.js +33 -3
- package/src/cli/cloud-init.js +11 -0
- package/src/cli/cron.js +0 -1
- package/src/cli/deploy.js +46 -23
- package/src/cli/index.js +5 -0
- package/src/cli/lxd.js +7 -0
- package/src/cli/repository.js +42 -6
- package/src/cli/run.js +45 -13
- package/src/cli/ssh.js +20 -6
- package/src/client/Default.index.js +42 -1
- package/src/client/components/core/Account.js +10 -2
- package/src/client/components/core/AgGrid.js +30 -8
- package/src/client/components/core/Auth.js +99 -56
- package/src/client/components/core/BtnIcon.js +3 -2
- package/src/client/components/core/CalendarCore.js +2 -3
- package/src/client/components/core/CommonJs.js +1 -2
- package/src/client/components/core/Content.js +15 -12
- package/src/client/components/core/Css.js +2 -1
- package/src/client/components/core/CssCore.js +6 -1
- package/src/client/components/core/Docs.js +5 -5
- package/src/client/components/core/FileExplorer.js +3 -3
- package/src/client/components/core/Input.js +22 -17
- package/src/client/components/core/JoyStick.js +2 -2
- package/src/client/components/core/LoadingAnimation.js +2 -2
- package/src/client/components/core/LogIn.js +16 -23
- package/src/client/components/core/LogOut.js +5 -1
- package/src/client/components/core/Logger.js +4 -1
- package/src/client/components/core/Modal.js +82 -53
- package/src/client/components/core/ObjectLayerEngineModal.js +2 -1
- package/src/client/components/core/Pagination.js +207 -0
- package/src/client/components/core/Panel.js +10 -10
- package/src/client/components/core/PanelForm.js +130 -33
- package/src/client/components/core/Recover.js +2 -2
- package/src/client/components/core/Router.js +210 -34
- package/src/client/components/core/SignUp.js +1 -2
- package/src/client/components/core/Stream.js +1 -1
- package/src/client/components/core/VanillaJs.js +3 -84
- package/src/client/components/core/Worker.js +2 -2
- package/src/client/components/default/LogInDefault.js +0 -6
- package/src/client/components/default/LogOutDefault.js +0 -16
- package/src/client/components/default/MenuDefault.js +97 -44
- package/src/client/components/default/RoutesDefault.js +5 -2
- package/src/client/services/core/core.service.js +8 -20
- package/src/client/services/default/default.management.js +115 -18
- package/src/client/services/default/default.service.js +13 -4
- package/src/client/services/document/document.service.js +97 -0
- package/src/client/services/file/file.service.js +2 -0
- package/src/client/services/test/test.service.js +3 -0
- package/src/client/services/user/user.management.js +6 -0
- package/src/client/services/user/user.service.js +15 -4
- package/src/client/ssr/Render.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +3 -0
- package/src/client/ssr/head/Seo.js +1 -0
- package/src/index.js +24 -2
- package/src/runtime/lampp/Lampp.js +89 -2
- package/src/runtime/xampp/Xampp.js +48 -1
- package/src/server/auth.js +519 -155
- package/src/server/backup.js +2 -2
- package/src/server/conf.js +66 -8
- package/src/server/process.js +2 -1
- package/src/server/runtime.js +135 -286
- package/src/server/ssl.js +1 -2
- package/src/server/ssr.js +85 -0
- package/src/server/start.js +2 -2
- package/src/server/valkey.js +2 -1
package/src/server/runtime.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import express from 'express';
|
|
3
|
-
import cors from 'cors';
|
|
4
3
|
import dotenv from 'dotenv';
|
|
5
4
|
import fileUpload from 'express-fileupload';
|
|
6
5
|
import swaggerUi from 'swagger-ui-express';
|
|
7
6
|
import * as promClient from 'prom-client';
|
|
8
7
|
import compression from 'compression';
|
|
9
8
|
|
|
10
|
-
import { createServer } from 'http';
|
|
11
|
-
import { getRootDirectory } from './process.js';
|
|
12
9
|
import UnderpostStartUp from './start.js';
|
|
10
|
+
import { createServer } from 'http';
|
|
13
11
|
import { loggerFactory, loggerMiddleware } from './logger.js';
|
|
14
12
|
import { getCapVariableName, newInstance } from '../client/components/core/CommonJs.js';
|
|
15
|
-
import { Xampp } from '../runtime/xampp/Xampp.js';
|
|
16
13
|
import { MailerProvider } from '../mailer/MailerProvider.js';
|
|
17
14
|
import { DataBaseProvider } from '../db/DataBaseProvider.js';
|
|
18
|
-
// import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
19
15
|
import { createPeerServer } from './peer.js';
|
|
20
16
|
import { Lampp } from '../runtime/lampp/Lampp.js';
|
|
21
|
-
import {
|
|
22
|
-
import Underpost from '../index.js';
|
|
17
|
+
import { Xampp } from '../runtime/xampp/Xampp.js';
|
|
23
18
|
import { createValkeyConnection } from './valkey.js';
|
|
19
|
+
import { applySecurity, authMiddlewareFactory } from './auth.js';
|
|
20
|
+
import { getInstanceContext } from './conf.js';
|
|
21
|
+
import { ssrMiddlewareFactory } from './ssr.js';
|
|
24
22
|
|
|
25
23
|
dotenv.config();
|
|
26
24
|
|
|
@@ -38,8 +36,6 @@ const buildRuntime = async () => {
|
|
|
38
36
|
labelNames: ['instance', 'method', 'status_code'],
|
|
39
37
|
};
|
|
40
38
|
|
|
41
|
-
// logger.info('promCounterOption', promCounterOption);
|
|
42
|
-
|
|
43
39
|
const requestCounter = new promClient.Counter(promCounterOption);
|
|
44
40
|
const initPort = parseInt(process.env.PORT) + 1;
|
|
45
41
|
let currentPort = initPort;
|
|
@@ -47,9 +43,8 @@ const buildRuntime = async () => {
|
|
|
47
43
|
const confSSR = JSON.parse(fs.readFileSync(`./conf/conf.ssr.json`, 'utf8'));
|
|
48
44
|
const singleReplicaHosts = [];
|
|
49
45
|
for (const host of Object.keys(confServer)) {
|
|
50
|
-
if (singleReplicaHosts.length > 0
|
|
46
|
+
if (singleReplicaHosts.length > 0)
|
|
51
47
|
currentPort += singleReplicaHosts.reduce((accumulator, currentValue) => accumulator + currentValue.replicas, 0);
|
|
52
|
-
}
|
|
53
48
|
const rootHostPath = `/public/${host}`;
|
|
54
49
|
for (const path of Object.keys(confServer[host])) {
|
|
55
50
|
confServer[host][path].port = newInstance(currentPort);
|
|
@@ -68,9 +63,17 @@ const buildRuntime = async () => {
|
|
|
68
63
|
singleReplica,
|
|
69
64
|
replicas,
|
|
70
65
|
valkey,
|
|
66
|
+
apiBaseHost,
|
|
71
67
|
} = confServer[host][path];
|
|
72
68
|
|
|
73
|
-
|
|
69
|
+
const { redirectTarget, singleReplicaHost } = await getInstanceContext({
|
|
70
|
+
redirect,
|
|
71
|
+
singleReplicaHosts,
|
|
72
|
+
singleReplica,
|
|
73
|
+
replicas,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (singleReplicaHost) {
|
|
74
77
|
singleReplicaHosts.push({
|
|
75
78
|
host,
|
|
76
79
|
replicas: replicas.length,
|
|
@@ -87,161 +90,7 @@ const buildRuntime = async () => {
|
|
|
87
90
|
apis,
|
|
88
91
|
};
|
|
89
92
|
|
|
90
|
-
const redirectTarget = redirect
|
|
91
|
-
? redirect[redirect.length - 1] === '/'
|
|
92
|
-
? redirect.slice(0, -1)
|
|
93
|
-
: redirect
|
|
94
|
-
: undefined;
|
|
95
|
-
|
|
96
|
-
// if (redirect) logger.info('redirect', new URL(redirect));
|
|
97
|
-
|
|
98
93
|
switch (runtime) {
|
|
99
|
-
case 'lampp':
|
|
100
|
-
if (!Lampp.enabled()) continue;
|
|
101
|
-
if (!Lampp.ports.includes(port)) Lampp.ports.push(port);
|
|
102
|
-
if (currentPort === initPort) Lampp.removeRouter();
|
|
103
|
-
Lampp.appendRouter(`
|
|
104
|
-
|
|
105
|
-
Listen ${port}
|
|
106
|
-
|
|
107
|
-
<VirtualHost *:${port}>
|
|
108
|
-
DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
|
|
109
|
-
ServerName ${host}:${port}
|
|
110
|
-
|
|
111
|
-
<Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
|
|
112
|
-
Options Indexes FollowSymLinks MultiViews
|
|
113
|
-
AllowOverride All
|
|
114
|
-
Require all granted
|
|
115
|
-
</Directory>
|
|
116
|
-
|
|
117
|
-
${
|
|
118
|
-
redirect
|
|
119
|
-
? `
|
|
120
|
-
RewriteEngine on
|
|
121
|
-
|
|
122
|
-
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
|
|
123
|
-
RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
|
|
124
|
-
`
|
|
125
|
-
: ''
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
ErrorDocument 400 ${path === '/' ? '' : path}/400.html
|
|
129
|
-
ErrorDocument 404 ${path === '/' ? '' : path}/400.html
|
|
130
|
-
ErrorDocument 500 ${path === '/' ? '' : path}/500.html
|
|
131
|
-
ErrorDocument 502 ${path === '/' ? '' : path}/500.html
|
|
132
|
-
ErrorDocument 503 ${path === '/' ? '' : path}/500.html
|
|
133
|
-
ErrorDocument 504 ${path === '/' ? '' : path}/500.html
|
|
134
|
-
|
|
135
|
-
</VirtualHost>
|
|
136
|
-
|
|
137
|
-
`);
|
|
138
|
-
// ERR too many redirects:
|
|
139
|
-
// Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
|
|
140
|
-
// Check: wp-config.php
|
|
141
|
-
// if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
|
142
|
-
// $_SERVER['HTTPS'] = 'on';
|
|
143
|
-
// }
|
|
144
|
-
// For plugins:
|
|
145
|
-
// define( 'FS_METHOD', 'direct' );
|
|
146
|
-
|
|
147
|
-
// ErrorDocument 404 /custom_404.html
|
|
148
|
-
// ErrorDocument 500 /custom_50x.html
|
|
149
|
-
// ErrorDocument 502 /custom_50x.html
|
|
150
|
-
// ErrorDocument 503 /custom_50x.html
|
|
151
|
-
// ErrorDocument 504 /custom_50x.html
|
|
152
|
-
|
|
153
|
-
// Respond When Error Pages are Directly Requested
|
|
154
|
-
|
|
155
|
-
// <Files "custom_404.html">
|
|
156
|
-
// <If "-z %{ENV:REDIRECT_STATUS}">
|
|
157
|
-
// RedirectMatch 404 ^/custom_404.html$
|
|
158
|
-
// </If>
|
|
159
|
-
// </Files>
|
|
160
|
-
|
|
161
|
-
// <Files "custom_50x.html">
|
|
162
|
-
// <If "-z %{ENV:REDIRECT_STATUS}">
|
|
163
|
-
// RedirectMatch 404 ^/custom_50x.html$
|
|
164
|
-
// </If>
|
|
165
|
-
// </Files>
|
|
166
|
-
|
|
167
|
-
// Add www or https with htaccess rewrite
|
|
168
|
-
|
|
169
|
-
// Options +FollowSymLinks
|
|
170
|
-
// RewriteEngine On
|
|
171
|
-
// RewriteCond %{HTTP_HOST} ^ejemplo.com [NC]
|
|
172
|
-
// RewriteRule ^(.*)$ http://ejemplo.com/$1 [R=301,L]
|
|
173
|
-
|
|
174
|
-
// Redirect http to https with htaccess rewrite
|
|
175
|
-
|
|
176
|
-
// RewriteEngine On
|
|
177
|
-
// RewriteCond %{SERVER_PORT} 80
|
|
178
|
-
// RewriteRule ^(.*)$ https://www.ejemplo.com/$1 [R,L]
|
|
179
|
-
|
|
180
|
-
// Redirect to HTTPS with www subdomain
|
|
181
|
-
|
|
182
|
-
// RewriteEngine On
|
|
183
|
-
// RewriteCond %{HTTPS} off [OR]
|
|
184
|
-
// RewriteCond %{HTTP_HOST} ^www\. [NC]
|
|
185
|
-
// RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
|
|
186
|
-
// RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
|
|
187
|
-
|
|
188
|
-
await UnderpostStartUp.API.listenPortController(
|
|
189
|
-
UnderpostStartUp.API.listenServerFactory(),
|
|
190
|
-
port,
|
|
191
|
-
runningData,
|
|
192
|
-
);
|
|
193
|
-
break;
|
|
194
|
-
case 'xampp':
|
|
195
|
-
if (!Xampp.enabled()) continue;
|
|
196
|
-
if (!Xampp.ports.includes(port)) Xampp.ports.push(port);
|
|
197
|
-
if (currentPort === initPort) Xampp.removeRouter();
|
|
198
|
-
Xampp.appendRouter(`
|
|
199
|
-
|
|
200
|
-
Listen ${port}
|
|
201
|
-
|
|
202
|
-
<VirtualHost *:${port}>
|
|
203
|
-
DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
|
|
204
|
-
ServerName ${host}:${port}
|
|
205
|
-
|
|
206
|
-
<Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
|
|
207
|
-
Options Indexes FollowSymLinks MultiViews
|
|
208
|
-
AllowOverride All
|
|
209
|
-
Require all granted
|
|
210
|
-
</Directory>
|
|
211
|
-
|
|
212
|
-
${
|
|
213
|
-
redirect
|
|
214
|
-
? `
|
|
215
|
-
RewriteEngine on
|
|
216
|
-
|
|
217
|
-
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
|
|
218
|
-
RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
|
|
219
|
-
`
|
|
220
|
-
: ''
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
ErrorDocument 400 ${path === '/' ? '' : path}/400.html
|
|
224
|
-
ErrorDocument 404 ${path === '/' ? '' : path}/400.html
|
|
225
|
-
ErrorDocument 500 ${path === '/' ? '' : path}/500.html
|
|
226
|
-
ErrorDocument 502 ${path === '/' ? '' : path}/500.html
|
|
227
|
-
ErrorDocument 503 ${path === '/' ? '' : path}/500.html
|
|
228
|
-
ErrorDocument 504 ${path === '/' ? '' : path}/500.html
|
|
229
|
-
|
|
230
|
-
</VirtualHost>
|
|
231
|
-
|
|
232
|
-
`);
|
|
233
|
-
// ERR too many redirects:
|
|
234
|
-
// Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
|
|
235
|
-
// Check: wp-config.php
|
|
236
|
-
// if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
|
237
|
-
// $_SERVER['HTTPS'] = 'on';
|
|
238
|
-
// }
|
|
239
|
-
await UnderpostStartUp.API.listenPortController(
|
|
240
|
-
UnderpostStartUp.API.listenServerFactory(),
|
|
241
|
-
port,
|
|
242
|
-
runningData,
|
|
243
|
-
);
|
|
244
|
-
break;
|
|
245
94
|
case 'nodejs':
|
|
246
95
|
const app = express();
|
|
247
96
|
|
|
@@ -268,9 +117,6 @@ const buildRuntime = async () => {
|
|
|
268
117
|
// set logger
|
|
269
118
|
app.use(loggerMiddleware(import.meta));
|
|
270
119
|
|
|
271
|
-
// instance public static
|
|
272
|
-
app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
|
|
273
|
-
|
|
274
120
|
// js src compression
|
|
275
121
|
app.use(compression({ filter: shouldCompress }));
|
|
276
122
|
function shouldCompress(req, res) {
|
|
@@ -315,14 +161,15 @@ const buildRuntime = async () => {
|
|
|
315
161
|
return next();
|
|
316
162
|
});
|
|
317
163
|
|
|
318
|
-
//
|
|
319
|
-
|
|
164
|
+
// instance public static
|
|
165
|
+
app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
|
|
166
|
+
|
|
167
|
+
// security
|
|
168
|
+
applySecurity(app, {
|
|
320
169
|
origin: origins.concat(
|
|
321
170
|
apis && process.env.NODE_ENV === 'development' ? [`http://localhost:${currentPort + 2}`] : [],
|
|
322
171
|
),
|
|
323
|
-
};
|
|
324
|
-
// logger.info('originPayload', originPayload);
|
|
325
|
-
app.use(cors(originPayload));
|
|
172
|
+
});
|
|
326
173
|
|
|
327
174
|
if (redirect) {
|
|
328
175
|
app.use(function (req = express.Request, res = express.Response, next = express.NextFunction) {
|
|
@@ -342,145 +189,147 @@ const buildRuntime = async () => {
|
|
|
342
189
|
await UnderpostStartUp.API.listenPortController(app, port, runningData);
|
|
343
190
|
break;
|
|
344
191
|
}
|
|
192
|
+
// instance server
|
|
193
|
+
const server = createServer({}, app);
|
|
194
|
+
if (peer) currentPort++;
|
|
345
195
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const swaggerInstance =
|
|
351
|
-
(swaggerDoc) =>
|
|
352
|
-
(...args) =>
|
|
353
|
-
swaggerUi.setup(swaggerDoc)(...args);
|
|
196
|
+
if (!apiBaseHost) {
|
|
197
|
+
const swaggerJsonPath = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
|
|
198
|
+
if (fs.existsSync(swaggerJsonPath)) {
|
|
199
|
+
// logger.info('Build swagger serve', swaggerJsonPath);
|
|
354
200
|
|
|
355
|
-
|
|
201
|
+
const swaggerInstance =
|
|
202
|
+
(swaggerDoc) =>
|
|
203
|
+
(...args) =>
|
|
204
|
+
swaggerUi.setup(swaggerDoc)(...args);
|
|
356
205
|
|
|
357
|
-
|
|
358
|
-
}
|
|
206
|
+
const swaggerDoc = JSON.parse(fs.readFileSync(swaggerJsonPath, 'utf8'));
|
|
359
207
|
|
|
360
|
-
|
|
208
|
+
app.use(
|
|
209
|
+
`${path === '/' ? `/api-docs` : `${path}/api-docs`}`,
|
|
210
|
+
swaggerUi.serve,
|
|
211
|
+
swaggerInstance(swaggerDoc),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
361
214
|
|
|
362
|
-
|
|
363
|
-
if (valkey) await createValkeyConnection({ host, path }, valkey);
|
|
215
|
+
if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
|
|
364
216
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
await MailerProvider.load({
|
|
368
|
-
id: `${host}${path}`,
|
|
369
|
-
meta: `mailer-${host}${path}`,
|
|
370
|
-
host,
|
|
371
|
-
path,
|
|
372
|
-
...mailer,
|
|
373
|
-
templates: mailerSsrConf ? mailerSsrConf.mailer : {},
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
if (apis) {
|
|
377
|
-
const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
|
|
378
|
-
for (const api of apis)
|
|
379
|
-
await (async () => {
|
|
380
|
-
const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
|
|
381
|
-
const router = ApiRouter({ host, path, apiPath, mailer, db });
|
|
382
|
-
// router.use(cors({ origin: origins }));
|
|
383
|
-
// logger.info('Load api router', { host, path: apiPath, api });
|
|
384
|
-
app.use(`${apiPath}/${api}`, router);
|
|
385
|
-
})();
|
|
386
|
-
}
|
|
217
|
+
// valkey server
|
|
218
|
+
if (valkey) await createValkeyConnection({ host, path }, valkey);
|
|
387
219
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
version: Underpost.version,
|
|
399
|
-
},
|
|
400
|
-
renderApi: {
|
|
401
|
-
JSONweb,
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
|
|
405
|
-
const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
|
|
406
|
-
app.use(function (req, res, next) {
|
|
407
|
-
if (page404) return res.status(404).redirect(page404);
|
|
408
|
-
else {
|
|
409
|
-
res.set('Content-Type', 'text/html');
|
|
410
|
-
return res.status(404).send(defaultHtmlSrc404);
|
|
220
|
+
if (mailer) {
|
|
221
|
+
const mailerSsrConf = confSSR[getCapVariableName(client)];
|
|
222
|
+
await MailerProvider.load({
|
|
223
|
+
id: `${host}${path}`,
|
|
224
|
+
meta: `mailer-${host}${path}`,
|
|
225
|
+
host,
|
|
226
|
+
path,
|
|
227
|
+
...mailer,
|
|
228
|
+
templates: mailerSsrConf ? mailerSsrConf.mailer : {},
|
|
229
|
+
});
|
|
411
230
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
JSONweb,
|
|
425
|
-
},
|
|
426
|
-
});
|
|
427
|
-
const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
|
|
428
|
-
const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
|
|
429
|
-
app.use(function (err, req, res, next) {
|
|
430
|
-
logger.error(err, err.stack);
|
|
431
|
-
if (page500) return res.status(500).redirect(page500);
|
|
432
|
-
else {
|
|
433
|
-
res.set('Content-Type', 'text/html');
|
|
434
|
-
return res.status(500).send(defaultHtmlSrc500);
|
|
231
|
+
if (apis) {
|
|
232
|
+
const authMiddleware = authMiddlewareFactory({ host, path });
|
|
233
|
+
|
|
234
|
+
const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
|
|
235
|
+
for (const api of apis)
|
|
236
|
+
await (async () => {
|
|
237
|
+
const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
|
|
238
|
+
const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware, origins });
|
|
239
|
+
// router.use(cors({ origin: origins }));
|
|
240
|
+
// logger.info('Load api router', { host, path: apiPath, api });
|
|
241
|
+
app.use(`${apiPath}/${api}`, router);
|
|
242
|
+
})();
|
|
435
243
|
}
|
|
436
|
-
});
|
|
437
244
|
|
|
438
|
-
|
|
439
|
-
|
|
245
|
+
if (ws)
|
|
246
|
+
await (async () => {
|
|
247
|
+
const { createIoServer } = await import(`../ws/${ws}/${ws}.ws.server.js`);
|
|
248
|
+
// logger.info('Load socket.io ws router', { host, ws });
|
|
249
|
+
// start socket.io
|
|
250
|
+
const { options, meta } = await createIoServer(server, {
|
|
251
|
+
host,
|
|
252
|
+
path,
|
|
253
|
+
db,
|
|
254
|
+
port,
|
|
255
|
+
origins,
|
|
256
|
+
});
|
|
257
|
+
await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), port, {
|
|
258
|
+
runtime: 'nodejs',
|
|
259
|
+
client: null,
|
|
260
|
+
host,
|
|
261
|
+
path: options.path,
|
|
262
|
+
meta,
|
|
263
|
+
});
|
|
264
|
+
})();
|
|
440
265
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
266
|
+
if (peer) {
|
|
267
|
+
const peerPort = newInstance(currentPort);
|
|
268
|
+
const { options, meta, peerServer } = await createPeerServer({
|
|
269
|
+
port: peerPort,
|
|
270
|
+
devPort: port,
|
|
271
|
+
origins,
|
|
447
272
|
host,
|
|
448
273
|
path,
|
|
449
|
-
db,
|
|
450
|
-
port,
|
|
451
|
-
origins,
|
|
452
274
|
});
|
|
453
|
-
|
|
275
|
+
|
|
276
|
+
await UnderpostStartUp.API.listenPortController(peerServer, peerPort, {
|
|
454
277
|
runtime: 'nodejs',
|
|
455
278
|
client: null,
|
|
456
279
|
host,
|
|
457
280
|
path: options.path,
|
|
458
281
|
meta,
|
|
459
282
|
});
|
|
460
|
-
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
461
285
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
286
|
+
// load ssr
|
|
287
|
+
const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
|
|
288
|
+
for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
|
|
289
|
+
|
|
290
|
+
await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
291
|
+
|
|
292
|
+
break;
|
|
293
|
+
|
|
294
|
+
case 'lampp':
|
|
295
|
+
{
|
|
296
|
+
const { disabled } = await Lampp.createApp({
|
|
297
|
+
port,
|
|
469
298
|
host,
|
|
470
299
|
path,
|
|
300
|
+
directory,
|
|
301
|
+
rootHostPath,
|
|
302
|
+
redirect,
|
|
303
|
+
redirectTarget,
|
|
304
|
+
resetRouter: currentPort === initPort,
|
|
471
305
|
});
|
|
472
|
-
|
|
473
|
-
await UnderpostStartUp.API.listenPortController(
|
|
474
|
-
|
|
475
|
-
|
|
306
|
+
if (disabled) continue;
|
|
307
|
+
await UnderpostStartUp.API.listenPortController(
|
|
308
|
+
UnderpostStartUp.API.listenServerFactory(),
|
|
309
|
+
port,
|
|
310
|
+
runningData,
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
case 'xampp':
|
|
315
|
+
{
|
|
316
|
+
const { disabled } = await Xampp.createApp({
|
|
317
|
+
port,
|
|
476
318
|
host,
|
|
477
|
-
path
|
|
478
|
-
|
|
319
|
+
path,
|
|
320
|
+
directory,
|
|
321
|
+
rootHostPath,
|
|
322
|
+
redirect,
|
|
323
|
+
redirectTarget,
|
|
324
|
+
resetRouter: currentPort === initPort,
|
|
479
325
|
});
|
|
326
|
+
if (disabled) continue;
|
|
327
|
+
await UnderpostStartUp.API.listenPortController(
|
|
328
|
+
UnderpostStartUp.API.listenServerFactory(),
|
|
329
|
+
port,
|
|
330
|
+
runningData,
|
|
331
|
+
);
|
|
480
332
|
}
|
|
481
|
-
|
|
482
|
-
await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
483
|
-
|
|
484
333
|
break;
|
|
485
334
|
default:
|
|
486
335
|
break;
|
package/src/server/ssl.js
CHANGED
|
@@ -50,8 +50,7 @@ const buildSSL = async (host) => {
|
|
|
50
50
|
|
|
51
51
|
fs.writeFileSync(`./engine-private/ssl/${host}/_ca_bundle.crt`, ca, 'utf8');
|
|
52
52
|
fs.writeFileSync(`./engine-private/ssl/${host}/_ca_full_bundle.crt`, caFull, 'utf8');
|
|
53
|
-
|
|
54
|
-
// fs.removeSync(`${sslPath}/${folderHost}`);
|
|
53
|
+
|
|
55
54
|
return true;
|
|
56
55
|
}
|
|
57
56
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
import Underpost from '../index.js';
|
|
4
|
+
|
|
5
|
+
import { ssrFactory, JSONweb } from './client-formatted.js';
|
|
6
|
+
import { loggerFactory } from './logger.js';
|
|
7
|
+
import { getRootDirectory } from './process.js';
|
|
8
|
+
|
|
9
|
+
dotenv.config();
|
|
10
|
+
|
|
11
|
+
const logger = loggerFactory(import.meta);
|
|
12
|
+
|
|
13
|
+
const ssrMiddlewareFactory = async ({ app, directory, rootHostPath, path }) => {
|
|
14
|
+
const Render = await ssrFactory();
|
|
15
|
+
const ssrPath = path === '/' ? path : `${path}/`;
|
|
16
|
+
|
|
17
|
+
// Build default html src for 404 and 500
|
|
18
|
+
|
|
19
|
+
const defaultHtmlSrc404 = Render({
|
|
20
|
+
title: '404 Not Found',
|
|
21
|
+
ssrPath,
|
|
22
|
+
ssrHeadComponents: '',
|
|
23
|
+
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/404.js`))(),
|
|
24
|
+
renderPayload: {
|
|
25
|
+
apiBasePath: process.env.BASE_API,
|
|
26
|
+
version: Underpost.version,
|
|
27
|
+
},
|
|
28
|
+
renderApi: {
|
|
29
|
+
JSONweb,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
|
|
33
|
+
const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
|
|
34
|
+
|
|
35
|
+
const defaultHtmlSrc500 = Render({
|
|
36
|
+
title: '500 Server Error',
|
|
37
|
+
ssrPath,
|
|
38
|
+
ssrHeadComponents: '',
|
|
39
|
+
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/500.js`))(),
|
|
40
|
+
renderPayload: {
|
|
41
|
+
apiBasePath: process.env.BASE_API,
|
|
42
|
+
version: Underpost.version,
|
|
43
|
+
},
|
|
44
|
+
renderApi: {
|
|
45
|
+
JSONweb,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
|
|
49
|
+
const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
|
|
50
|
+
|
|
51
|
+
const sanitizeHtml = (res, req, html) => {
|
|
52
|
+
const nonce = res.locals.nonce;
|
|
53
|
+
|
|
54
|
+
return html
|
|
55
|
+
.replace(/<script(?=\s|>)/gi, `<script nonce="${nonce}"`)
|
|
56
|
+
.replace(/<style(?=\s|>)/gi, `<style nonce="${nonce}"`);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
error500: function (err, req, res, next) {
|
|
61
|
+
logger.error(err, err.stack);
|
|
62
|
+
if (page500) return res.status(500).redirect(page500);
|
|
63
|
+
else {
|
|
64
|
+
res.set('Content-Type', 'text/html');
|
|
65
|
+
return res.status(500).send(sanitizeHtml(res, req, defaultHtmlSrc500));
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
error400: function (req, res, next) {
|
|
69
|
+
// if /<path>/home redirect to /<path>
|
|
70
|
+
const homeRedirectPath = `${path === '/' ? '' : path}/home`;
|
|
71
|
+
if (req.url.startsWith(homeRedirectPath)) {
|
|
72
|
+
const redirectUrl = req.url.replace('/home', '');
|
|
73
|
+
return res.redirect(redirectUrl.startsWith('/') ? redirectUrl : `/${redirectUrl}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (page404) return res.status(404).redirect(page404);
|
|
77
|
+
else {
|
|
78
|
+
res.set('Content-Type', 'text/html');
|
|
79
|
+
return res.status(404).send(sanitizeHtml(res, req, defaultHtmlSrc404));
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export { ssrMiddlewareFactory };
|
package/src/server/start.js
CHANGED
|
@@ -86,9 +86,9 @@ class UnderpostStartUp {
|
|
|
86
86
|
async build(deployId = 'dd-default', env = 'development') {
|
|
87
87
|
const buildBasePath = `/home/dd`;
|
|
88
88
|
const repoName = `engine-${deployId.split('-')[1]}`;
|
|
89
|
-
shellExec(`cd ${buildBasePath} && underpost clone
|
|
89
|
+
shellExec(`cd ${buildBasePath} && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}`);
|
|
90
90
|
shellExec(`cd ${buildBasePath} && sudo mv ./${repoName} ./engine`);
|
|
91
|
-
shellExec(`cd ${buildBasePath}/engine && underpost clone
|
|
91
|
+
shellExec(`cd ${buildBasePath}/engine && underpost clone ${process.env.GITHUB_USERNAME}/${repoName}-private`);
|
|
92
92
|
shellExec(`cd ${buildBasePath}/engine && sudo mv ./${repoName}-private ./engine-private`);
|
|
93
93
|
shellCd(`${buildBasePath}/engine`);
|
|
94
94
|
shellExec(`npm install`);
|
package/src/server/valkey.js
CHANGED
|
@@ -148,7 +148,7 @@ const updateValkeyObject = async (options = { host: '', path: '' }, key = '', pa
|
|
|
148
148
|
return await setValkeyObject(options, key, { ...base, ...payload });
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
-
const valkeyObjectFactory = async (options = { host: 'localhost', object: {} }, model = '') => {
|
|
151
|
+
const valkeyObjectFactory = async (options = { host: 'localhost', path: '', object: {} }, model = '') => {
|
|
152
152
|
const idoDate = new Date().toISOString();
|
|
153
153
|
options.object = options.object || {};
|
|
154
154
|
const { object } = options;
|
|
@@ -173,6 +173,7 @@ const valkeyObjectFactory = async (options = { host: 'localhost', object: {} },
|
|
|
173
173
|
emailConfirmed: false,
|
|
174
174
|
recoverTimeOut: null,
|
|
175
175
|
lastLoginDate: null,
|
|
176
|
+
activeSessions: [],
|
|
176
177
|
};
|
|
177
178
|
}
|
|
178
179
|
default:
|