underpost 2.8.872 → 2.8.873
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 +2 -1
- package/.env.production +2 -1
- package/.env.test +2 -1
- 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 +1 -1
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +2 -4
- package/README.md +22 -2
- package/bin/build.js +4 -0
- package/bin/deploy.js +4 -0
- package/cli.md +3 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +138 -0
- package/manifests/deployment/dd-test-development/proxy.yaml +26 -0
- package/package.json +5 -1
- 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/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 +6 -3
- package/src/api/user/user.service.js +80 -32
- package/src/cli/baremetal.js +33 -3
- package/src/cli/cloud-init.js +11 -0
- package/src/cli/deploy.js +5 -2
- package/src/cli/index.js +1 -0
- package/src/cli/lxd.js +7 -0
- package/src/cli/run.js +17 -5
- package/src/cli/ssh.js +20 -6
- package/src/client/components/core/AgGrid.js +28 -6
- package/src/client/components/core/Auth.js +98 -55
- package/src/client/components/core/LogIn.js +16 -23
- package/src/client/components/core/LogOut.js +5 -1
- package/src/client/components/core/Pagination.js +202 -9
- package/src/client/components/core/Router.js +30 -3
- package/src/client/components/core/SignUp.js +1 -2
- package/src/client/components/default/LogInDefault.js +0 -6
- package/src/client/components/default/LogOutDefault.js +0 -16
- package/src/client/services/core/core.service.js +5 -1
- package/src/client/services/default/default.management.js +115 -18
- package/src/client/services/default/default.service.js +9 -4
- package/src/client/services/user/user.management.js +6 -0
- package/src/client/services/user/user.service.js +11 -4
- 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 +518 -155
- package/src/server/conf.js +19 -1
- package/src/server/runtime.js +62 -228
- package/src/server/ssr.js +85 -0
- package/src/server/valkey.js +2 -1
package/src/server/conf.js
CHANGED
|
@@ -557,7 +557,7 @@ const buildPortProxyRouter = (port, proxyRouter) => {
|
|
|
557
557
|
// build router
|
|
558
558
|
Object.keys(hosts).map((hostKey) => {
|
|
559
559
|
let { host, path, target, proxy, peer } = hosts[hostKey];
|
|
560
|
-
if (process.env.NODE_ENV === 'development') host = `localhost`;
|
|
560
|
+
if (process.env.NODE_ENV === 'development' && process.argv.includes('localhost')) host = `localhost`;
|
|
561
561
|
|
|
562
562
|
if (!proxy.includes(port)) {
|
|
563
563
|
logger.warn('Proxy port not set on conf', { port, host, path, proxy, target });
|
|
@@ -926,6 +926,23 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
|
|
|
926
926
|
);
|
|
927
927
|
};
|
|
928
928
|
|
|
929
|
+
const getInstanceContext = async (options = { singleReplica, replicas, redirect: '' }) => {
|
|
930
|
+
const { singleReplica, replicas, redirect } = options;
|
|
931
|
+
|
|
932
|
+
if (singleReplica && replicas && replicas.length > 0)
|
|
933
|
+
return {
|
|
934
|
+
singleReplicaHost: true,
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const redirectTarget = redirect
|
|
938
|
+
? redirect[redirect.length - 1] === '/'
|
|
939
|
+
? redirect.slice(0, -1)
|
|
940
|
+
: redirect
|
|
941
|
+
: undefined;
|
|
942
|
+
|
|
943
|
+
return { redirectTarget };
|
|
944
|
+
};
|
|
945
|
+
|
|
929
946
|
export {
|
|
930
947
|
Cmd,
|
|
931
948
|
Config,
|
|
@@ -958,4 +975,5 @@ export {
|
|
|
958
975
|
awaitDeployMonitor,
|
|
959
976
|
rebuildConfFactory,
|
|
960
977
|
buildCliDoc,
|
|
978
|
+
getInstanceContext,
|
|
961
979
|
};
|
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);
|
|
@@ -70,7 +65,14 @@ const buildRuntime = async () => {
|
|
|
70
65
|
valkey,
|
|
71
66
|
} = confServer[host][path];
|
|
72
67
|
|
|
73
|
-
|
|
68
|
+
const { redirectTarget, singleReplicaHost } = await getInstanceContext({
|
|
69
|
+
redirect,
|
|
70
|
+
singleReplicaHosts,
|
|
71
|
+
singleReplica,
|
|
72
|
+
replicas,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (singleReplicaHost) {
|
|
74
76
|
singleReplicaHosts.push({
|
|
75
77
|
host,
|
|
76
78
|
replicas: replicas.length,
|
|
@@ -87,161 +89,7 @@ const buildRuntime = async () => {
|
|
|
87
89
|
apis,
|
|
88
90
|
};
|
|
89
91
|
|
|
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
92
|
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
93
|
case 'nodejs':
|
|
246
94
|
const app = express();
|
|
247
95
|
|
|
@@ -315,14 +163,12 @@ const buildRuntime = async () => {
|
|
|
315
163
|
return next();
|
|
316
164
|
});
|
|
317
165
|
|
|
318
|
-
//
|
|
319
|
-
|
|
166
|
+
// security
|
|
167
|
+
applySecurity(app, {
|
|
320
168
|
origin: origins.concat(
|
|
321
169
|
apis && process.env.NODE_ENV === 'development' ? [`http://localhost:${currentPort + 2}`] : [],
|
|
322
170
|
),
|
|
323
|
-
};
|
|
324
|
-
// logger.info('originPayload', originPayload);
|
|
325
|
-
app.use(cors(originPayload));
|
|
171
|
+
});
|
|
326
172
|
|
|
327
173
|
if (redirect) {
|
|
328
174
|
app.use(function (req = express.Request, res = express.Response, next = express.NextFunction) {
|
|
@@ -374,73 +220,22 @@ const buildRuntime = async () => {
|
|
|
374
220
|
});
|
|
375
221
|
}
|
|
376
222
|
if (apis) {
|
|
223
|
+
const authMiddleware = authMiddlewareFactory({ host, path });
|
|
224
|
+
|
|
377
225
|
const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
|
|
378
226
|
for (const api of apis)
|
|
379
227
|
await (async () => {
|
|
380
228
|
const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
|
|
381
|
-
const router = ApiRouter({ host, path, apiPath, mailer, db });
|
|
229
|
+
const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware });
|
|
382
230
|
// router.use(cors({ origin: origins }));
|
|
383
231
|
// logger.info('Load api router', { host, path: apiPath, api });
|
|
384
232
|
app.use(`${apiPath}/${api}`, router);
|
|
385
233
|
})();
|
|
386
234
|
}
|
|
387
235
|
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
const defaultHtmlSrc404 = Render({
|
|
392
|
-
title: '404 Not Found',
|
|
393
|
-
ssrPath,
|
|
394
|
-
ssrHeadComponents: '',
|
|
395
|
-
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/404.js`))(),
|
|
396
|
-
renderPayload: {
|
|
397
|
-
apiBasePath: process.env.BASE_API,
|
|
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 /<path>/home redirect to /<path>
|
|
408
|
-
const homeRedirectPath = `${path === '/' ? '' : path}/home`;
|
|
409
|
-
if (req.url.startsWith(homeRedirectPath)) {
|
|
410
|
-
const redirectUrl = req.url.replace('/home', '');
|
|
411
|
-
return res.redirect(redirectUrl.startsWith('/') ? redirectUrl : `/${redirectUrl}`);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (page404) return res.status(404).redirect(page404);
|
|
415
|
-
else {
|
|
416
|
-
res.set('Content-Type', 'text/html');
|
|
417
|
-
return res.status(404).send(defaultHtmlSrc404);
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
const defaultHtmlSrc500 = Render({
|
|
422
|
-
title: '500 Server Error',
|
|
423
|
-
ssrPath,
|
|
424
|
-
ssrHeadComponents: '',
|
|
425
|
-
ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/500.js`))(),
|
|
426
|
-
renderPayload: {
|
|
427
|
-
apiBasePath: process.env.BASE_API,
|
|
428
|
-
version: Underpost.version,
|
|
429
|
-
},
|
|
430
|
-
renderApi: {
|
|
431
|
-
JSONweb,
|
|
432
|
-
},
|
|
433
|
-
});
|
|
434
|
-
const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
|
|
435
|
-
const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
|
|
436
|
-
app.use(function (err, req, res, next) {
|
|
437
|
-
logger.error(err, err.stack);
|
|
438
|
-
if (page500) return res.status(500).redirect(page500);
|
|
439
|
-
else {
|
|
440
|
-
res.set('Content-Type', 'text/html');
|
|
441
|
-
return res.status(500).send(defaultHtmlSrc500);
|
|
442
|
-
}
|
|
443
|
-
});
|
|
236
|
+
// load ssr
|
|
237
|
+
const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
|
|
238
|
+
for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
|
|
444
239
|
|
|
445
240
|
// instance server
|
|
446
241
|
const server = createServer({}, app);
|
|
@@ -489,6 +284,45 @@ const buildRuntime = async () => {
|
|
|
489
284
|
await UnderpostStartUp.API.listenPortController(server, port, runningData);
|
|
490
285
|
|
|
491
286
|
break;
|
|
287
|
+
|
|
288
|
+
case 'lampp':
|
|
289
|
+
{
|
|
290
|
+
const { disabled } = await Lampp.createApp({
|
|
291
|
+
port,
|
|
292
|
+
host,
|
|
293
|
+
path,
|
|
294
|
+
directory,
|
|
295
|
+
rootHostPath,
|
|
296
|
+
redirect,
|
|
297
|
+
redirectTarget,
|
|
298
|
+
});
|
|
299
|
+
if (disabled) continue;
|
|
300
|
+
await UnderpostStartUp.API.listenPortController(
|
|
301
|
+
UnderpostStartUp.API.listenServerFactory(),
|
|
302
|
+
port,
|
|
303
|
+
runningData,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
break;
|
|
307
|
+
case 'xampp':
|
|
308
|
+
{
|
|
309
|
+
const { disabled } = await Xampp.createApp({
|
|
310
|
+
port,
|
|
311
|
+
host,
|
|
312
|
+
path,
|
|
313
|
+
directory,
|
|
314
|
+
rootHostPath,
|
|
315
|
+
redirect,
|
|
316
|
+
redirectTarget,
|
|
317
|
+
});
|
|
318
|
+
if (disabled) continue;
|
|
319
|
+
await UnderpostStartUp.API.listenPortController(
|
|
320
|
+
UnderpostStartUp.API.listenServerFactory(),
|
|
321
|
+
port,
|
|
322
|
+
runningData,
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
break;
|
|
492
326
|
default:
|
|
493
327
|
break;
|
|
494
328
|
}
|
|
@@ -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/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:
|