@underpostnet/underpost 2.7.9

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 (297) 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 +115 -0
  6. package/.github/workflows/publish.yml +84 -0
  7. package/.github/workflows/pwa-microservices-template.page.yml +54 -0
  8. package/.github/workflows/pwa-microservices-template.test.yml +30 -0
  9. package/.nycrc +9 -0
  10. package/.prettierignore +13 -0
  11. package/.prettierrc +9 -0
  12. package/.vscode/extensions.json +72 -0
  13. package/.vscode/settings.json +106 -0
  14. package/AUTHORS.md +10 -0
  15. package/CHANGELOG.md +85 -0
  16. package/Dockerfile +90 -0
  17. package/LICENSE +21 -0
  18. package/README.md +96 -0
  19. package/bin/cron.js +47 -0
  20. package/bin/db.js +180 -0
  21. package/bin/deploy.js +859 -0
  22. package/bin/file.js +109 -0
  23. package/bin/index.js +82 -0
  24. package/bin/ssl.js +55 -0
  25. package/bin/util.js +204 -0
  26. package/bin/vs.js +35 -0
  27. package/conf.js +265 -0
  28. package/docker-compose.yml +67 -0
  29. package/jsconfig.json +7 -0
  30. package/jsdoc.json +32 -0
  31. package/nodemon.json +6 -0
  32. package/package.json +134 -0
  33. package/prometheus.yml +36 -0
  34. package/src/api/core/core.controller.js +69 -0
  35. package/src/api/core/core.model.js +11 -0
  36. package/src/api/core/core.router.js +23 -0
  37. package/src/api/core/core.service.js +31 -0
  38. package/src/api/crypto/crypto.controller.js +51 -0
  39. package/src/api/crypto/crypto.model.js +23 -0
  40. package/src/api/crypto/crypto.router.js +20 -0
  41. package/src/api/crypto/crypto.service.js +64 -0
  42. package/src/api/default/default.controller.js +69 -0
  43. package/src/api/default/default.model.js +20 -0
  44. package/src/api/default/default.router.js +23 -0
  45. package/src/api/default/default.service.js +31 -0
  46. package/src/api/file/file.controller.js +53 -0
  47. package/src/api/file/file.model.js +19 -0
  48. package/src/api/file/file.router.js +21 -0
  49. package/src/api/file/file.service.js +80 -0
  50. package/src/api/instance/instance.controller.js +69 -0
  51. package/src/api/instance/instance.model.js +36 -0
  52. package/src/api/instance/instance.router.js +33 -0
  53. package/src/api/instance/instance.service.js +48 -0
  54. package/src/api/test/test.controller.js +59 -0
  55. package/src/api/test/test.model.js +14 -0
  56. package/src/api/test/test.router.js +21 -0
  57. package/src/api/test/test.service.js +35 -0
  58. package/src/api/user/user.build.js +16 -0
  59. package/src/api/user/user.controller.js +70 -0
  60. package/src/api/user/user.model.js +65 -0
  61. package/src/api/user/user.router.js +345 -0
  62. package/src/api/user/user.service.js +479 -0
  63. package/src/api.js +23 -0
  64. package/src/client/Default.index.js +40 -0
  65. package/src/client/components/core/Account.js +290 -0
  66. package/src/client/components/core/AgGrid.js +160 -0
  67. package/src/client/components/core/Auth.js +19 -0
  68. package/src/client/components/core/Badge.js +32 -0
  69. package/src/client/components/core/Blockchain.js +41 -0
  70. package/src/client/components/core/Blog.js +9 -0
  71. package/src/client/components/core/BtnIcon.js +101 -0
  72. package/src/client/components/core/CalendarCore.js +458 -0
  73. package/src/client/components/core/Chat.js +64 -0
  74. package/src/client/components/core/ColorPalette.js +5267 -0
  75. package/src/client/components/core/CommonJs.js +742 -0
  76. package/src/client/components/core/Content.js +193 -0
  77. package/src/client/components/core/Css.js +846 -0
  78. package/src/client/components/core/CssCore.js +844 -0
  79. package/src/client/components/core/D3Chart.js +44 -0
  80. package/src/client/components/core/Docs.js +331 -0
  81. package/src/client/components/core/DropDown.js +164 -0
  82. package/src/client/components/core/EventsUI.js +46 -0
  83. package/src/client/components/core/FileExplorer.js +699 -0
  84. package/src/client/components/core/FullScreen.js +45 -0
  85. package/src/client/components/core/Input.js +346 -0
  86. package/src/client/components/core/JoyStick.js +77 -0
  87. package/src/client/components/core/Keyboard.js +73 -0
  88. package/src/client/components/core/LoadingAnimation.js +178 -0
  89. package/src/client/components/core/LogIn.js +187 -0
  90. package/src/client/components/core/LogOut.js +58 -0
  91. package/src/client/components/core/Logger.js +26 -0
  92. package/src/client/components/core/Modal.js +1814 -0
  93. package/src/client/components/core/NotificationManager.js +84 -0
  94. package/src/client/components/core/Panel.js +613 -0
  95. package/src/client/components/core/PanelForm.js +469 -0
  96. package/src/client/components/core/Polyhedron.js +162 -0
  97. package/src/client/components/core/Recover.js +204 -0
  98. package/src/client/components/core/Responsive.js +68 -0
  99. package/src/client/components/core/RichText.js +53 -0
  100. package/src/client/components/core/Router.js +76 -0
  101. package/src/client/components/core/Scroll.js +34 -0
  102. package/src/client/components/core/SignUp.js +125 -0
  103. package/src/client/components/core/SocketIo.js +72 -0
  104. package/src/client/components/core/Stream.js +113 -0
  105. package/src/client/components/core/ToggleSwitch.js +87 -0
  106. package/src/client/components/core/ToolTip.js +26 -0
  107. package/src/client/components/core/Translate.js +446 -0
  108. package/src/client/components/core/Validator.js +100 -0
  109. package/src/client/components/core/VanillaJs.js +463 -0
  110. package/src/client/components/core/Wallet.js +106 -0
  111. package/src/client/components/core/WebComponent.js +44 -0
  112. package/src/client/components/core/Webhook.js +25 -0
  113. package/src/client/components/core/Worker.js +280 -0
  114. package/src/client/components/default/CommonDefault.js +29 -0
  115. package/src/client/components/default/CssDefault.js +13 -0
  116. package/src/client/components/default/ElementsDefault.js +38 -0
  117. package/src/client/components/default/LogInDefault.js +41 -0
  118. package/src/client/components/default/LogOutDefault.js +28 -0
  119. package/src/client/components/default/MenuDefault.js +389 -0
  120. package/src/client/components/default/RoutesDefault.js +48 -0
  121. package/src/client/components/default/SettingsDefault.js +16 -0
  122. package/src/client/components/default/SignUpDefault.js +9 -0
  123. package/src/client/components/default/SocketIoDefault.js +54 -0
  124. package/src/client/components/default/TranslateDefault.js +7 -0
  125. package/src/client/public/default/android-chrome-144x144.png +0 -0
  126. package/src/client/public/default/android-chrome-192x192.png +0 -0
  127. package/src/client/public/default/android-chrome-256x256.png +0 -0
  128. package/src/client/public/default/android-chrome-36x36.png +0 -0
  129. package/src/client/public/default/android-chrome-384x384.png +0 -0
  130. package/src/client/public/default/android-chrome-48x48.png +0 -0
  131. package/src/client/public/default/android-chrome-512x512.png +0 -0
  132. package/src/client/public/default/android-chrome-72x72.png +0 -0
  133. package/src/client/public/default/android-chrome-96x96.png +0 -0
  134. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  135. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  136. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  137. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  138. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  139. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  140. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  141. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  142. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  143. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  144. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  145. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  146. package/src/client/public/default/apple-touch-icon.png +0 -0
  147. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  148. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  149. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  150. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  151. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  152. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  153. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  154. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  155. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  156. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  157. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  158. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  159. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  160. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  161. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  162. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  163. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  164. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  165. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  166. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  167. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  168. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  169. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  170. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  171. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  172. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  173. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  174. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  175. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  176. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  177. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  178. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  179. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  180. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  181. package/src/client/public/default/assets/background/white.jpg +0 -0
  182. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  183. package/src/client/public/default/assets/background/white0.jpg +0 -0
  184. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  185. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  186. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  187. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  188. package/src/client/public/default/browserconfig.xml +12 -0
  189. package/src/client/public/default/favicon-16x16.png +0 -0
  190. package/src/client/public/default/favicon-32x32.png +0 -0
  191. package/src/client/public/default/favicon-48x48.png +0 -0
  192. package/src/client/public/default/favicon.ico +0 -0
  193. package/src/client/public/default/manifest.webmanifest +69 -0
  194. package/src/client/public/default/mstile-144x144.png +0 -0
  195. package/src/client/public/default/mstile-150x150.png +0 -0
  196. package/src/client/public/default/mstile-310x150.png +0 -0
  197. package/src/client/public/default/mstile-310x310.png +0 -0
  198. package/src/client/public/default/mstile-70x70.png +0 -0
  199. package/src/client/public/default/plantuml/client-conf.svg +1 -0
  200. package/src/client/public/default/plantuml/client-schema.svg +1 -0
  201. package/src/client/public/default/plantuml/cron-conf.svg +1 -0
  202. package/src/client/public/default/plantuml/cron-schema.svg +1 -0
  203. package/src/client/public/default/plantuml/server-conf.svg +1 -0
  204. package/src/client/public/default/plantuml/server-schema.svg +1 -0
  205. package/src/client/public/default/plantuml/ssr-conf.svg +1 -0
  206. package/src/client/public/default/plantuml/ssr-schema.svg +1 -0
  207. package/src/client/public/default/site.webmanifest +69 -0
  208. package/src/client/public/default/sitemap +148 -0
  209. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  210. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  211. package/src/client/public/doc/favicon.ico +0 -0
  212. package/src/client/public/doc/sitemap +148 -0
  213. package/src/client/public/test/favicon.ico +0 -0
  214. package/src/client/public/test/sitemap +148 -0
  215. package/src/client/services/core/core.service.js +170 -0
  216. package/src/client/services/crypto/crypto.service.js +70 -0
  217. package/src/client/services/default/default.management.js +343 -0
  218. package/src/client/services/default/default.service.js +89 -0
  219. package/src/client/services/file/file.service.js +70 -0
  220. package/src/client/services/instance/instance.management.js +74 -0
  221. package/src/client/services/instance/instance.service.js +89 -0
  222. package/src/client/services/test/test.service.js +70 -0
  223. package/src/client/services/user/user.management.js +50 -0
  224. package/src/client/services/user/user.service.js +89 -0
  225. package/src/client/ssr/Render.js +237 -0
  226. package/src/client/ssr/common/Alert.js +75 -0
  227. package/src/client/ssr/common/SsrCore.js +91 -0
  228. package/src/client/ssr/common/Translate.js +26 -0
  229. package/src/client/ssr/common/Worker.js +28 -0
  230. package/src/client/ssr/components/body/CacheControl.js +114 -0
  231. package/src/client/ssr/components/body/DefaultSplashScreen.js +90 -0
  232. package/src/client/ssr/components/email/DefaultRecoverEmail.js +21 -0
  233. package/src/client/ssr/components/email/DefaultVerifyEmail.js +17 -0
  234. package/src/client/ssr/components/head/Css.js +241 -0
  235. package/src/client/ssr/components/head/DefaultScripts.js +3 -0
  236. package/src/client/ssr/components/head/Production.js +1 -0
  237. package/src/client/ssr/components/head/Pwa.js +146 -0
  238. package/src/client/ssr/components/head/PwaDefault.js +60 -0
  239. package/src/client/ssr/components/head/Seo.js +14 -0
  240. package/src/client/ssr/pages/404.js +12 -0
  241. package/src/client/ssr/pages/500.js +12 -0
  242. package/src/client/ssr/pages/maintenance.js +14 -0
  243. package/src/client/ssr/pages/offline.js +21 -0
  244. package/src/client/sw/default.sw.js +205 -0
  245. package/src/client/sw/template.sw.js +84 -0
  246. package/src/client.build.js +22 -0
  247. package/src/client.dev.js +21 -0
  248. package/src/db/DataBaseProvider.js +45 -0
  249. package/src/db/mariadb/MariaDB.js +33 -0
  250. package/src/db/mongo/MongooseDB.js +124 -0
  251. package/src/dns.js +22 -0
  252. package/src/index.js +43 -0
  253. package/src/mailer/EmailRender.js +69 -0
  254. package/src/mailer/MailerProvider.js +96 -0
  255. package/src/proxy.js +22 -0
  256. package/src/runtime/lampp/Lampp.js +115 -0
  257. package/src/runtime/nginx/Nginx.js +3 -0
  258. package/src/runtime/xampp/Xampp.js +49 -0
  259. package/src/server/auth.js +235 -0
  260. package/src/server/backup.js +120 -0
  261. package/src/server/client-build-live.js +98 -0
  262. package/src/server/client-build.js +754 -0
  263. package/src/server/client-dev-server.js +60 -0
  264. package/src/server/client-formatted.js +58 -0
  265. package/src/server/client-icons.js +151 -0
  266. package/src/server/conf.js +929 -0
  267. package/src/server/crypto.js +91 -0
  268. package/src/server/dns.js +118 -0
  269. package/src/server/downloader.js +42 -0
  270. package/src/server/logger.js +190 -0
  271. package/src/server/network.js +209 -0
  272. package/src/server/peer.js +33 -0
  273. package/src/server/process.js +66 -0
  274. package/src/server/prompt-optimizer.js +28 -0
  275. package/src/server/proxy.js +118 -0
  276. package/src/server/runtime.js +463 -0
  277. package/src/server/ssl.js +120 -0
  278. package/src/server.js +25 -0
  279. package/src/ws/IoInterface.js +45 -0
  280. package/src/ws/IoServer.js +39 -0
  281. package/src/ws/core/channels/core.ws.chat.js +23 -0
  282. package/src/ws/core/channels/core.ws.mailer.js +35 -0
  283. package/src/ws/core/channels/core.ws.stream.js +31 -0
  284. package/src/ws/core/core.ws.connection.js +28 -0
  285. package/src/ws/core/core.ws.emit.js +14 -0
  286. package/src/ws/core/core.ws.server.js +24 -0
  287. package/src/ws/core/management/core.ws.chat.js +8 -0
  288. package/src/ws/core/management/core.ws.mailer.js +16 -0
  289. package/src/ws/core/management/core.ws.stream.js +8 -0
  290. package/src/ws/default/channels/default.ws.main.js +16 -0
  291. package/src/ws/default/default.ws.connection.js +22 -0
  292. package/src/ws/default/default.ws.emit.js +14 -0
  293. package/src/ws/default/default.ws.server.js +20 -0
  294. package/src/ws/default/management/default.ws.main.js +8 -0
  295. package/startup.js +11 -0
  296. package/supervisord-openssh-server.conf +5 -0
  297. package/test/api.test.js +60 -0
@@ -0,0 +1,96 @@
1
+ import nodemailer from 'nodemailer';
2
+ import { loggerFactory } from '../server/logger.js';
3
+ import { EmailRender } from './EmailRender.js';
4
+
5
+ const logger = loggerFactory(import.meta);
6
+
7
+ const MailerProvider = {
8
+ instance: {},
9
+ load: async function (
10
+ options = {
11
+ id: '',
12
+ meta: 'mailer',
13
+ sender: {
14
+ email: '',
15
+ name: '',
16
+ },
17
+ transport: {
18
+ host: '', // smtp host
19
+ port: 587,
20
+ secure: false, // true for 465, false for other ports
21
+ auth: {
22
+ user: '', // generated ethereal user
23
+ pass: '', // generated ethereal password
24
+ },
25
+ },
26
+ host: '',
27
+ path: '',
28
+ templates: ['SsrTemplate'],
29
+ },
30
+ ) {
31
+ try {
32
+ const { id } = options;
33
+ // Generate test SMTP service account from ethereal.email
34
+ // Only needed if you don't have a real mail account for testing
35
+ // let testAccount = await nodemailer.createTestAccount();
36
+
37
+ // create reusable transporter object using the default SMTP transport
38
+ const transporter = nodemailer.createTransport(options.transport);
39
+
40
+ // console.log('load logger', { url: options.meta });
41
+ this.instance[id] = {
42
+ ...options,
43
+ transporter,
44
+ templates: await EmailRender.getTemplates(options),
45
+ };
46
+
47
+ return this.instance[id];
48
+ } catch (error) {
49
+ logger.error(error, error.stack);
50
+ return undefined;
51
+ }
52
+ },
53
+ send: async function (
54
+ options = {
55
+ id: '',
56
+ sendOptions: {
57
+ from: '"Fred Foo 👻" <foo@example.com>', // sender address
58
+ to: 'bar@example.com, baz@example.com', // list of receivers
59
+ subject: 'Hello ✔', // Subject line
60
+ text: 'Hello world?', // plain text body
61
+ html: '<b>Hello world?</b>', // html body
62
+ attachments: [
63
+ {
64
+ filename: 'logo.png',
65
+ path: `./logo.png`,
66
+ cid: 'logo', // <img src='cid:logo'>
67
+ },
68
+ ],
69
+ },
70
+ },
71
+ ) {
72
+ try {
73
+ const { id, sendOptions } = options;
74
+ if (!sendOptions.from) sendOptions.from = `${this.instance[id].sender.name} <${this.instance[id].sender.email}>`;
75
+
76
+ // send mail with defined transport object
77
+ const info = await this.instance[id].transporter.sendMail(sendOptions);
78
+
79
+ // console.log('Message sent: %s', info.messageId);
80
+ // logger.info('Message sent', info);
81
+
82
+ // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
83
+
84
+ // Preview only available when sending through an Ethereal account
85
+ // console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
86
+ // Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
87
+
88
+ return info;
89
+ } catch (error) {
90
+ logger.error(error, error.stack);
91
+ return undefined;
92
+ }
93
+ },
94
+ };
95
+
96
+ export { MailerProvider };
package/src/proxy.js ADDED
@@ -0,0 +1,22 @@
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 { buildProxy } from './server/proxy.js';
9
+ import { ProcessController } from './server/process.js';
10
+ import { Config } from './server/conf.js';
11
+
12
+ dotenv.config();
13
+
14
+ await Config.build();
15
+
16
+ const logger = loggerFactory(import.meta);
17
+
18
+ await logger.setUpInfo();
19
+
20
+ await buildProxy();
21
+
22
+ ProcessController.init(logger);
@@ -0,0 +1,115 @@
1
+ import fs from 'fs-extra';
2
+ import { network } from '../../server/network.js';
3
+ import { shellCd, shellExec } from '../../server/process.js';
4
+ import { timer } from '../../client/components/core/CommonJs.js';
5
+ import { loggerFactory } from '../../server/logger.js';
6
+
7
+ const logger = loggerFactory(import.meta);
8
+
9
+ const Lampp = {
10
+ ports: [],
11
+ initService: async function (options = { daemon: false }) {
12
+ let cmd;
13
+ // linux
14
+ fs.writeFileSync(`/opt/lampp/apache2/conf/httpd.conf`, this.router || '', 'utf8');
15
+ cmd = `sudo /opt/lampp/lampp stop`;
16
+ if (!fs.readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8').match(`# Listen 80`))
17
+ fs.writeFileSync(
18
+ `/opt/lampp/etc/httpd.conf`,
19
+ fs.readFileSync(`/opt/lampp/etc/httpd.conf`, 'utf8').replace(`Listen 80`, `# Listen 80`),
20
+ 'utf8',
21
+ );
22
+ if (!fs.readFileSync(`/opt/lampp/etc/extra/httpd-ssl.conf`, 'utf8').match(`# Listen 443`))
23
+ fs.writeFileSync(
24
+ `/opt/lampp/etc/extra/httpd-ssl.conf`,
25
+ fs.readFileSync(`/opt/lampp/etc/extra/httpd-ssl.conf`, 'utf8').replace(`Listen 443`, `# Listen 443`),
26
+ 'utf8',
27
+ );
28
+ if (!fs.readFileSync(`/opt/lampp/lampp`, 'utf8').match(`testport 443 && false`))
29
+ fs.writeFileSync(
30
+ `/opt/lampp/lampp`,
31
+ fs.readFileSync(`/opt/lampp/lampp`, 'utf8').replace(`testport 443`, `testport 443 && false`),
32
+ 'utf8',
33
+ );
34
+ if (!fs.readFileSync(`/opt/lampp/lampp`, 'utf8').match(`testport 80 && false`))
35
+ fs.writeFileSync(
36
+ `/opt/lampp/lampp`,
37
+ fs.readFileSync(`/opt/lampp/lampp`, 'utf8').replace(`testport 80`, `testport 80 && false`),
38
+ 'utf8',
39
+ );
40
+
41
+ shellExec(cmd);
42
+ await network.port.portClean(3306);
43
+ for (const port of this.ports) await network.port.portClean(port);
44
+ cmd = `sudo /opt/lampp/lampp start`;
45
+ if (this.router) fs.writeFileSync(`./tmp/lampp-router.conf`, this.router, 'utf-8');
46
+ shellExec(cmd, { async: true });
47
+ if (options && options.daemon) this.daemon();
48
+ },
49
+ daemon: async function () {
50
+ await timer(1000 * 60 * 2); // 2 minutes
51
+ for (const port of this.ports) {
52
+ const [portStatus] = await network.port.status([port]);
53
+ if (!portStatus.open) return await this.initService();
54
+ }
55
+ this.daemon();
56
+ },
57
+ enabled: () => fs.existsSync(`/opt/lampp/apache2/conf/httpd.conf`),
58
+ appendRouter: function (render) {
59
+ if (!this.router) {
60
+ if (fs.existsSync(`./tmp/lampp-router.conf`))
61
+ return (this.router = fs.readFileSync(`./tmp/lampp-router.conf`, 'utf-8')) + render;
62
+ return (this.router = render);
63
+ }
64
+ return (this.router += render);
65
+ },
66
+ removeRouter: function () {
67
+ this.router = undefined;
68
+ if (fs.existsSync(`./tmp/lampp-router.conf`)) fs.rmSync(`./tmp/lampp-router.conf`);
69
+ },
70
+ install: async function () {
71
+ switch (process.platform) {
72
+ case 'linux':
73
+ {
74
+ if (!fs.existsSync(`./engine-private/setup`)) fs.mkdirSync(`./engine-private/setup`, { recursive: true });
75
+
76
+ shellCd(`./engine-private/setup`);
77
+
78
+ if (!process.argv.includes(`server`)) {
79
+ shellExec(
80
+ `curl -Lo xampp-linux-installer.run https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.30/xampp-linux-x64-7.4.30-1-installer.run?from_af=true`,
81
+ );
82
+ shellExec(`sudo chmod +x xampp-linux-installer.run`);
83
+ shellExec(
84
+ `sudo ./xampp-linux-installer.run --mode unattended && \\` +
85
+ `ln -sf /opt/lampp/lampp /usr/bin/lampp && \\` +
86
+ `sed -i.bak s'/Require local/Require all granted/g' /opt/lampp/etc/extra/httpd-xampp.conf && \\` +
87
+ `sed -i.bak s'/display_errors=Off/display_errors=On/g' /opt/lampp/etc/php.ini && \\` +
88
+ `mkdir /opt/lampp/apache2/conf.d && \\` +
89
+ `echo "IncludeOptional /opt/lampp/apache2/conf.d/*.conf" >> /opt/lampp/etc/httpd.conf && \\` +
90
+ `mkdir /www && \\` +
91
+ `ln -s /www /opt/lampp/htdocs`,
92
+ );
93
+
94
+ if (fs.existsSync(`/opt/lampp/logs/access_log`))
95
+ fs.copySync(`/opt/lampp/logs/access_log`, `/opt/lampp/logs/access.log`);
96
+ if (fs.existsSync(`/opt/lampp/logs/error_log`))
97
+ fs.copySync(`/opt/lampp/logs/error_log`, `/opt/lampp/logs/error.log`);
98
+ if (fs.existsSync(`/opt/lampp/logs/php_error_log`))
99
+ fs.copySync(`/opt/lampp/logs/php_error_log`, `/opt/lampp/logs/php_error.log`);
100
+ if (fs.existsSync(`/opt/lampp/logs/ssl_request_log`))
101
+ fs.copySync(`/opt/lampp/logs/ssl_request_log`, `/opt/lampp/logs/ssl_request.log`);
102
+ }
103
+
104
+ await Lampp.initService({ daemon: true });
105
+ }
106
+
107
+ break;
108
+
109
+ default:
110
+ break;
111
+ }
112
+ },
113
+ };
114
+
115
+ export { Lampp };
@@ -0,0 +1,3 @@
1
+ const Nginx = {};
2
+
3
+ export { Nginx };
@@ -0,0 +1,49 @@
1
+ import fs from 'fs-extra';
2
+ import { network } from '../../server/network.js';
3
+ import { shellExec } from '../../server/process.js';
4
+ import { timer } from '../../client/components/core/CommonJs.js';
5
+
6
+ const Xampp = {
7
+ ports: [],
8
+ initService: async function (options = { daemon: false }) {
9
+ let cmd;
10
+ // windows
11
+ fs.writeFileSync(
12
+ `C:/xampp/apache/conf/httpd.conf`,
13
+ fs.readFileSync(`C:/xampp/apache/conf/httpd.template.conf`, 'utf8').replace(`Listen 80`, ``),
14
+ 'utf8',
15
+ );
16
+ fs.writeFileSync(`C:/xampp/apache/conf/extra/httpd-ssl.conf`, this.router || '', 'utf8');
17
+ cmd = `C:/xampp/xampp_stop.exe`;
18
+ shellExec(cmd);
19
+ await network.port.portClean(3306);
20
+ for (const port of this.ports) await network.port.portClean(port);
21
+ cmd = `C:/xampp/xampp_start.exe`;
22
+ if (this.router) fs.writeFileSync(`./tmp/xampp-router.conf`, this.router, 'utf-8');
23
+ shellExec(cmd);
24
+ if (options && options.daemon) this.daemon();
25
+ },
26
+ daemon: async function () {
27
+ await timer(1000 * 60 * 2); // 2 minutes
28
+ for (const port of this.ports) {
29
+ const [portStatus] = await network.port.status([port]);
30
+ if (!portStatus.open) return await this.initService();
31
+ }
32
+ this.daemon();
33
+ },
34
+ enabled: () => fs.existsSync(`C:/xampp/apache/conf/httpd.conf`),
35
+ appendRouter: function (render) {
36
+ if (!this.router) {
37
+ if (fs.existsSync(`./tmp/xampp-router.conf`))
38
+ return (this.router = fs.readFileSync(`./tmp/xampp-router.conf`, 'utf-8')) + render;
39
+ return (this.router = render);
40
+ }
41
+ return (this.router += render);
42
+ },
43
+ removeRouter: function () {
44
+ this.router = undefined;
45
+ if (fs.existsSync(`./tmp/xampp-router.conf`)) fs.rmSync(`./tmp/xampp-router.conf`);
46
+ },
47
+ };
48
+
49
+ export { Xampp };
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Module for managing identity and authorization
3
+ * @module src/server/auth.js
4
+ * @namespace Auth
5
+ */
6
+
7
+ import dotenv from 'dotenv';
8
+ import jwt from 'jsonwebtoken';
9
+ import { loggerFactory } from './logger.js';
10
+ import crypto from 'crypto';
11
+ import { userRoleEnum } from '../api/user/user.model.js';
12
+ import { validatePassword } from '../client/components/core/CommonJs.js';
13
+
14
+ dotenv.config();
15
+
16
+ const logger = loggerFactory(import.meta);
17
+
18
+ /* The `const config` object is defining parameters related to the hashing process used for password
19
+ security. Here's a breakdown of each property in the `config` object: */
20
+ const config = {
21
+ hashBytes: 32,
22
+ saltBytes: 16,
23
+ iterations: 872791,
24
+ digest: 'sha512',
25
+ };
26
+
27
+ /**
28
+ * @param {String} password - given password to hash
29
+ * @returns {String} the hash corresponding to the password
30
+ * @memberof Auth
31
+ */
32
+ function hashPassword(password) {
33
+ const { iterations, hashBytes, digest, saltBytes } = config;
34
+ const salt = crypto.randomBytes(saltBytes).toString('hex');
35
+ const hash = crypto.pbkdf2Sync(password, salt, iterations, hashBytes, digest).toString('hex');
36
+ return [salt, hash].join('$');
37
+ }
38
+
39
+ /**
40
+ * @param {String} password - password to verify
41
+ * @param {String} combined - a combined salt + hash returned by hashPassword function
42
+ * @returns {Boolean} true if password correspond to the hash. False otherwise
43
+ * @memberof Auth
44
+ */
45
+ function verifyPassword(password, combined) {
46
+ const { iterations, hashBytes, digest } = config;
47
+ const [salt, originalHash] = combined.split('$');
48
+ const hash = crypto.pbkdf2Sync(password, salt, iterations, hashBytes, digest).toString('hex');
49
+ return hash === originalHash;
50
+ }
51
+
52
+ // jwt middleware
53
+
54
+ /**
55
+ * The hashJWT function generates a JSON Web Token (JWT) with a specified payload and expiration time.
56
+ * @param payload - The `payload` parameter in the `hashJWT` function is the data that you want to
57
+ * encode into the JSON Web Token (JWT). It typically contains information about the user or any other
58
+ * relevant data that you want to securely transmit.
59
+ * @param expire - The `expire` parameter in the `hashJWT` function is used to specify the expiration
60
+ * time for the JSON Web Token (JWT) being generated. If a value is provided for `expire`, it will be
61
+ * used as the expiration time. If `expire` is not provided (i.e., it
62
+ * @memberof Auth
63
+ */
64
+ const hashJWT = (payload, expire) =>
65
+ jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: expire !== undefined ? expire : `${process.env.EXPIRE}h` });
66
+
67
+ /**
68
+ * The function `verifyJWT` is used to verify a JSON Web Token (JWT) using a secret key stored in the
69
+ * environment variables.
70
+ * @param token - The `token` parameter is a JSON Web Token (JWT) that is passed to the `verifyJWT`
71
+ * function for verification.
72
+ * @memberof Auth
73
+ */
74
+ const verifyJWT = (token = '') => jwt.verify(token, process.env.JWT_SECRET);
75
+
76
+ /**
77
+ * The function `getBearerToken` extracts and returns the Bearer token from the Authorization header in
78
+ * a request object.
79
+ * @param req - The `req` parameter in the `getBearerToken` function is typically an object
80
+ * representing the HTTP request. It is commonly used in Node.js applications with frameworks like
81
+ * Express.js. The `req` object contains information about the incoming HTTP request, including
82
+ * headers, body, parameters, and more. In
83
+ * @returns {String} The function `getBearerToken` is returning the Bearer token extracted from the
84
+ * Authorization header in the request object. If the Authorization header starts with 'Bearer ', it
85
+ * will return the token portion of the header (excluding 'Bearer ').
86
+ * @memberof Auth
87
+ */
88
+ const getBearerToken = (req) => {
89
+ const authHeader = String(req.headers['authorization'] || req.headers['Authorization'] || '');
90
+ if (authHeader.startsWith('Bearer ')) return authHeader.substring(7, authHeader.length);
91
+ return '';
92
+ };
93
+
94
+ /**
95
+ * The function `getPayloadJWT` extracts and verifies a JWT payload from a request using a bearer
96
+ * token.
97
+ * @param req - The `req` parameter is typically used in web development to represent the HTTP request
98
+ * object. It contains information about the incoming request, such as headers, parameters, and body
99
+ * data. In this context, it seems like the `getPayloadJWT` function is designed to extract and verify
100
+ * a JWT token from
101
+ * @returns {Object} The JWT payload from a request using a bearer
102
+ * @memberof Auth
103
+ */
104
+ const getPayloadJWT = (req) => verifyJWT(getBearerToken(req));
105
+
106
+ /**
107
+ * The authMiddleware function checks and verifies the authorization token in the request headers
108
+ * before allowing access to protected routes.
109
+ * @param req - The `req` parameter in the `authMiddleware` function stands for the request object. It
110
+ * contains information about the HTTP request made to the server, including headers, body, parameters,
111
+ * and more. In this context, the function is extracting the authorization token from the request
112
+ * headers to authenticate the user.
113
+ * @param res - The `res` parameter in the `authMiddleware` function is the response object that
114
+ * represents the HTTP response that an Express.js server sends when it receives an HTTP request. It is
115
+ * used to send a response back to the client with status codes, headers, and data.
116
+ * @param next - The `next` parameter in the `authMiddleware` function is a callback function that is
117
+ * used to pass control to the next middleware function in the stack. When called, it invokes the next
118
+ * middleware function in the chain. This is a common pattern in Express.js middleware functions to
119
+ * move to the next middleware
120
+ * @returns {Object} The `req.auth` included JWT payload in request authorization
121
+ * @memberof Auth
122
+ */
123
+ const authMiddleware = (req, res, next) => {
124
+ try {
125
+ const token = getBearerToken(req);
126
+ if (token) {
127
+ const payload = verifyJWT(token);
128
+ req.auth = payload;
129
+ return next();
130
+ } else
131
+ return res.status(401).json({
132
+ status: 'error',
133
+ message: 'unauthorized: invalid token',
134
+ });
135
+ } catch (error) {
136
+ logger.error(error, error.stack);
137
+ return res.status(400).json({
138
+ status: 'error',
139
+ message: error.message,
140
+ });
141
+ }
142
+ };
143
+
144
+ /**
145
+ * The `adminGuard` function checks if the user has admin role permission and returns an error message
146
+ * if not.
147
+ * @param req - The `req` parameter typically represents the HTTP request object in Node.js. It
148
+ * contains information about the incoming request such as the request headers, parameters, body, and
149
+ * more. In the context of your `adminGuard` function, `req` is the request object that is being passed
150
+ * to the middleware
151
+ * @param res - The `res` parameter in the `adminGuard` function is the response object in Express.js.
152
+ * It is used to send a response back to the client making the HTTP request.
153
+ * @param next - The `next` parameter in the `adminGuard` function is a callback function that is used
154
+ * to pass control to the next middleware function in the stack. When called, it executes the next
155
+ * middleware function. If there are no more middleware functions in the stack, it will proceed to the
156
+ * route handler.
157
+ * @returns The `adminGuard` function is returning either a 403 status with an error message if the
158
+ * user role is not 'admin', or it is calling the `next()` function to proceed to the next middleware
159
+ * if the user role is 'admin'. If an error occurs during the process, it will log the error and return
160
+ * a 400 status with the error message.
161
+ * @memberof Auth
162
+ */
163
+ const adminGuard = (req, res, next) => {
164
+ try {
165
+ if (!(userRoleEnum.indexOf(req.auth.user.role) === userRoleEnum.indexOf('admin')))
166
+ return res.status(403).json({ status: 'error', message: 'Insufficient permission' });
167
+ return next();
168
+ } catch (error) {
169
+ logger.error(error, error.stack);
170
+ return res.status(400).json({
171
+ status: 'error',
172
+ message: error.message,
173
+ });
174
+ }
175
+ };
176
+
177
+ /**
178
+ * The function `moderatorGuard` checks if the user's role is at least a moderator and handles errors
179
+ * accordingly.
180
+ * @param req - The `req` parameter in the `moderatorGuard` function typically represents the HTTP
181
+ * request object, which contains information about the incoming request such as headers, parameters,
182
+ * body, etc. It is commonly used to access data sent from the client to the server.
183
+ * @param res - The `res` parameter in the `moderatorGuard` function is the response object in
184
+ * Express.js. It is used to send a response back to the client making the HTTP request.
185
+ * @param next - The `next` parameter in the `moderatorGuard` function is a callback function that is
186
+ * used to pass control to the next middleware function in the stack. When called, it will execute the
187
+ * next middleware function. In the context of Express.js middleware, `next` is typically called to
188
+ * move to
189
+ * @returns In the `moderatorGuard` function, if the user's role is not a moderator or higher, a 403
190
+ * status with an error message "Insufficient permission" is returned. If there is an error during the
191
+ * process, a 400 status with the error message is returned. If everything is successful, the `next()`
192
+ * function is called to proceed to the next middleware in the chain.
193
+ * @memberof Auth
194
+ */
195
+ const moderatorGuard = (req, res, next) => {
196
+ try {
197
+ if (!(userRoleEnum.indexOf(req.auth.user.role) <= userRoleEnum.indexOf('moderator')))
198
+ return res.status(403).json({ status: 'error', message: 'Insufficient permission' });
199
+ return next();
200
+ } catch (error) {
201
+ logger.error(error, error.stack);
202
+ return res.status(400).json({
203
+ status: 'error',
204
+ message: error.message,
205
+ });
206
+ }
207
+ };
208
+
209
+ const validatePasswordMiddleware = (req, password) => {
210
+ let errors = [];
211
+ if (req.body && 'password' in req.body) errors = validatePassword(req.body.password);
212
+ if (errors.length > 0)
213
+ return {
214
+ status: 'error',
215
+ message:
216
+ 'Password, ' + errors.map((e, i) => (i > 0 ? ', ' : '') + (e[req.lang] ? e[req.lang] : e['en'])).join(''),
217
+ };
218
+ else
219
+ return {
220
+ status: 'success',
221
+ };
222
+ };
223
+
224
+ export {
225
+ authMiddleware,
226
+ hashPassword,
227
+ verifyPassword,
228
+ hashJWT,
229
+ adminGuard,
230
+ moderatorGuard,
231
+ verifyJWT,
232
+ validatePasswordMiddleware,
233
+ getBearerToken,
234
+ getPayloadJWT,
235
+ };
@@ -0,0 +1,120 @@
1
+ import fs from 'fs-extra';
2
+ import { loggerFactory } from './logger.js';
3
+ import { shellCd, shellExec } from './process.js';
4
+ import { getCronBackUpFolder, getDataDeploy } from './conf.js';
5
+ import dotenv from 'dotenv';
6
+
7
+ dotenv.config();
8
+
9
+ const logger = loggerFactory(import.meta);
10
+
11
+ const BackUpManagement = {
12
+ repoUrl: `https://${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_USERNAME}/${process.env.GITHUB_BACKUP_REPO}.git`,
13
+ Init: async function ({ deployId }) {
14
+ const Callback = async function () {
15
+ const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`;
16
+
17
+ const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
18
+
19
+ const { backups } = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
20
+
21
+ if (!backups) return;
22
+
23
+ logger.info('init backups callback');
24
+ await logger.setUpInfo();
25
+
26
+ const currentDate = new Date().getTime();
27
+
28
+ if (!fs.existsSync('./engine-private/cron-backups'))
29
+ fs.mkdirSync('./engine-private/cron-backups', { recursive: true });
30
+
31
+ for (const deployGroupData of backups) {
32
+ const { deployGroupId } = deployGroupData;
33
+ const dataDeploy = getDataDeploy({ deployGroupId });
34
+
35
+ for (const deployObj of dataDeploy) {
36
+ const { deployId, replicaHost } = deployObj;
37
+
38
+ if (replicaHost) continue;
39
+
40
+ const confServer = JSON.parse(
41
+ fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
42
+ ? fs.readFileSync(`./engine-private/replica/${deployId}/conf.server.json`, 'utf8')
43
+ : fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
44
+ );
45
+
46
+ for (const host of Object.keys(confServer))
47
+ for (const path of Object.keys(confServer[host])) {
48
+ // retention policy
49
+ let { db, backupFrequency, maxBackupRetention, singleReplica, wp, git, directory } =
50
+ confServer[host][path];
51
+
52
+ if (!db || singleReplica) continue;
53
+
54
+ if (!backupFrequency) backupFrequency = 'daily';
55
+ if (!maxBackupRetention) maxBackupRetention = 5;
56
+
57
+ const backUpPath = `${process.cwd()}/engine-private/cron-backups/${getCronBackUpFolder(host, path)}`;
58
+ if (!fs.existsSync(backUpPath)) fs.mkdirSync(`${backUpPath}`, { recursive: true });
59
+ // .isDirectory()
60
+ const files = await fs.readdir(backUpPath, { withFileTypes: true });
61
+
62
+ const currentBackupsDirs = files
63
+ .map((fileObj) => parseInt(fileObj.name))
64
+ .sort((a, b) => a - b)
65
+ .reverse();
66
+
67
+ switch (backupFrequency) {
68
+ case 'daily':
69
+
70
+ default:
71
+ // if (currentBackupsDirs[0] && currentDate - currentBackupsDirs[0] < 1000 * 60 * 60 * 24) continue;
72
+ break;
73
+ }
74
+
75
+ for (const retentionPath of currentBackupsDirs.filter((t, i) => i >= maxBackupRetention - 1)) {
76
+ const removePathRetention = `${backUpPath}/${retentionPath}`;
77
+ logger.info('Remove backup folder', removePathRetention);
78
+ fs.removeSync(removePathRetention);
79
+ }
80
+
81
+ fs.mkdirSync(`${backUpPath}/${currentDate}`, { recursive: true });
82
+
83
+ shellExec(`node bin/db ${host}${path} export ${deployId} ${backUpPath}/${currentDate}`);
84
+
85
+ if (wp) {
86
+ const repoUrl = `https://${process.env.GITHUB_TOKEN}@github.com/${process.env.GITHUB_USERNAME}/${git
87
+ .split('/')
88
+ .pop()}.git`;
89
+
90
+ shellExec(
91
+ `cd ${directory}` +
92
+ ` && git pull ${repoUrl}` +
93
+ ` && git add . && git commit -m "backup ${new Date().toLocaleDateString()}"` +
94
+ ` && git push ${repoUrl}`,
95
+ {
96
+ disableLog: true,
97
+ },
98
+ );
99
+ }
100
+ }
101
+ }
102
+ }
103
+ shellExec(
104
+ `cd ./engine-private/cron-backups` +
105
+ ` && git pull ${BackUpManagement.repoUrl}` +
106
+ ` && git add . && git commit -m "backup ${new Date().toLocaleDateString()}"` +
107
+ ` && git push ${BackUpManagement.repoUrl}`,
108
+ {
109
+ disableLog: true,
110
+ },
111
+ );
112
+ };
113
+ await Callback();
114
+ BackUpManagement.Callback = Callback;
115
+ return Callback;
116
+ },
117
+ Callback: async function (params) {},
118
+ };
119
+
120
+ export { BackUpManagement };