underpost 2.8.86 → 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 +39 -2
- package/.env.production +42 -2
- package/.env.test +39 -2
- 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 +76 -2
- package/bin/build.js +5 -0
- package/bin/deploy.js +93 -27
- package/bin/file.js +8 -4
- package/bin/util.js +1 -56
- package/cli.md +16 -5
- package/conf.js +33 -7
- 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/manifests/deployment/mongo-express/deployment.yaml +12 -12
- package/manifests/maas/nvim.sh +91 -0
- package/package.json +8 -15
- 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/file/file.service.js +28 -8
- 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 +40 -8
- package/src/api/user/user.service.js +86 -35
- package/src/cli/baremetal.js +33 -3
- package/src/cli/cloud-init.js +11 -0
- package/src/cli/cluster.js +4 -23
- package/src/cli/cron.js +0 -1
- package/src/cli/db.js +0 -19
- package/src/cli/deploy.js +67 -52
- package/src/cli/fs.js +1 -0
- package/src/cli/index.js +9 -1
- package/src/cli/lxd.js +7 -0
- package/src/cli/repository.js +44 -6
- package/src/cli/run.js +56 -9
- 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 +18 -1
- package/src/client/components/core/Docs.js +5 -5
- package/src/client/components/core/FileExplorer.js +3 -3
- package/src/client/components/core/FullScreen.js +19 -28
- package/src/client/components/core/Input.js +22 -16
- 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 +102 -87
- package/src/client/components/core/ObjectLayerEngine.js +229 -4
- package/src/client/components/core/ObjectLayerEngineModal.js +442 -0
- 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/ToggleSwitch.js +15 -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/public/default/assets/mailer/api-user-default-avatar.png +0 -0
- 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/client-build-docs.js +1 -1
- package/src/server/client-build.js +4 -12
- package/src/server/client-icons.js +6 -78
- package/src/server/conf.js +144 -141
- package/src/server/process.js +2 -1
- package/src/server/proxy.js +1 -1
- package/src/server/runtime.js +136 -288
- package/src/server/ssl.js +1 -2
- package/src/server/ssr.js +85 -0
- package/src/server/start.js +4 -4
- package/src/server/valkey.js +2 -1
- package/test/api.test.js +3 -2
- package/bin/cyberia0.js +0 -78
package/src/server/runtime.js
CHANGED
|
@@ -1,34 +1,31 @@
|
|
|
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 { JSONweb, ssrFactory } from './client-formatted.js';
|
|
23
|
-
import Underpost from '../index.js';
|
|
17
|
+
import { Xampp } from '../runtime/xampp/Xampp.js';
|
|
24
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';
|
|
25
22
|
|
|
26
23
|
dotenv.config();
|
|
27
24
|
|
|
28
25
|
const logger = loggerFactory(import.meta);
|
|
29
26
|
|
|
30
27
|
const buildRuntime = async () => {
|
|
31
|
-
const deployId =
|
|
28
|
+
const deployId = process.env.DEPLOY_ID;
|
|
32
29
|
|
|
33
30
|
const collectDefaultMetrics = promClient.collectDefaultMetrics;
|
|
34
31
|
collectDefaultMetrics();
|
|
@@ -39,8 +36,6 @@ const buildRuntime = async () => {
|
|
|
39
36
|
labelNames: ['instance', 'method', 'status_code'],
|
|
40
37
|
};
|
|
41
38
|
|
|
42
|
-
// logger.info('promCounterOption', promCounterOption);
|
|
43
|
-
|
|
44
39
|
const requestCounter = new promClient.Counter(promCounterOption);
|
|
45
40
|
const initPort = parseInt(process.env.PORT) + 1;
|
|
46
41
|
let currentPort = initPort;
|
|
@@ -48,9 +43,8 @@ const buildRuntime = async () => {
|
|
|
48
43
|
const confSSR = JSON.parse(fs.readFileSync(`./conf/conf.ssr.json`, 'utf8'));
|
|
49
44
|
const singleReplicaHosts = [];
|
|
50
45
|
for (const host of Object.keys(confServer)) {
|
|
51
|
-
if (singleReplicaHosts.length > 0
|
|
46
|
+
if (singleReplicaHosts.length > 0)
|
|
52
47
|
currentPort += singleReplicaHosts.reduce((accumulator, currentValue) => accumulator + currentValue.replicas, 0);
|
|
53
|
-
}
|
|
54
48
|
const rootHostPath = `/public/${host}`;
|
|
55
49
|
for (const path of Object.keys(confServer[host])) {
|
|
56
50
|
confServer[host][path].port = newInstance(currentPort);
|
|
@@ -69,9 +63,17 @@ const buildRuntime = async () => {
|
|
|
69
63
|
singleReplica,
|
|
70
64
|
replicas,
|
|
71
65
|
valkey,
|
|
66
|
+
apiBaseHost,
|
|
72
67
|
} = confServer[host][path];
|
|
73
68
|
|
|
74
|
-
|
|
69
|
+
const { redirectTarget, singleReplicaHost } = await getInstanceContext({
|
|
70
|
+
redirect,
|
|
71
|
+
singleReplicaHosts,
|
|
72
|
+
singleReplica,
|
|
73
|
+
replicas,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (singleReplicaHost) {
|
|
75
77
|
singleReplicaHosts.push({
|
|
76
78
|
host,
|
|
77
79
|
replicas: replicas.length,
|
|
@@ -88,161 +90,7 @@ const buildRuntime = async () => {
|
|
|
88
90
|
apis,
|
|
89
91
|
};
|
|
90
92
|
|
|
91
|
-
const redirectTarget = redirect
|
|
92
|
-
? redirect[redirect.length - 1] === '/'
|
|
93
|
-
? redirect.slice(0, -1)
|
|
94
|
-
: redirect
|
|
95
|
-
: undefined;
|
|
96
|
-
|
|
97
|
-
// if (redirect) logger.info('redirect', new URL(redirect));
|
|
98
|
-
|
|
99
93
|
switch (runtime) {
|
|
100
|
-
case 'lampp':
|
|
101
|
-
if (!Lampp.enabled()) continue;
|
|
102
|
-
if (!Lampp.ports.includes(port)) Lampp.ports.push(port);
|
|
103
|
-
if (currentPort === initPort) Lampp.removeRouter();
|
|
104
|
-
Lampp.appendRouter(`
|
|
105
|
-
|
|
106
|
-
Listen ${port}
|
|
107
|
-
|
|
108
|
-
<VirtualHost *:${port}>
|
|
109
|
-
DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
|
|
110
|
-
ServerName ${host}:${port}
|
|
111
|
-
|
|
112
|
-
<Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
|
|
113
|
-
Options Indexes FollowSymLinks MultiViews
|
|
114
|
-
AllowOverride All
|
|
115
|
-
Require all granted
|
|
116
|
-
</Directory>
|
|
117
|
-
|
|
118
|
-
${
|
|
119
|
-
redirect
|
|
120
|
-
? `
|
|
121
|
-
RewriteEngine on
|
|
122
|
-
|
|
123
|
-
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
|
|
124
|
-
RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
|
|
125
|
-
`
|
|
126
|
-
: ''
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
ErrorDocument 400 ${path === '/' ? '' : path}/400.html
|
|
130
|
-
ErrorDocument 404 ${path === '/' ? '' : path}/400.html
|
|
131
|
-
ErrorDocument 500 ${path === '/' ? '' : path}/500.html
|
|
132
|
-
ErrorDocument 502 ${path === '/' ? '' : path}/500.html
|
|
133
|
-
ErrorDocument 503 ${path === '/' ? '' : path}/500.html
|
|
134
|
-
ErrorDocument 504 ${path === '/' ? '' : path}/500.html
|
|
135
|
-
|
|
136
|
-
</VirtualHost>
|
|
137
|
-
|
|
138
|
-
`);
|
|
139
|
-
// ERR too many redirects:
|
|
140
|
-
// Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
|
|
141
|
-
// Check: wp-config.php
|
|
142
|
-
// if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
|
143
|
-
// $_SERVER['HTTPS'] = 'on';
|
|
144
|
-
// }
|
|
145
|
-
// For plugins:
|
|
146
|
-
// define( 'FS_METHOD', 'direct' );
|
|
147
|
-
|
|
148
|
-
// ErrorDocument 404 /custom_404.html
|
|
149
|
-
// ErrorDocument 500 /custom_50x.html
|
|
150
|
-
// ErrorDocument 502 /custom_50x.html
|
|
151
|
-
// ErrorDocument 503 /custom_50x.html
|
|
152
|
-
// ErrorDocument 504 /custom_50x.html
|
|
153
|
-
|
|
154
|
-
// Respond When Error Pages are Directly Requested
|
|
155
|
-
|
|
156
|
-
// <Files "custom_404.html">
|
|
157
|
-
// <If "-z %{ENV:REDIRECT_STATUS}">
|
|
158
|
-
// RedirectMatch 404 ^/custom_404.html$
|
|
159
|
-
// </If>
|
|
160
|
-
// </Files>
|
|
161
|
-
|
|
162
|
-
// <Files "custom_50x.html">
|
|
163
|
-
// <If "-z %{ENV:REDIRECT_STATUS}">
|
|
164
|
-
// RedirectMatch 404 ^/custom_50x.html$
|
|
165
|
-
// </If>
|
|
166
|
-
// </Files>
|
|
167
|
-
|
|
168
|
-
// Add www or https with htaccess rewrite
|
|
169
|
-
|
|
170
|
-
// Options +FollowSymLinks
|
|
171
|
-
// RewriteEngine On
|
|
172
|
-
// RewriteCond %{HTTP_HOST} ^ejemplo.com [NC]
|
|
173
|
-
// RewriteRule ^(.*)$ http://ejemplo.com/$1 [R=301,L]
|
|
174
|
-
|
|
175
|
-
// Redirect http to https with htaccess rewrite
|
|
176
|
-
|
|
177
|
-
// RewriteEngine On
|
|
178
|
-
// RewriteCond %{SERVER_PORT} 80
|
|
179
|
-
// RewriteRule ^(.*)$ https://www.ejemplo.com/$1 [R,L]
|
|
180
|
-
|
|
181
|
-
// Redirect to HTTPS with www subdomain
|
|
182
|
-
|
|
183
|
-
// RewriteEngine On
|
|
184
|
-
// RewriteCond %{HTTPS} off [OR]
|
|
185
|
-
// RewriteCond %{HTTP_HOST} ^www\. [NC]
|
|
186
|
-
// RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
|
|
187
|
-
// RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
|
|
188
|
-
|
|
189
|
-
await UnderpostStartUp.API.listenPortController(
|
|
190
|
-
UnderpostStartUp.API.listenServerFactory(),
|
|
191
|
-
port,
|
|
192
|
-
runningData,
|
|
193
|
-
);
|
|
194
|
-
break;
|
|
195
|
-
case 'xampp':
|
|
196
|
-
if (!Xampp.enabled()) continue;
|
|
197
|
-
if (!Xampp.ports.includes(port)) Xampp.ports.push(port);
|
|
198
|
-
if (currentPort === initPort) Xampp.removeRouter();
|
|
199
|
-
Xampp.appendRouter(`
|
|
200
|
-
|
|
201
|
-
Listen ${port}
|
|
202
|
-
|
|
203
|
-
<VirtualHost *:${port}>
|
|
204
|
-
DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
|
|
205
|
-
ServerName ${host}:${port}
|
|
206
|
-
|
|
207
|
-
<Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
|
|
208
|
-
Options Indexes FollowSymLinks MultiViews
|
|
209
|
-
AllowOverride All
|
|
210
|
-
Require all granted
|
|
211
|
-
</Directory>
|
|
212
|
-
|
|
213
|
-
${
|
|
214
|
-
redirect
|
|
215
|
-
? `
|
|
216
|
-
RewriteEngine on
|
|
217
|
-
|
|
218
|
-
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
|
|
219
|
-
RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
|
|
220
|
-
`
|
|
221
|
-
: ''
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
ErrorDocument 400 ${path === '/' ? '' : path}/400.html
|
|
225
|
-
ErrorDocument 404 ${path === '/' ? '' : path}/400.html
|
|
226
|
-
ErrorDocument 500 ${path === '/' ? '' : path}/500.html
|
|
227
|
-
ErrorDocument 502 ${path === '/' ? '' : path}/500.html
|
|
228
|
-
ErrorDocument 503 ${path === '/' ? '' : path}/500.html
|
|
229
|
-
ErrorDocument 504 ${path === '/' ? '' : path}/500.html
|
|
230
|
-
|
|
231
|
-
</VirtualHost>
|
|
232
|
-
|
|
233
|
-
`);
|
|
234
|
-
// ERR too many redirects:
|
|
235
|
-
// Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
|
|
236
|
-
// Check: wp-config.php
|
|
237
|
-
// if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
|
238
|
-
// $_SERVER['HTTPS'] = 'on';
|
|
239
|
-
// }
|
|
240
|
-
await UnderpostStartUp.API.listenPortController(
|
|
241
|
-
UnderpostStartUp.API.listenServerFactory(),
|
|
242
|
-
port,
|
|
243
|
-
runningData,
|
|
244
|
-
);
|
|
245
|
-
break;
|
|
246
94
|
case 'nodejs':
|
|
247
95
|
const app = express();
|
|
248
96
|
|
|
@@ -269,9 +117,6 @@ const buildRuntime = async () => {
|
|
|
269
117
|
// set logger
|
|
270
118
|
app.use(loggerMiddleware(import.meta));
|
|
271
119
|
|
|
272
|
-
// instance public static
|
|
273
|
-
app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
|
|
274
|
-
|
|
275
120
|
// js src compression
|
|
276
121
|
app.use(compression({ filter: shouldCompress }));
|
|
277
122
|
function shouldCompress(req, res) {
|
|
@@ -316,14 +161,15 @@ const buildRuntime = async () => {
|
|
|
316
161
|
return next();
|
|
317
162
|
});
|
|
318
163
|
|
|
319
|
-
//
|
|
320
|
-
|
|
164
|
+
// instance public static
|
|
165
|
+
app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
|
|
166
|
+
|
|
167
|
+
// security
|
|
168
|
+
applySecurity(app, {
|
|
321
169
|
origin: origins.concat(
|
|
322
170
|
apis && process.env.NODE_ENV === 'development' ? [`http://localhost:${currentPort + 2}`] : [],
|
|
323
171
|
),
|
|
324
|
-
};
|
|
325
|
-
// logger.info('originPayload', originPayload);
|
|
326
|
-
app.use(cors(originPayload));
|
|
172
|
+
});
|
|
327
173
|
|
|
328
174
|
if (redirect) {
|
|
329
175
|
app.use(function (req = express.Request, res = express.Response, next = express.NextFunction) {
|
|
@@ -343,145 +189,147 @@ const buildRuntime = async () => {
|
|
|
343
189
|
await UnderpostStartUp.API.listenPortController(app, port, runningData);
|
|
344
190
|
break;
|
|
345
191
|
}
|
|
192
|
+
// instance server
|
|
193
|
+
const server = createServer({}, app);
|
|
194
|
+
if (peer) currentPort++;
|
|
346
195
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const swaggerInstance =
|
|
352
|
-
(swaggerDoc) =>
|
|
353
|
-
(...args) =>
|
|
354
|
-
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);
|
|
355
200
|
|
|
356
|
-
|
|
201
|
+
const swaggerInstance =
|
|
202
|
+
(swaggerDoc) =>
|
|
203
|
+
(...args) =>
|
|
204
|
+
swaggerUi.setup(swaggerDoc)(...args);
|
|
357
205
|
|
|
358
|
-
|
|
359
|
-
}
|
|
206
|
+
const swaggerDoc = JSON.parse(fs.readFileSync(swaggerJsonPath, 'utf8'));
|
|
360
207
|
|
|
361
|
-
|
|
208
|
+
app.use(
|
|
209
|
+
`${path === '/' ? `/api-docs` : `${path}/api-docs`}`,
|
|
210
|
+
swaggerUi.serve,
|
|
211
|
+
swaggerInstance(swaggerDoc),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
362
214
|
|
|
363
|
-
|
|
364
|
-
if (valkey) await createValkeyConnection({ host, path }, valkey);
|
|
215
|
+
if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
|
|
365
216
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
await MailerProvider.load({
|
|
369
|
-
id: `${host}${path}`,
|
|
370
|
-
meta: `mailer-${host}${path}`,
|
|
371
|
-
host,
|
|
372
|
-
path,
|
|
373
|
-
...mailer,
|
|
374
|
-
templates: mailerSsrConf ? mailerSsrConf.mailer : {},
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
if (apis) {
|
|
378
|
-
const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
|
|
379
|
-
for (const api of apis)
|
|
380
|
-
await (async () => {
|
|
381
|
-
const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
|
|
382
|
-
const router = ApiRouter({ host, path, apiPath, mailer, db });
|
|
383
|
-
// router.use(cors({ origin: origins }));
|
|
384
|
-
// logger.info('Load api router', { host, path: apiPath, api });
|
|
385
|
-
app.use(`${apiPath}/${api}`, router);
|
|
386
|
-
})();
|
|
387
|
-
}
|
|
217
|
+
// valkey server
|
|
218
|
+
if (valkey) await createValkeyConnection({ host, path }, valkey);
|
|
388
219
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
version: Underpost.version,
|
|
400
|
-
},
|
|
401
|
-
renderApi: {
|
|
402
|
-
JSONweb,
|
|
403
|
-
},
|
|
404
|
-
});
|
|
405
|
-
const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
|
|
406
|
-
const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
|
|
407
|
-
app.use(function (req, res, next) {
|
|
408
|
-
if (page404) return res.status(404).redirect(page404);
|
|
409
|
-
else {
|
|
410
|
-
res.set('Content-Type', 'text/html');
|
|
411
|
-
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
|
+
});
|
|
412
230
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
JSONweb,
|
|
426
|
-
},
|
|
427
|
-
});
|
|
428
|
-
const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
|
|
429
|
-
const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
|
|
430
|
-
app.use(function (err, req, res, next) {
|
|
431
|
-
logger.error(err, err.stack);
|
|
432
|
-
if (page500) return res.status(500).redirect(page500);
|
|
433
|
-
else {
|
|
434
|
-
res.set('Content-Type', 'text/html');
|
|
435
|
-
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
|
+
})();
|
|
436
243
|
}
|
|
437
|
-
});
|
|
438
244
|
|
|
439
|
-
|
|
440
|
-
|
|
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
|
+
})();
|
|
441
265
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
266
|
+
if (peer) {
|
|
267
|
+
const peerPort = newInstance(currentPort);
|
|
268
|
+
const { options, meta, peerServer } = await createPeerServer({
|
|
269
|
+
port: peerPort,
|
|
270
|
+
devPort: port,
|
|
271
|
+
origins,
|
|
448
272
|
host,
|
|
449
273
|
path,
|
|
450
|
-
db,
|
|
451
|
-
port,
|
|
452
|
-
origins,
|
|
453
274
|
});
|
|
454
|
-
|
|
275
|
+
|
|
276
|
+
await UnderpostStartUp.API.listenPortController(peerServer, peerPort, {
|
|
455
277
|
runtime: 'nodejs',
|
|
456
278
|
client: null,
|
|
457
279
|
host,
|
|
458
280
|
path: options.path,
|
|
459
281
|
meta,
|
|
460
282
|
});
|
|
461
|
-
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
462
285
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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,
|
|
470
298
|
host,
|
|
471
299
|
path,
|
|
300
|
+
directory,
|
|
301
|
+
rootHostPath,
|
|
302
|
+
redirect,
|
|
303
|
+
redirectTarget,
|
|
304
|
+
resetRouter: currentPort === initPort,
|
|
472
305
|
});
|
|
473
|
-
|
|
474
|
-
await UnderpostStartUp.API.listenPortController(
|
|
475
|
-
|
|
476
|
-
|
|
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,
|
|
477
318
|
host,
|
|
478
|
-
path
|
|
479
|
-
|
|
319
|
+
path,
|
|
320
|
+
directory,
|
|
321
|
+
rootHostPath,
|
|
322
|
+
redirect,
|
|
323
|
+
redirectTarget,
|
|
324
|
+
resetRouter: currentPort === initPort,
|
|
480
325
|
});
|
|
326
|
+
if (disabled) continue;
|
|
327
|
+
await UnderpostStartUp.API.listenPortController(
|
|
328
|
+
UnderpostStartUp.API.listenServerFactory(),
|
|
329
|
+
port,
|
|
330
|
+
runningData,
|
|
331
|
+
);
|
|
481
332
|
}
|
|
482
|
-
|
|
483
|
-
await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
484
|
-
|
|
485
333
|
break;
|
|
486
334
|
default:
|
|
487
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`);
|
|
@@ -107,12 +107,12 @@ class UnderpostStartUp {
|
|
|
107
107
|
for (const replica of replicas) {
|
|
108
108
|
if (!replica.match(deployId)) continue;
|
|
109
109
|
shellExec(`node bin/deploy conf ${replica} ${env}`);
|
|
110
|
-
shellExec(`npm ${runCmd}
|
|
110
|
+
shellExec(`npm ${runCmd} ${replica}`, { async: true });
|
|
111
111
|
await awaitDeployMonitor(true);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
shellExec(`node bin/deploy conf ${deployId} ${env}`);
|
|
115
|
-
shellExec(`npm ${runCmd}
|
|
115
|
+
shellExec(`npm ${runCmd} ${deployId}`, { async: true });
|
|
116
116
|
await awaitDeployMonitor(true);
|
|
117
117
|
UnderpostRootEnv.API.set('container-status', `${deployId}-${env}-running-deployment`);
|
|
118
118
|
},
|
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:
|