@underpostnet/underpost 2.7.82

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