underpost 2.6.2

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.
Files changed (269) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.development +8 -0
  3. package/.env.production +8 -0
  4. package/.env.test +8 -0
  5. package/.nycrc +9 -0
  6. package/.prettierignore +13 -0
  7. package/.prettierrc +9 -0
  8. package/.vscode/extensions.json +72 -0
  9. package/.vscode/settings.json +99 -0
  10. package/Dockerfile +88 -0
  11. package/LICENSE +21 -0
  12. package/README.md +51 -0
  13. package/bin/db.js +119 -0
  14. package/bin/deploy.js +600 -0
  15. package/bin/dns.js +1 -0
  16. package/bin/file.js +92 -0
  17. package/bin/help.js +110 -0
  18. package/bin/index.js +29 -0
  19. package/bin/install.js +357 -0
  20. package/bin/shortcut.js +44 -0
  21. package/bin/ssl.js +61 -0
  22. package/bin/util.js +182 -0
  23. package/bin/vs.js +35 -0
  24. package/conf.js +244 -0
  25. package/docker-compose.yml +67 -0
  26. package/jsconfig.json +7 -0
  27. package/jsdoc.json +32 -0
  28. package/nodemon.json +6 -0
  29. package/package.json +128 -0
  30. package/prometheus.yml +36 -0
  31. package/setup.sh +25 -0
  32. package/src/api/core/core.controller.js +69 -0
  33. package/src/api/core/core.model.js +11 -0
  34. package/src/api/core/core.router.js +23 -0
  35. package/src/api/core/core.service.js +29 -0
  36. package/src/api/crypto/crypto.controller.js +51 -0
  37. package/src/api/crypto/crypto.model.js +23 -0
  38. package/src/api/crypto/crypto.router.js +20 -0
  39. package/src/api/crypto/crypto.service.js +64 -0
  40. package/src/api/default/default.controller.js +69 -0
  41. package/src/api/default/default.model.js +20 -0
  42. package/src/api/default/default.router.js +23 -0
  43. package/src/api/default/default.service.js +31 -0
  44. package/src/api/file/file.controller.js +51 -0
  45. package/src/api/file/file.model.js +19 -0
  46. package/src/api/file/file.router.js +20 -0
  47. package/src/api/file/file.service.js +70 -0
  48. package/src/api/instance/instance.controller.js +69 -0
  49. package/src/api/instance/instance.model.js +36 -0
  50. package/src/api/instance/instance.router.js +33 -0
  51. package/src/api/instance/instance.service.js +48 -0
  52. package/src/api/test/test.controller.js +59 -0
  53. package/src/api/test/test.model.js +14 -0
  54. package/src/api/test/test.router.js +21 -0
  55. package/src/api/test/test.service.js +35 -0
  56. package/src/api/user/user.controller.js +70 -0
  57. package/src/api/user/user.model.js +65 -0
  58. package/src/api/user/user.router.js +345 -0
  59. package/src/api/user/user.service.js +479 -0
  60. package/src/api.js +23 -0
  61. package/src/client/Default.index.js +40 -0
  62. package/src/client/components/core/Account.js +290 -0
  63. package/src/client/components/core/AgGrid.js +160 -0
  64. package/src/client/components/core/Auth.js +19 -0
  65. package/src/client/components/core/Badge.js +32 -0
  66. package/src/client/components/core/BlockChain.js +41 -0
  67. package/src/client/components/core/Blog.js +9 -0
  68. package/src/client/components/core/BtnIcon.js +91 -0
  69. package/src/client/components/core/CalendarCore.js +319 -0
  70. package/src/client/components/core/Chat.js +64 -0
  71. package/src/client/components/core/ColorPalette.js +5267 -0
  72. package/src/client/components/core/CommonJs.js +708 -0
  73. package/src/client/components/core/Content.js +49 -0
  74. package/src/client/components/core/Css.js +1027 -0
  75. package/src/client/components/core/CssCore.js +792 -0
  76. package/src/client/components/core/D3Chart.js +44 -0
  77. package/src/client/components/core/Docs.js +130 -0
  78. package/src/client/components/core/DropDown.js +164 -0
  79. package/src/client/components/core/EventsUI.js +54 -0
  80. package/src/client/components/core/FileExplorer.js +624 -0
  81. package/src/client/components/core/FullScreen.js +45 -0
  82. package/src/client/components/core/Input.js +259 -0
  83. package/src/client/components/core/JoyStick.js +77 -0
  84. package/src/client/components/core/Keyboard.js +73 -0
  85. package/src/client/components/core/LoadingAnimation.js +157 -0
  86. package/src/client/components/core/LogIn.js +181 -0
  87. package/src/client/components/core/LogOut.js +52 -0
  88. package/src/client/components/core/Logger.js +26 -0
  89. package/src/client/components/core/Modal.js +1596 -0
  90. package/src/client/components/core/NotificationManager.js +84 -0
  91. package/src/client/components/core/Panel.js +413 -0
  92. package/src/client/components/core/Polyhedron.js +162 -0
  93. package/src/client/components/core/Recover.js +204 -0
  94. package/src/client/components/core/Responsive.js +53 -0
  95. package/src/client/components/core/RichText.js +27 -0
  96. package/src/client/components/core/Router.js +77 -0
  97. package/src/client/components/core/SignUp.js +125 -0
  98. package/src/client/components/core/SocketIo.js +72 -0
  99. package/src/client/components/core/Stream.js +113 -0
  100. package/src/client/components/core/ToggleSwitch.js +87 -0
  101. package/src/client/components/core/ToolTip.js +26 -0
  102. package/src/client/components/core/Translate.js +408 -0
  103. package/src/client/components/core/Validator.js +100 -0
  104. package/src/client/components/core/VanillaJs.js +454 -0
  105. package/src/client/components/core/Wallet.js +106 -0
  106. package/src/client/components/core/Webhook.js +25 -0
  107. package/src/client/components/core/Worker.js +272 -0
  108. package/src/client/components/default/CommonDefault.js +29 -0
  109. package/src/client/components/default/CssDefault.js +13 -0
  110. package/src/client/components/default/ElementsDefault.js +38 -0
  111. package/src/client/components/default/LogInDefault.js +41 -0
  112. package/src/client/components/default/LogOutDefault.js +28 -0
  113. package/src/client/components/default/MenuDefault.js +389 -0
  114. package/src/client/components/default/RoutesDefault.js +48 -0
  115. package/src/client/components/default/SettingsDefault.js +16 -0
  116. package/src/client/components/default/SignUpDefault.js +9 -0
  117. package/src/client/components/default/SocketIoDefault.js +54 -0
  118. package/src/client/components/default/TranslateDefault.js +7 -0
  119. package/src/client/public/default/android-chrome-144x144.png +0 -0
  120. package/src/client/public/default/android-chrome-192x192.png +0 -0
  121. package/src/client/public/default/android-chrome-256x256.png +0 -0
  122. package/src/client/public/default/android-chrome-36x36.png +0 -0
  123. package/src/client/public/default/android-chrome-384x384.png +0 -0
  124. package/src/client/public/default/android-chrome-48x48.png +0 -0
  125. package/src/client/public/default/android-chrome-512x512.png +0 -0
  126. package/src/client/public/default/android-chrome-72x72.png +0 -0
  127. package/src/client/public/default/android-chrome-96x96.png +0 -0
  128. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  129. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  130. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  131. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  132. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  133. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  134. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  135. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  136. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  137. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  138. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  139. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  140. package/src/client/public/default/apple-touch-icon.png +0 -0
  141. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  142. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  143. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  144. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  145. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  146. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  147. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  148. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  149. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  150. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  151. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  152. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  153. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  154. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  155. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  156. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  157. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  158. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  159. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  160. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  161. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  162. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  163. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  164. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  165. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  166. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  167. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  168. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  169. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  170. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  171. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  172. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  173. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  174. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  175. package/src/client/public/default/assets/background/white.jpg +0 -0
  176. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  177. package/src/client/public/default/assets/background/white0.jpg +0 -0
  178. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  179. package/src/client/public/default/browserconfig.xml +12 -0
  180. package/src/client/public/default/favicon-16x16.png +0 -0
  181. package/src/client/public/default/favicon-32x32.png +0 -0
  182. package/src/client/public/default/favicon-48x48.png +0 -0
  183. package/src/client/public/default/favicon.ico +0 -0
  184. package/src/client/public/default/manifest.webmanifest +69 -0
  185. package/src/client/public/default/mstile-144x144.png +0 -0
  186. package/src/client/public/default/mstile-150x150.png +0 -0
  187. package/src/client/public/default/mstile-310x150.png +0 -0
  188. package/src/client/public/default/mstile-310x310.png +0 -0
  189. package/src/client/public/default/mstile-70x70.png +0 -0
  190. package/src/client/public/default/sitemap +148 -0
  191. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  192. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  193. package/src/client/public/doc/favicon.ico +0 -0
  194. package/src/client/public/doc/sitemap +148 -0
  195. package/src/client/public/test/favicon.ico +0 -0
  196. package/src/client/public/test/sitemap +148 -0
  197. package/src/client/services/core/core.service.js +152 -0
  198. package/src/client/services/crypto/crypto.service.js +70 -0
  199. package/src/client/services/default/default.management.js +345 -0
  200. package/src/client/services/default/default.service.js +89 -0
  201. package/src/client/services/file/file.service.js +70 -0
  202. package/src/client/services/instance/instance.management.js +74 -0
  203. package/src/client/services/instance/instance.service.js +89 -0
  204. package/src/client/services/test/test.service.js +70 -0
  205. package/src/client/services/user/user.management.js +50 -0
  206. package/src/client/services/user/user.service.js +89 -0
  207. package/src/client/ssr/Render.js +16 -0
  208. package/src/client/ssr/body-components/CacheControl.js +113 -0
  209. package/src/client/ssr/body-components/DefaultSplashScreen.js +79 -0
  210. package/src/client/ssr/email-components/DefaultRecoverEmail.js +21 -0
  211. package/src/client/ssr/email-components/DefaultVerifyEmail.js +17 -0
  212. package/src/client/ssr/head-components/Css.js +241 -0
  213. package/src/client/ssr/head-components/DefaultScripts.js +3 -0
  214. package/src/client/ssr/head-components/Microdata.js +11 -0
  215. package/src/client/ssr/head-components/Production.js +1 -0
  216. package/src/client/ssr/head-components/PwaDefault.js +60 -0
  217. package/src/client/ssr/head-components/Seo.js +14 -0
  218. package/src/client/sw/default.sw.js +201 -0
  219. package/src/client/sw/template.sw.js +84 -0
  220. package/src/client.build.js +22 -0
  221. package/src/client.dev.js +21 -0
  222. package/src/cron.js +25 -0
  223. package/src/db/DataBaseProvider.js +34 -0
  224. package/src/db/mariadb/MariaDB.js +33 -0
  225. package/src/db/mongo/MongooseDB.js +46 -0
  226. package/src/dns.js +22 -0
  227. package/src/mailer/EmailRender.js +69 -0
  228. package/src/mailer/MailerProvider.js +96 -0
  229. package/src/proxy.js +22 -0
  230. package/src/runtime/lampp/Lampp.js +44 -0
  231. package/src/runtime/nginx/Nginx.js +3 -0
  232. package/src/runtime/xampp/Xampp.js +49 -0
  233. package/src/server/auth.js +204 -0
  234. package/src/server/backup.js +83 -0
  235. package/src/server/client-build-live.js +72 -0
  236. package/src/server/client-build.js +688 -0
  237. package/src/server/client-dev-server.js +58 -0
  238. package/src/server/client-formatted.js +48 -0
  239. package/src/server/client-icons.js +150 -0
  240. package/src/server/conf.js +611 -0
  241. package/src/server/dns.js +87 -0
  242. package/src/server/downloader.js +42 -0
  243. package/src/server/logger.js +135 -0
  244. package/src/server/network.js +122 -0
  245. package/src/server/peer.js +33 -0
  246. package/src/server/process.js +66 -0
  247. package/src/server/proxy.js +118 -0
  248. package/src/server/runtime.js +393 -0
  249. package/src/server/ssl.js +107 -0
  250. package/src/server.js +25 -0
  251. package/src/ws/IoInterface.js +45 -0
  252. package/src/ws/IoServer.js +39 -0
  253. package/src/ws/core/channels/core.ws.chat.js +23 -0
  254. package/src/ws/core/channels/core.ws.mailer.js +35 -0
  255. package/src/ws/core/channels/core.ws.stream.js +31 -0
  256. package/src/ws/core/core.ws.connection.js +28 -0
  257. package/src/ws/core/core.ws.emit.js +14 -0
  258. package/src/ws/core/core.ws.server.js +24 -0
  259. package/src/ws/core/management/core.ws.chat.js +8 -0
  260. package/src/ws/core/management/core.ws.mailer.js +16 -0
  261. package/src/ws/core/management/core.ws.stream.js +8 -0
  262. package/src/ws/default/channels/default.ws.main.js +16 -0
  263. package/src/ws/default/default.ws.connection.js +22 -0
  264. package/src/ws/default/default.ws.emit.js +14 -0
  265. package/src/ws/default/default.ws.server.js +20 -0
  266. package/src/ws/default/management/default.ws.main.js +8 -0
  267. package/startup.js +11 -0
  268. package/supervisord-openssh-server.conf +5 -0
  269. package/test/api.test.js +60 -0
@@ -0,0 +1,393 @@
1
+ import fs from 'fs';
2
+ import express from 'express';
3
+ import cors from 'cors';
4
+ import dotenv from 'dotenv';
5
+ import fileUpload from 'express-fileupload';
6
+ import swaggerUi from 'swagger-ui-express';
7
+ import * as promClient from 'prom-client';
8
+ import compression from 'compression';
9
+
10
+ import { createServer } from 'http';
11
+ import { getRootDirectory } from './process.js';
12
+ import { network, listenPortController, saveRuntimeRouter, logRuntimeRouter, listenServerFactory } from './network.js';
13
+ import { loggerFactory, loggerMiddleware } from './logger.js';
14
+ import { newInstance } from '../client/components/core/CommonJs.js';
15
+ import { Xampp } from '../runtime/xampp/Xampp.js';
16
+ import { MailerProvider } from '../mailer/MailerProvider.js';
17
+ import { DataBaseProvider } from '../db/DataBaseProvider.js';
18
+ import { createProxyMiddleware } from 'http-proxy-middleware';
19
+ import { createPeerServer } from './peer.js';
20
+ import { Lampp } from '../runtime/lampp/Lampp.js';
21
+
22
+ dotenv.config();
23
+
24
+ const logger = loggerFactory(import.meta);
25
+
26
+ const buildRuntime = async () => {
27
+ const deployId = `${process.argv[3] ? process.argv[3] : 'default'}`;
28
+
29
+ const collectDefaultMetrics = promClient.collectDefaultMetrics;
30
+ collectDefaultMetrics();
31
+
32
+ const promCounterOption = {
33
+ name: `${deployId.replaceAll('-', '_')}_http_requests_total`,
34
+ help: 'Total number of HTTP requests',
35
+ labelNames: ['instance', 'method', 'status_code'],
36
+ };
37
+
38
+ // logger.info('promCounterOption', promCounterOption);
39
+
40
+ const requestCounter = new promClient.Counter(promCounterOption);
41
+
42
+ const ipInstance = ''; // await ip.public.ipv4();
43
+ const initPort = parseInt(process.env.PORT) + 1;
44
+ let currentPort = initPort;
45
+ const confServer = JSON.parse(fs.readFileSync(`./conf/conf.server.json`, 'utf8'));
46
+ const singleReplicaHosts = [];
47
+ for (const host of Object.keys(confServer)) {
48
+ if (singleReplicaHosts.length > 0 && !singleReplicaHosts.includes(host)) {
49
+ currentPort += singleReplicaHosts.reduce((accumulator, currentValue) => accumulator + currentValue.replicas, 0);
50
+ }
51
+ const rootHostPath = `/public/${host}`;
52
+ for (const path of Object.keys(confServer[host])) {
53
+ confServer[host][path].port = newInstance(currentPort);
54
+ const {
55
+ runtime,
56
+ port,
57
+ client,
58
+ apis,
59
+ origins,
60
+ directory,
61
+ ws,
62
+ mailer,
63
+ db,
64
+ redirect,
65
+ peer,
66
+ singleReplica,
67
+ replicas,
68
+ } = confServer[host][path];
69
+
70
+ if (singleReplica && replicas && replicas.length > 0 && !singleReplicaHosts.includes(host)) {
71
+ singleReplicaHosts.push({
72
+ host,
73
+ replicas: replicas.length,
74
+ });
75
+ continue;
76
+ }
77
+
78
+ const runningData = {
79
+ host,
80
+ path,
81
+ runtime,
82
+ client,
83
+ meta: import.meta,
84
+ };
85
+
86
+ let redirectUrl;
87
+ let redirectTarget;
88
+ if (redirect) {
89
+ redirectUrl = new URL(redirect);
90
+ redirectTarget = redirect[redirect.length - 1] === '/' ? redirect.slice(0, -1) : redirect;
91
+ }
92
+
93
+ logger.info('Build runtime', `${host}${path}`);
94
+
95
+ switch (runtime) {
96
+ case 'lampp':
97
+ if (!Lampp.enabled()) continue;
98
+ if (!Lampp.ports.includes(port)) Lampp.ports.push(port);
99
+ if (currentPort === initPort) Lampp.removeRouter();
100
+ Lampp.appendRouter(`
101
+
102
+ Listen ${port}
103
+
104
+ <VirtualHost *:${port}>
105
+ DocumentRoot "${directory ? directory.replace(path, '/') : `${getRootDirectory()}${rootHostPath}`}"
106
+ ServerName ${host}:${port}
107
+
108
+ <Directory "${directory ? directory.replace(path, '/') : `${getRootDirectory()}${rootHostPath}`}">
109
+ Options Indexes FollowSymLinks MultiViews
110
+ AllowOverride All
111
+ Require all granted
112
+ </Directory>
113
+
114
+ ${
115
+ redirect
116
+ ? `
117
+ RewriteEngine on
118
+
119
+ RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
120
+ RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
121
+ `
122
+ : ''
123
+ }
124
+
125
+ </VirtualHost>
126
+
127
+ `);
128
+ // ERR too many redirects:
129
+ // Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
130
+ // Check: wp-config.php
131
+ // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
132
+ // $_SERVER['HTTPS'] = 'on';
133
+ // }
134
+
135
+ // ErrorDocument 404 /custom_404.html
136
+ // ErrorDocument 500 /custom_50x.html
137
+ // ErrorDocument 502 /custom_50x.html
138
+ // ErrorDocument 503 /custom_50x.html
139
+ // ErrorDocument 504 /custom_50x.html
140
+
141
+ // Respond When Error Pages are Directly Requested
142
+
143
+ // <Files "custom_404.html">
144
+ // <If "-z %{ENV:REDIRECT_STATUS}">
145
+ // RedirectMatch 404 ^/custom_404.html$
146
+ // </If>
147
+ // </Files>
148
+
149
+ // <Files "custom_50x.html">
150
+ // <If "-z %{ENV:REDIRECT_STATUS}">
151
+ // RedirectMatch 404 ^/custom_50x.html$
152
+ // </If>
153
+ // </Files>
154
+ await listenPortController(listenServerFactory(), port, runningData);
155
+ break;
156
+ case 'xampp':
157
+ if (!Xampp.enabled()) continue;
158
+ if (!Xampp.ports.includes(port)) Xampp.ports.push(port);
159
+ if (currentPort === initPort) Xampp.removeRouter();
160
+ Xampp.appendRouter(`
161
+
162
+ Listen ${port}
163
+
164
+ <VirtualHost *:${port}>
165
+ DocumentRoot "${directory ? directory.replace(path, '/') : `${getRootDirectory()}${rootHostPath}`}"
166
+ ServerName ${host}:${port}
167
+
168
+ <Directory "${directory ? directory.replace(path, '/') : `${getRootDirectory()}${rootHostPath}`}">
169
+ Options Indexes FollowSymLinks MultiViews
170
+ AllowOverride All
171
+ Require all granted
172
+ </Directory>
173
+
174
+ ${
175
+ redirect
176
+ ? `
177
+ RewriteEngine on
178
+
179
+ RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
180
+ RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
181
+ `
182
+ : ''
183
+ }
184
+
185
+ </VirtualHost>
186
+
187
+ `);
188
+ // ERR too many redirects:
189
+ // Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
190
+ // Check: wp-config.php
191
+ // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
192
+ // $_SERVER['HTTPS'] = 'on';
193
+ // }
194
+ await listenPortController(listenServerFactory(), port, runningData);
195
+ break;
196
+ case 'nodejs':
197
+ const app = express();
198
+
199
+ app.use((req, res, next) => {
200
+ // const info = `${req.headers.host}${req.url}`;
201
+ return next();
202
+ });
203
+
204
+ // https://github.com/prometheus/prometheus/blob/main/documentation/examples/prometheus.yml
205
+ // https://github.com/grafana/grafana/tree/main/conf
206
+ // https://medium.com/@diego.coder/monitoreo-de-aplicaciones-con-node-js-grafana-y-prometheus-afd2b33e3f91
207
+ // for grafana prometheus server: host.docker.internal:9090
208
+
209
+ app.use((req, res, next) => {
210
+ requestCounter.inc({
211
+ instance: `${host}:${port}${path}`,
212
+ method: req.method,
213
+ status_code: res.statusCode,
214
+ });
215
+ // decodeURIComponent(req.url)
216
+ return next();
217
+ });
218
+
219
+ app.get(`${path === '/' ? '' : path}/metrics`, async (req, res) => {
220
+ res.set('Content-Type', promClient.register.contentType);
221
+ return res.end(await promClient.register.metrics());
222
+ });
223
+
224
+ // set logger
225
+ app.use(loggerMiddleware(import.meta));
226
+
227
+ // instance public static
228
+ app.use('/', express.static(directory ? directory : `.${rootHostPath}`));
229
+
230
+ // js src compression
231
+ app.use(compression({ filter: shouldCompress }));
232
+ function shouldCompress(req, res) {
233
+ if (req.headers['x-no-compression']) {
234
+ // don't compress responses with this request header
235
+ return false;
236
+ }
237
+
238
+ // fallback to standard filter function
239
+ return compression.filter(req, res);
240
+ }
241
+
242
+ // parse requests of content-type - application/json
243
+ app.use(express.json({ limit: '100MB' }));
244
+
245
+ // parse requests of content-type - application/x-www-form-urlencoded
246
+ app.use(express.urlencoded({ extended: true, limit: '20MB' }));
247
+
248
+ // file upload middleware
249
+ app.use(fileUpload());
250
+
251
+ // json formatted response
252
+ app.set('json spaces', 2);
253
+
254
+ // lang handling middleware
255
+ app.use(function (req, res, next) {
256
+ const lang = req.headers['accept-language'] || 'en';
257
+ if (typeof lang === 'string' && lang.toLowerCase().match('es')) {
258
+ req.lang = 'es';
259
+ } else req.lang = 'en';
260
+ return next();
261
+ });
262
+
263
+ // cors
264
+ app.use(cors({ origin: origins }));
265
+
266
+ if (redirect) {
267
+ app.use(function (req = express.Request, res = express.Response, next = express.NextFunction) {
268
+ if (process.env.NODE_ENV === 'production' && !req.url.startsWith(`/.well-known/acme-challenge`))
269
+ return res.status(302).redirect(redirectTarget + req.url);
270
+ // if (!req.url.startsWith(`/.well-known/acme-challenge`)) return res.status(302).redirect(redirect);
271
+ return next();
272
+ });
273
+ // app.use(
274
+ // '*',
275
+ // createProxyMiddleware({
276
+ // target: redirect,
277
+ // changeOrigin: true,
278
+ // }),
279
+ // );
280
+ await network.port.portClean(port);
281
+ await listenPortController(app, port, runningData);
282
+ break;
283
+ }
284
+
285
+ const swaggerJsonPath = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
286
+ if (fs.existsSync(swaggerJsonPath)) {
287
+ // logger.info('Build swagger serve', swaggerJsonPath);
288
+
289
+ const swaggerInstance =
290
+ (swaggerDoc) =>
291
+ (...args) =>
292
+ swaggerUi.setup(swaggerDoc)(...args);
293
+
294
+ const swaggerDoc = JSON.parse(fs.readFileSync(swaggerJsonPath, 'utf8'));
295
+
296
+ app.use(`${path === '/' ? `/api-docs` : `${path}/api-docs`}`, swaggerUi.serve, swaggerInstance(swaggerDoc));
297
+ }
298
+
299
+ if (db && apis) await DataBaseProvider.load({ apis, host, path, db });
300
+
301
+ if (mailer)
302
+ await MailerProvider.load({
303
+ id: `${host}${path}`,
304
+ meta: `mailer-${host}${path}`,
305
+ host,
306
+ path,
307
+ ...mailer,
308
+ });
309
+
310
+ if (apis) {
311
+ const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
312
+ for (const api of apis)
313
+ await (async () => {
314
+ const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
315
+ const router = ApiRouter({ host, path, apiPath, mailer, db });
316
+ // router.use(cors({ origin: origins }));
317
+ // logger.info('Load api router', { host, path: apiPath, api });
318
+ app.use(`${apiPath}/${api}`, router);
319
+ })();
320
+ }
321
+
322
+ app.use(function (req, res, next) {
323
+ res.status(404).send('Sorry cant find that!');
324
+ });
325
+
326
+ app.use(function (err, req, res, next) {
327
+ logger.error(err, err.stack);
328
+ res.status(500).send('Something broke!');
329
+ });
330
+
331
+ // instance server
332
+ const server = createServer({}, app);
333
+
334
+ if (ws)
335
+ await (async () => {
336
+ const { createIoServer } = await import(`../ws/${ws}/${ws}.ws.server.js`);
337
+ // logger.info('Load socket.io ws router', { host, ws });
338
+ // start socket.io
339
+ const { options, meta } = await createIoServer(server, {
340
+ host,
341
+ path,
342
+ db,
343
+ port,
344
+ origins,
345
+ });
346
+ await listenPortController(listenServerFactory(), port, {
347
+ runtime: 'nodejs',
348
+ client: null,
349
+ host,
350
+ path: options.path,
351
+ meta,
352
+ });
353
+ })();
354
+
355
+ if (peer) {
356
+ currentPort++;
357
+ const peerPort = newInstance(currentPort);
358
+ const { options, meta, peerServer } = await createPeerServer({
359
+ port: peerPort,
360
+ devPort: port,
361
+ origins,
362
+ host,
363
+ path,
364
+ });
365
+ await network.port.portClean(peerPort);
366
+ await listenPortController(peerServer, peerPort, {
367
+ runtime: 'nodejs',
368
+ client: null,
369
+ host,
370
+ path: options.path,
371
+ meta,
372
+ });
373
+ }
374
+
375
+ await network.port.portClean(port);
376
+ await listenPortController(server, port, runningData);
377
+
378
+ break;
379
+ default:
380
+ break;
381
+ }
382
+ currentPort++;
383
+ }
384
+ }
385
+
386
+ if (Xampp.enabled() && Xampp.router) await Xampp.initService({ daemon: true });
387
+ if (Lampp.enabled() && Lampp.router) await Lampp.initService({ daemon: true });
388
+
389
+ saveRuntimeRouter();
390
+ logRuntimeRouter();
391
+ };
392
+
393
+ export { buildRuntime };
@@ -0,0 +1,107 @@
1
+ import fs from 'fs-extra';
2
+ import dotenv from 'dotenv';
3
+ import https from 'https';
4
+ import { loggerFactory } from './logger.js';
5
+ import { range } from '../client/components/core/CommonJs.js';
6
+
7
+ dotenv.config();
8
+
9
+ const logger = loggerFactory(import.meta);
10
+
11
+ const buildSSL = async (host) => {
12
+ const sslPath = process.env.CERTBOT_LIVE_PATH;
13
+
14
+ const files = await fs.readdir(sslPath);
15
+
16
+ for (const folderHost of files)
17
+ if (folderHost.match(host.split('/')[0])) {
18
+ for (const i of [''].concat(range(1, 10))) {
19
+ const privateKeyPath = `${sslPath}/${folderHost}/privkey${i}.pem`;
20
+ const certificatePath = `${sslPath}/${folderHost}/cert${i}.pem`;
21
+ const caPath = `${sslPath}/${folderHost}/chain${i}.pem`;
22
+ const caFullPath = `${sslPath}/${folderHost}/fullchain${i}.pem`;
23
+
24
+ if (
25
+ fs.existsSync(privateKeyPath) &&
26
+ fs.existsSync(certificatePath) &&
27
+ fs.existsSync(caPath) &&
28
+ fs.existsSync(caFullPath)
29
+ ) {
30
+ const privateKey = fs.readFileSync(privateKeyPath, 'utf8');
31
+ const certificate = fs.readFileSync(certificatePath, 'utf8');
32
+ const ca = fs.readFileSync(caPath, 'utf8');
33
+ const caFull = fs.readFileSync(caFullPath, 'utf8');
34
+
35
+ logger.info(`SSL files update`, {
36
+ privateKey,
37
+ certificate,
38
+ ca,
39
+ caFull,
40
+ });
41
+
42
+ if (!fs.existsSync(`./engine-private/ssl/${host}`))
43
+ fs.mkdirSync(`./engine-private/ssl/${host}`, { recursive: true });
44
+
45
+ fs.writeFileSync(`./engine-private/ssl/${host}/key.key`, privateKey, 'utf8');
46
+ fs.writeFileSync(`./engine-private/ssl/${host}/crt.crt`, certificate, 'utf8');
47
+ fs.writeFileSync(`./engine-private/ssl/${host}/ca_bundle.crt`, caFull, 'utf8');
48
+
49
+ fs.writeFileSync(`./engine-private/ssl/${host}/_ca_bundle.crt`, ca, 'utf8');
50
+ fs.writeFileSync(`./engine-private/ssl/${host}/_ca_full_bundle.crt`, caFull, 'utf8');
51
+
52
+ fs.removeSync(`${sslPath}/${folderHost}`);
53
+ return true;
54
+ }
55
+ }
56
+ }
57
+ return false;
58
+ };
59
+
60
+ const validateSecureContext = (host) => {
61
+ return (
62
+ fs.existsSync(`./engine-private/ssl/${host}/key.key`) &&
63
+ fs.existsSync(`./engine-private/ssl/${host}/crt.crt`) &&
64
+ fs.existsSync(`./engine-private/ssl/${host}/ca_bundle.crt`)
65
+ );
66
+ };
67
+
68
+ const buildSecureContext = (host) => {
69
+ return {
70
+ key: fs.readFileSync(`./engine-private/ssl/${host}/key.key`, 'utf8'),
71
+ cert: fs.readFileSync(`./engine-private/ssl/${host}/crt.crt`, 'utf8'),
72
+ ca: fs.readFileSync(`./engine-private/ssl/${host}/ca_bundle.crt`, 'utf8'),
73
+ };
74
+ };
75
+
76
+ const createSslServer = async (app, hosts) => {
77
+ let ServerSSL;
78
+ for (const host of Object.keys(hosts)) {
79
+ // const { redirect } = hosts[host];
80
+ const [hostSSL, path = ''] = host.split('/');
81
+ await buildSSL(host);
82
+ const validSSL = validateSecureContext(hostSSL);
83
+ if (validSSL) {
84
+ if (!ServerSSL) ServerSSL = https.createServer(buildSecureContext(hostSSL), app);
85
+ else ServerSSL.addContext(hostSSL, buildSecureContext(hostSSL));
86
+ } else logger.error('Invalid SSL context', { host, ...hosts[host] });
87
+ }
88
+ return { ServerSSL };
89
+ };
90
+
91
+ const sslRedirectMiddleware = (req, res, port, proxyRouter) => {
92
+ const sslRedirectUrl = `https://${req.headers.host}${req.url}`;
93
+ if (
94
+ process.env.NODE_ENV === 'production' &&
95
+ port !== 443 &&
96
+ !req.secure &&
97
+ !req.url.startsWith(`/.well-known/acme-challenge`) &&
98
+ proxyRouter[443] &&
99
+ Object.keys(proxyRouter[443]).find((host) => {
100
+ const [hostSSL, path = ''] = host.split('/');
101
+ return sslRedirectUrl.match(hostSSL) && validateSecureContext(hostSSL);
102
+ })
103
+ )
104
+ return res.status(302).redirect(sslRedirectUrl);
105
+ };
106
+
107
+ export { buildSSL, buildSecureContext, validateSecureContext, createSslServer, sslRedirectMiddleware };
package/src/server.js ADDED
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ // https://nodejs.org/api
4
+ // https://expressjs.com/en/4x/api.html
5
+
6
+ import dotenv from 'dotenv';
7
+ import { loggerFactory } from './server/logger.js';
8
+ import { buildClient } from './server/client-build.js';
9
+ import { buildRuntime } from './server/runtime.js';
10
+ import { ProcessController } from './server/process.js';
11
+ import { Config } from './server/conf.js';
12
+
13
+ dotenv.config();
14
+
15
+ await Config.build();
16
+
17
+ const logger = loggerFactory(import.meta);
18
+
19
+ await logger.setUpInfo();
20
+
21
+ await buildClient();
22
+
23
+ await buildRuntime();
24
+
25
+ ProcessController.init(logger);
@@ -0,0 +1,45 @@
1
+ import { loggerFactory } from '../server/logger.js';
2
+
3
+ const logger = loggerFactory(import.meta);
4
+
5
+ const IoCreateChannel = (
6
+ IoInterface = {
7
+ channel: '',
8
+ connection: (socket = {}, client = {}, wsManagementId = '') => {},
9
+ controller: (socket = {}, client = {}, args = '', wsManagementId = '') => {},
10
+ disconnect: (socket = {}, client = {}, reason = '', wsManagementId = '') => {},
11
+ stream: false,
12
+ },
13
+ ) => {
14
+ return {
15
+ channel: IoInterface.channel,
16
+ client: {},
17
+ connection: async function (socket, wsManagementId) {
18
+ try {
19
+ this.client[socket.id] = socket;
20
+ socket.on(IoInterface.channel, (...args) => this.controller(socket, args, wsManagementId));
21
+ await IoInterface.connection(socket, this.client, wsManagementId);
22
+ } catch (error) {
23
+ logger.error(error, { channel: IoInterface.channel, wsManagementId, stack: error.stack });
24
+ }
25
+ },
26
+ controller: async function (socket, args, wsManagementId) {
27
+ try {
28
+ const payload = IoInterface.stream ? args[0] : JSON.parse(args[0]);
29
+ await IoInterface.controller(socket, this.client, payload, wsManagementId, args);
30
+ } catch (error) {
31
+ logger.error(error, { channel: IoInterface.channel, wsManagementId, args, stack: error.stack });
32
+ }
33
+ },
34
+ disconnect: async function (socket, reason, wsManagementId) {
35
+ try {
36
+ await IoInterface.disconnect(socket, this.client, reason, wsManagementId);
37
+ delete this.client[socket.id];
38
+ } catch (error) {
39
+ logger.error(error, { channel: IoInterface.channel, wsManagementId, reason, stack: error.stack });
40
+ }
41
+ },
42
+ };
43
+ };
44
+
45
+ export { IoCreateChannel };
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ import { Server } from 'socket.io';
4
+ import { loggerFactory } from '../server/logger.js';
5
+
6
+ // https://socket.io/docs/v3/
7
+
8
+ const logger = loggerFactory(import.meta);
9
+
10
+ const IoServer = (httpServer, options = {}, Connection = () => {}) => {
11
+ const wsOptions = {
12
+ cors: {
13
+ // origin: `http://localhost:${options.port}`,
14
+ origins: options.origins,
15
+ methods: ['GET', 'POST', 'DELETE', 'PUT'],
16
+ allowedHeaders: [
17
+ 'Access-Control-Allow-Headers',
18
+ 'Access-Control-Allow-Origin',
19
+ 'X-Requested-With',
20
+ 'X-Access-Token',
21
+ 'Content-Type',
22
+ 'Host',
23
+ 'Accept',
24
+ 'Connection',
25
+ 'Cache-Control',
26
+ 'Authorization',
27
+ ],
28
+ credentials: true,
29
+ },
30
+ path: options.path !== '/' ? `${options.path}/socket.io/` : '/socket.io',
31
+ };
32
+ return {
33
+ options: wsOptions,
34
+ meta: import.meta,
35
+ ioServer: new Server(httpServer, wsOptions).on('connection', Connection),
36
+ };
37
+ };
38
+
39
+ export { IoServer };
@@ -0,0 +1,23 @@
1
+ import { loggerFactory } from '../../../server/logger.js';
2
+ import { IoCreateChannel } from '../../IoInterface.js';
3
+ import { CoreWsEmit } from '../core.ws.emit.js';
4
+
5
+ const channel = 'chat';
6
+ const logger = loggerFactory(import.meta);
7
+
8
+ const CoreWsChatController = {
9
+ channel,
10
+ controller: function (socket, client, payload, wsManagementId) {
11
+ for (const socketId of Object.keys(client)) {
12
+ if (socketId !== socket.id) {
13
+ CoreWsEmit(channel, client[socketId], { id: socket.id, ...payload });
14
+ }
15
+ }
16
+ },
17
+ connection: function (socket, client, wsManagementId) {},
18
+ disconnect: function (socket, client, reason, wsManagementId) {},
19
+ };
20
+
21
+ const CoreWsChatChannel = IoCreateChannel(CoreWsChatController);
22
+
23
+ export { CoreWsChatChannel, CoreWsChatController };
@@ -0,0 +1,35 @@
1
+ import { loggerFactory } from '../../../server/logger.js';
2
+ import { IoCreateChannel } from '../../IoInterface.js';
3
+ import { CoreWsMailerManagement } from '../management/core.ws.mailer.js';
4
+
5
+ const channel = 'mailer';
6
+ const logger = loggerFactory(import.meta);
7
+
8
+ const CoreWsMailerController = {
9
+ channel,
10
+ controller: function (socket, client, payload, wsManagementId) {
11
+ switch (payload.status) {
12
+ case 'register-user':
13
+ CoreWsMailerManagement.element[wsManagementId][socket.id] = {
14
+ model: {
15
+ user: payload.user,
16
+ },
17
+ };
18
+ break;
19
+ case 'unregister-user':
20
+ delete CoreWsMailerManagement.element[wsManagementId][socket.id];
21
+ break;
22
+
23
+ default:
24
+ break;
25
+ }
26
+ },
27
+ connection: function (socket, client, wsManagementId) {},
28
+ disconnect: function (socket, client, reason, wsManagementId) {
29
+ delete CoreWsMailerManagement.element[wsManagementId][socket.id];
30
+ },
31
+ };
32
+
33
+ const CoreWsMailerChannel = IoCreateChannel(CoreWsMailerController);
34
+
35
+ export { CoreWsMailerChannel, CoreWsMailerController };