underpost 2.6.3 → 2.7.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 (216) hide show
  1. package/.dockerignore +13 -13
  2. package/.env.development +7 -7
  3. package/.env.production +7 -7
  4. package/.env.test +7 -7
  5. package/.github/workflows/publish.yml +26 -0
  6. package/.nycrc +9 -9
  7. package/.prettierignore +12 -12
  8. package/.prettierrc +9 -9
  9. package/.vscode/extensions.json +72 -72
  10. package/.vscode/settings.json +100 -99
  11. package/AUTHORS.md +10 -0
  12. package/CHANGELOG.md +91 -0
  13. package/Dockerfile +89 -89
  14. package/LICENSE +21 -21
  15. package/README.md +96 -96
  16. package/bin/db.js +172 -119
  17. package/bin/deploy.js +582 -626
  18. package/bin/dns.js +1 -1
  19. package/bin/file.js +92 -92
  20. package/bin/index.js +53 -34
  21. package/bin/install.js +398 -357
  22. package/bin/shortcut.js +44 -44
  23. package/bin/ssl.js +65 -61
  24. package/bin/util.js +182 -182
  25. package/bin/vs.js +35 -35
  26. package/conf.js +251 -249
  27. package/docker-compose.yml +67 -67
  28. package/jsconfig.json +7 -7
  29. package/jsdoc.json +32 -32
  30. package/nodemon.json +6 -6
  31. package/package.json +137 -128
  32. package/prometheus.yml +36 -36
  33. package/setup.sh +24 -24
  34. package/src/api/core/core.controller.js +69 -69
  35. package/src/api/core/core.model.js +11 -11
  36. package/src/api/core/core.router.js +23 -23
  37. package/src/api/core/core.service.js +29 -29
  38. package/src/api/crypto/crypto.controller.js +51 -51
  39. package/src/api/crypto/crypto.model.js +23 -23
  40. package/src/api/crypto/crypto.router.js +20 -20
  41. package/src/api/crypto/crypto.service.js +64 -64
  42. package/src/api/default/default.controller.js +69 -69
  43. package/src/api/default/default.model.js +20 -20
  44. package/src/api/default/default.router.js +23 -23
  45. package/src/api/default/default.service.js +31 -31
  46. package/src/api/file/file.controller.js +53 -51
  47. package/src/api/file/file.model.js +19 -19
  48. package/src/api/file/file.router.js +21 -20
  49. package/src/api/file/file.service.js +76 -70
  50. package/src/api/instance/instance.controller.js +69 -69
  51. package/src/api/instance/instance.model.js +36 -36
  52. package/src/api/instance/instance.router.js +33 -33
  53. package/src/api/instance/instance.service.js +48 -48
  54. package/src/api/test/test.controller.js +59 -59
  55. package/src/api/test/test.model.js +14 -14
  56. package/src/api/test/test.router.js +21 -21
  57. package/src/api/test/test.service.js +35 -35
  58. package/src/api/user/user.build.js +16 -0
  59. package/src/api/user/user.controller.js +70 -70
  60. package/src/api/user/user.model.js +65 -65
  61. package/src/api/user/user.router.js +345 -345
  62. package/src/api/user/user.service.js +479 -479
  63. package/src/api.js +23 -23
  64. package/src/client/Default.index.js +40 -40
  65. package/src/client/components/core/Account.js +290 -290
  66. package/src/client/components/core/AgGrid.js +160 -160
  67. package/src/client/components/core/Auth.js +19 -19
  68. package/src/client/components/core/Badge.js +32 -32
  69. package/src/client/components/core/BlockChain.js +41 -41
  70. package/src/client/components/core/Blog.js +9 -9
  71. package/src/client/components/core/BtnIcon.js +101 -94
  72. package/src/client/components/core/CalendarCore.js +458 -319
  73. package/src/client/components/core/Chat.js +64 -64
  74. package/src/client/components/core/ColorPalette.js +5267 -5267
  75. package/src/client/components/core/CommonJs.js +735 -732
  76. package/src/client/components/core/Content.js +193 -49
  77. package/src/client/components/core/Css.js +1064 -1027
  78. package/src/client/components/core/CssCore.js +817 -796
  79. package/src/client/components/core/D3Chart.js +44 -44
  80. package/src/client/components/core/Docs.js +229 -229
  81. package/src/client/components/core/DropDown.js +164 -164
  82. package/src/client/components/core/EventsUI.js +46 -54
  83. package/src/client/components/core/FileExplorer.js +699 -624
  84. package/src/client/components/core/FullScreen.js +45 -45
  85. package/src/client/components/core/Input.js +346 -259
  86. package/src/client/components/core/JoyStick.js +77 -77
  87. package/src/client/components/core/Keyboard.js +73 -73
  88. package/src/client/components/core/LoadingAnimation.js +179 -157
  89. package/src/client/components/core/LogIn.js +187 -181
  90. package/src/client/components/core/LogOut.js +58 -52
  91. package/src/client/components/core/Logger.js +26 -26
  92. package/src/client/components/core/Modal.js +1612 -1596
  93. package/src/client/components/core/NotificationManager.js +84 -84
  94. package/src/client/components/core/Panel.js +613 -413
  95. package/src/client/components/core/PanelForm.js +468 -0
  96. package/src/client/components/core/Polyhedron.js +162 -162
  97. package/src/client/components/core/Recover.js +204 -204
  98. package/src/client/components/core/Responsive.js +53 -53
  99. package/src/client/components/core/RichText.js +51 -27
  100. package/src/client/components/core/Router.js +76 -77
  101. package/src/client/components/core/Scroll.js +34 -0
  102. package/src/client/components/core/SignUp.js +125 -125
  103. package/src/client/components/core/SocketIo.js +72 -72
  104. package/src/client/components/core/Stream.js +113 -113
  105. package/src/client/components/core/ToggleSwitch.js +87 -87
  106. package/src/client/components/core/ToolTip.js +26 -26
  107. package/src/client/components/core/Translate.js +437 -408
  108. package/src/client/components/core/Validator.js +100 -100
  109. package/src/client/components/core/VanillaJs.js +460 -457
  110. package/src/client/components/core/Wallet.js +106 -106
  111. package/src/client/components/core/Webhook.js +25 -25
  112. package/src/client/components/core/Worker.js +272 -272
  113. package/src/client/components/default/CommonDefault.js +29 -29
  114. package/src/client/components/default/CssDefault.js +13 -13
  115. package/src/client/components/default/ElementsDefault.js +38 -38
  116. package/src/client/components/default/LogInDefault.js +41 -41
  117. package/src/client/components/default/LogOutDefault.js +28 -28
  118. package/src/client/components/default/MenuDefault.js +389 -389
  119. package/src/client/components/default/RoutesDefault.js +48 -48
  120. package/src/client/components/default/SettingsDefault.js +16 -16
  121. package/src/client/components/default/SignUpDefault.js +9 -9
  122. package/src/client/components/default/SocketIoDefault.js +54 -54
  123. package/src/client/components/default/TranslateDefault.js +7 -7
  124. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  125. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  126. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  127. package/src/client/public/default/browserconfig.xml +11 -11
  128. package/src/client/public/default/manifest.webmanifest +68 -68
  129. package/src/client/public/default/plantuml/client-conf.svg +1 -0
  130. package/src/client/public/default/plantuml/client-schema.svg +1 -0
  131. package/src/client/public/default/plantuml/cron-conf.svg +1 -0
  132. package/src/client/public/default/plantuml/cron-schema.svg +1 -0
  133. package/src/client/public/default/plantuml/server-conf.svg +1 -0
  134. package/src/client/public/default/plantuml/server-schema.svg +1 -0
  135. package/src/client/public/default/plantuml/ssr-conf.svg +1 -0
  136. package/src/client/public/default/plantuml/ssr-schema.svg +1 -0
  137. package/src/client/public/default/sitemap +147 -147
  138. package/src/client/public/default/yandex-browser-manifest.json +8 -8
  139. package/src/client/public/doc/sitemap +147 -147
  140. package/src/client/public/test/sitemap +147 -147
  141. package/src/client/services/core/core.service.js +170 -152
  142. package/src/client/services/crypto/crypto.service.js +70 -70
  143. package/src/client/services/default/default.management.js +345 -345
  144. package/src/client/services/default/default.service.js +89 -89
  145. package/src/client/services/file/file.service.js +70 -70
  146. package/src/client/services/instance/instance.management.js +74 -74
  147. package/src/client/services/instance/instance.service.js +89 -89
  148. package/src/client/services/test/test.service.js +70 -70
  149. package/src/client/services/user/user.management.js +50 -50
  150. package/src/client/services/user/user.service.js +89 -89
  151. package/src/client/ssr/Render.js +16 -16
  152. package/src/client/ssr/body-components/CacheControl.js +114 -113
  153. package/src/client/ssr/body-components/DefaultSplashScreen.js +79 -79
  154. package/src/client/ssr/email-components/DefaultRecoverEmail.js +21 -21
  155. package/src/client/ssr/email-components/DefaultVerifyEmail.js +17 -17
  156. package/src/client/ssr/head-components/Css.js +241 -241
  157. package/src/client/ssr/head-components/DefaultScripts.js +3 -3
  158. package/src/client/ssr/head-components/Microdata.js +11 -11
  159. package/src/client/ssr/head-components/Production.js +1 -1
  160. package/src/client/ssr/head-components/PwaDefault.js +59 -59
  161. package/src/client/ssr/head-components/Seo.js +14 -14
  162. package/src/client/sw/default.sw.js +201 -201
  163. package/src/client/sw/template.sw.js +84 -84
  164. package/src/client.build.js +22 -22
  165. package/src/client.dev.js +21 -21
  166. package/src/cron.js +25 -25
  167. package/src/db/DataBaseProvider.js +34 -34
  168. package/src/db/mariadb/MariaDB.js +33 -33
  169. package/src/db/mongo/MongooseDB.js +46 -46
  170. package/src/dns.js +22 -22
  171. package/src/index.js +42 -0
  172. package/src/mailer/EmailRender.js +69 -69
  173. package/src/mailer/MailerProvider.js +96 -96
  174. package/src/proxy.js +22 -22
  175. package/src/runtime/lampp/Lampp.js +69 -44
  176. package/src/runtime/nginx/Nginx.js +3 -3
  177. package/src/runtime/xampp/Xampp.js +49 -49
  178. package/src/server/auth.js +235 -204
  179. package/src/server/backup.js +101 -84
  180. package/src/server/client-build-live.js +72 -72
  181. package/src/server/client-build.js +705 -699
  182. package/src/server/client-dev-server.js +60 -58
  183. package/src/server/client-formatted.js +48 -48
  184. package/src/server/client-icons.js +149 -150
  185. package/src/server/conf.js +860 -611
  186. package/src/server/dns.js +98 -87
  187. package/src/server/downloader.js +42 -42
  188. package/src/server/logger.js +180 -135
  189. package/src/server/network.js +122 -122
  190. package/src/server/peer.js +33 -33
  191. package/src/server/process.js +66 -66
  192. package/src/server/prompt-optimizer.js +28 -0
  193. package/src/server/proxy.js +118 -118
  194. package/src/server/runtime.js +444 -393
  195. package/src/server/ssl.js +109 -107
  196. package/src/server.js +25 -25
  197. package/src/ws/IoInterface.js +45 -45
  198. package/src/ws/IoServer.js +39 -39
  199. package/src/ws/core/channels/core.ws.chat.js +23 -23
  200. package/src/ws/core/channels/core.ws.mailer.js +35 -35
  201. package/src/ws/core/channels/core.ws.stream.js +31 -31
  202. package/src/ws/core/core.ws.connection.js +28 -28
  203. package/src/ws/core/core.ws.emit.js +14 -14
  204. package/src/ws/core/core.ws.server.js +24 -24
  205. package/src/ws/core/management/core.ws.chat.js +8 -8
  206. package/src/ws/core/management/core.ws.mailer.js +16 -16
  207. package/src/ws/core/management/core.ws.stream.js +8 -8
  208. package/src/ws/default/channels/default.ws.main.js +16 -16
  209. package/src/ws/default/default.ws.connection.js +22 -22
  210. package/src/ws/default/default.ws.emit.js +14 -14
  211. package/src/ws/default/default.ws.server.js +20 -20
  212. package/src/ws/default/management/default.ws.main.js +8 -8
  213. package/startup.js +11 -11
  214. package/supervisord-openssh-server.conf +4 -4
  215. package/test/api.test.js +60 -60
  216. package/bin/help.js +0 -110
@@ -1,204 +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 authMiddleware function checks and verifies the authorization token in the request headers
78
- * before allowing access to protected routes.
79
- * @param req - The `req` parameter in the `authMiddleware` function stands for the request object. It
80
- * contains information about the HTTP request made to the server, including headers, body, parameters,
81
- * and more. In this context, the function is extracting the authorization token from the request
82
- * headers to authenticate the user.
83
- * @param res - The `res` parameter in the `authMiddleware` function is the response object that
84
- * represents the HTTP response that an Express.js server sends when it receives an HTTP request. It is
85
- * used to send a response back to the client with status codes, headers, and data.
86
- * @param next - The `next` parameter in the `authMiddleware` function is a callback function that is
87
- * used to pass control to the next middleware function in the stack. When called, it invokes the next
88
- * middleware function in the chain. This is a common pattern in Express.js middleware functions to
89
- * move to the next middleware
90
- * @returns {Object} The `req.auth` included JWT payload in request authorization
91
- * @memberof Auth
92
- */
93
- const authMiddleware = (req, res, next) => {
94
- try {
95
- const authHeader = String(req.headers['authorization'] || req.headers['Authorization'] || '');
96
- if (authHeader.startsWith('Bearer ')) {
97
- const token = authHeader.substring(7, authHeader.length);
98
- const payload = verifyJWT(token);
99
- req.auth = payload;
100
- return next();
101
- }
102
- return res.status(401).json({
103
- status: 'error',
104
- message: 'unauthorized: invalid token',
105
- });
106
- } catch (error) {
107
- logger.error(error, error.stack);
108
- return res.status(400).json({
109
- status: 'error',
110
- message: error.message,
111
- });
112
- }
113
- };
114
-
115
- /**
116
- * The `adminGuard` function checks if the user has admin role permission and returns an error message
117
- * if not.
118
- * @param req - The `req` parameter typically represents the HTTP request object in Node.js. It
119
- * contains information about the incoming request such as the request headers, parameters, body, and
120
- * more. In the context of your `adminGuard` function, `req` is the request object that is being passed
121
- * to the middleware
122
- * @param res - The `res` parameter in the `adminGuard` function is the response object in Express.js.
123
- * It is used to send a response back to the client making the HTTP request.
124
- * @param next - The `next` parameter in the `adminGuard` function is a callback function that is used
125
- * to pass control to the next middleware function in the stack. When called, it executes the next
126
- * middleware function. If there are no more middleware functions in the stack, it will proceed to the
127
- * route handler.
128
- * @returns The `adminGuard` function is returning either a 403 status with an error message if the
129
- * user role is not 'admin', or it is calling the `next()` function to proceed to the next middleware
130
- * if the user role is 'admin'. If an error occurs during the process, it will log the error and return
131
- * a 400 status with the error message.
132
- * @memberof Auth
133
- */
134
- const adminGuard = (req, res, next) => {
135
- try {
136
- if (!(userRoleEnum.indexOf(req.auth.user.role) === userRoleEnum.indexOf('admin')))
137
- return res.status(403).json({ status: 'error', message: 'Insufficient permission' });
138
- return next();
139
- } catch (error) {
140
- logger.error(error, error.stack);
141
- return res.status(400).json({
142
- status: 'error',
143
- message: error.message,
144
- });
145
- }
146
- };
147
-
148
- /**
149
- * The function `moderatorGuard` checks if the user's role is at least a moderator and handles errors
150
- * accordingly.
151
- * @param req - The `req` parameter in the `moderatorGuard` function typically represents the HTTP
152
- * request object, which contains information about the incoming request such as headers, parameters,
153
- * body, etc. It is commonly used to access data sent from the client to the server.
154
- * @param res - The `res` parameter in the `moderatorGuard` function is the response object in
155
- * Express.js. It is used to send a response back to the client making the HTTP request.
156
- * @param next - The `next` parameter in the `moderatorGuard` function is a callback function that is
157
- * used to pass control to the next middleware function in the stack. When called, it will execute the
158
- * next middleware function. In the context of Express.js middleware, `next` is typically called to
159
- * move to
160
- * @returns In the `moderatorGuard` function, if the user's role is not a moderator or higher, a 403
161
- * status with an error message "Insufficient permission" is returned. If there is an error during the
162
- * process, a 400 status with the error message is returned. If everything is successful, the `next()`
163
- * function is called to proceed to the next middleware in the chain.
164
- * @memberof Auth
165
- */
166
- const moderatorGuard = (req, res, next) => {
167
- try {
168
- if (!(userRoleEnum.indexOf(req.auth.user.role) <= userRoleEnum.indexOf('moderator')))
169
- return res.status(403).json({ status: 'error', message: 'Insufficient permission' });
170
- return next();
171
- } catch (error) {
172
- logger.error(error, error.stack);
173
- return res.status(400).json({
174
- status: 'error',
175
- message: error.message,
176
- });
177
- }
178
- };
179
-
180
- const validatePasswordMiddleware = (req, password) => {
181
- let errors = [];
182
- if (req.body && 'password' in req.body) errors = validatePassword(req.body.password);
183
- if (errors.length > 0)
184
- return {
185
- status: 'error',
186
- message:
187
- 'Password, ' + errors.map((e, i) => (i > 0 ? ', ' : '') + (e[req.lang] ? e[req.lang] : e['en'])).join(''),
188
- };
189
- else
190
- return {
191
- status: 'success',
192
- };
193
- };
194
-
195
- export {
196
- authMiddleware,
197
- hashPassword,
198
- verifyPassword,
199
- hashJWT,
200
- adminGuard,
201
- moderatorGuard,
202
- verifyJWT,
203
- validatePasswordMiddleware,
204
- };
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
+ };
@@ -1,84 +1,101 @@
1
- import fs from 'fs-extra';
2
- import { loggerFactory } from './logger.js';
3
- import { shellExec } from './process.js';
4
- import { getDataDeploy } from './conf.js';
5
-
6
- const logger = loggerFactory(import.meta);
7
-
8
- const BackUpManagement = {
9
- Init: async function () {
10
- await this.Callback();
11
- setInterval(async () => {
12
- await this.Callback();
13
- }, 1000 * 60 * 60); // hourly interval
14
- },
15
- Callback: async function () {
16
- const privateCronConfPath = `./engine-private/conf/${process.argv[2]}/conf.cron.json`;
17
-
18
- const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
19
-
20
- const { backups } = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
21
-
22
- if (!backups) return;
23
-
24
- const currentDate = new Date().getTime();
25
-
26
- if (!fs.existsSync('./engine-private/cron-backups'))
27
- fs.mkdirSync('./engine-private/cron-backups', { recursive: true });
28
-
29
- for (const deployGroupData of backups) {
30
- const { deployGroupId } = deployGroupData;
31
- const dataDeploy = getDataDeploy({ deployGroupId });
32
-
33
- for (const deployObj of dataDeploy) {
34
- const { deployId } = deployObj;
35
-
36
- const confServer = JSON.parse(
37
- fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
38
- ? fs.readFileSync(`./engine-private/replica/${deployId}/conf.server.json`, 'utf8')
39
- : fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
40
- );
41
-
42
- for (const host of Object.keys(confServer))
43
- for (const path of Object.keys(confServer[host])) {
44
- // retention policy
45
- let { db, backupFrequency, maxBackupRetention } = confServer[host][path];
46
-
47
- if (!db) continue;
48
-
49
- if (!backupFrequency) backupFrequency = 'daily';
50
- if (!maxBackupRetention) maxBackupRetention = 5;
51
-
52
- const backUpPath = `./engine-private/cron-backups/${host}${path.replace(/\\/g, '/').replace(`/`, '-')}`;
53
- if (!fs.existsSync(backUpPath)) fs.mkdirSync(`${backUpPath}`, { recursive: true });
54
- // .isDirectory()
55
- const files = await fs.readdir(backUpPath, { withFileTypes: true });
56
-
57
- const currentBackupsDirs = files
58
- .map((fileObj) => parseInt(fileObj.name))
59
- .sort((a, b) => a - b)
60
- .reverse();
61
-
62
- switch (backupFrequency) {
63
- case 'daily':
64
-
65
- default:
66
- if (currentBackupsDirs[0] && currentDate - currentBackupsDirs[0] <= 1000 * 60 * 60 * 24) continue;
67
- break;
68
- }
69
-
70
- for (const retentionPath of currentBackupsDirs.filter((t, i) => i >= maxBackupRetention + 1)) {
71
- const removePathRetention = `${backUpPath}/${retentionPath}`;
72
- fs.removeSync(removePathRetention);
73
- }
74
-
75
- fs.mkdirSync(`${backUpPath}/${currentDate}`, { recursive: true });
76
-
77
- shellExec(`node bin/db ${host}${path} export ${deployId} ${backUpPath}/${currentDate}`);
78
- }
79
- }
80
- }
81
- },
82
- };
83
-
84
- export { BackUpManagement };
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 cron from 'node-cron';
6
+
7
+ const logger = loggerFactory(import.meta);
8
+
9
+ const BackUpManagement = {
10
+ Init: async function () {
11
+ await BackUpManagement.Callback();
12
+
13
+ // Schedule the sending process to run every day at 1 am
14
+ cron.schedule(
15
+ '0 1 * * *',
16
+ async () => {
17
+ await BackUpManagement.Callback();
18
+ },
19
+ {
20
+ scheduled: true,
21
+ timezone: process.env.TIME_ZONE || 'America/New_York',
22
+ },
23
+ );
24
+ },
25
+ Callback: async function () {
26
+ const privateCronConfPath = `./engine-private/conf/${process.argv[2]}/conf.cron.json`;
27
+
28
+ const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json';
29
+
30
+ const { backups } = JSON.parse(fs.readFileSync(confCronPath, 'utf8'));
31
+
32
+ if (!backups) return;
33
+
34
+ const currentDate = new Date().getTime();
35
+
36
+ if (!fs.existsSync('./engine-private/cron-backups'))
37
+ fs.mkdirSync('./engine-private/cron-backups', { recursive: true });
38
+
39
+ for (const deployGroupData of backups) {
40
+ const { deployGroupId } = deployGroupData;
41
+ const dataDeploy = getDataDeploy({ deployGroupId });
42
+
43
+ for (const deployObj of dataDeploy) {
44
+ const { deployId, replicaHost } = deployObj;
45
+
46
+ if (replicaHost) continue;
47
+
48
+ const confServer = JSON.parse(
49
+ fs.existsSync(`./engine-private/replica/${deployId}/conf.server.json`)
50
+ ? fs.readFileSync(`./engine-private/replica/${deployId}/conf.server.json`, 'utf8')
51
+ : fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'),
52
+ );
53
+
54
+ for (const host of Object.keys(confServer))
55
+ for (const path of Object.keys(confServer[host])) {
56
+ // retention policy
57
+ let { db, backupFrequency, maxBackupRetention, singleReplica } = confServer[host][path];
58
+
59
+ if (!db || singleReplica) continue;
60
+
61
+ if (!backupFrequency) backupFrequency = 'daily';
62
+ if (!maxBackupRetention) maxBackupRetention = 5;
63
+
64
+ const backUpPath = `${process.cwd()}/engine-private/cron-backups/${getCronBackUpFolder(host, path)}`;
65
+ if (!fs.existsSync(backUpPath)) fs.mkdirSync(`${backUpPath}`, { recursive: true });
66
+ // .isDirectory()
67
+ const files = await fs.readdir(backUpPath, { withFileTypes: true });
68
+
69
+ const currentBackupsDirs = files
70
+ .map((fileObj) => parseInt(fileObj.name))
71
+ .sort((a, b) => a - b)
72
+ .reverse();
73
+
74
+ switch (backupFrequency) {
75
+ case 'daily':
76
+
77
+ default:
78
+ if (currentBackupsDirs[0] && currentDate - currentBackupsDirs[0] <= 1000 * 60 * 60 * 24) continue;
79
+ break;
80
+ }
81
+
82
+ for (const retentionPath of currentBackupsDirs.filter((t, i) => i >= maxBackupRetention + 1)) {
83
+ const removePathRetention = `${backUpPath}/${retentionPath}`;
84
+ fs.removeSync(removePathRetention);
85
+ }
86
+
87
+ fs.mkdirSync(`${backUpPath}/${currentDate}`, { recursive: true });
88
+
89
+ shellExec(`node bin/db ${host}${path} export ${deployId} ${backUpPath}/${currentDate}`);
90
+ }
91
+ }
92
+ }
93
+ shellCd(`./engine-private`);
94
+ shellExec(`git pull origin master`);
95
+ shellExec(`git add . && git commit -m "backup ${new Date().toLocaleDateString()}"`);
96
+ shellExec(`git push origin master`);
97
+ shellCd(`..`);
98
+ },
99
+ };
100
+
101
+ export { BackUpManagement };