@adaptivestone/framework 5.0.0-beta.4 → 5.0.0-beta.40

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 (298) hide show
  1. package/CHANGELOG.md +1107 -528
  2. package/LICENCE +1 -1
  3. package/dist/Cli.d.ts +7 -0
  4. package/dist/Cli.js +19 -0
  5. package/dist/Cli.js.map +1 -0
  6. package/dist/cluster.d.ts +1 -0
  7. package/dist/cluster.js +18 -0
  8. package/dist/cluster.js.map +1 -0
  9. package/dist/commands/CreateUser.d.ts +32 -0
  10. package/dist/commands/CreateUser.js +83 -0
  11. package/dist/commands/CreateUser.js.map +1 -0
  12. package/dist/commands/Documentation.d.ts +5 -0
  13. package/dist/commands/Documentation.js +15 -0
  14. package/dist/commands/Documentation.js.map +1 -0
  15. package/dist/commands/DropIndex.d.ts +16 -0
  16. package/dist/commands/DropIndex.js +30 -0
  17. package/dist/commands/DropIndex.js.map +1 -0
  18. package/dist/commands/GenerateRandomBytes.d.ts +7 -0
  19. package/dist/commands/GenerateRandomBytes.js +18 -0
  20. package/dist/commands/GenerateRandomBytes.js.map +1 -0
  21. package/dist/commands/GenerateTypes.d.ts +11 -0
  22. package/dist/commands/GenerateTypes.js +52 -0
  23. package/dist/commands/GenerateTypes.js.map +1 -0
  24. package/dist/commands/GetOpenApiJson.d.ts +17 -0
  25. package/dist/commands/GetOpenApiJson.js +272 -0
  26. package/dist/commands/GetOpenApiJson.js.map +1 -0
  27. package/dist/commands/SyncIndexes.d.ts +6 -0
  28. package/dist/commands/SyncIndexes.js +31 -0
  29. package/dist/commands/SyncIndexes.js.map +1 -0
  30. package/dist/commands/migration/Create.d.ts +18 -0
  31. package/dist/commands/migration/Create.js +57 -0
  32. package/dist/commands/migration/Create.js.map +1 -0
  33. package/dist/commands/migration/Migrate.d.ts +6 -0
  34. package/dist/commands/migration/Migrate.js +43 -0
  35. package/dist/commands/migration/Migrate.js.map +1 -0
  36. package/dist/config/auth.d.ts +6 -0
  37. package/dist/config/auth.js +7 -0
  38. package/dist/config/auth.js.map +1 -0
  39. package/dist/config/http.d.ts +8 -0
  40. package/dist/config/http.js +10 -0
  41. package/dist/config/http.js.map +1 -0
  42. package/dist/config/i18n.d.ts +13 -0
  43. package/dist/config/i18n.js +13 -0
  44. package/dist/config/i18n.js.map +1 -0
  45. package/dist/config/ipDetector.d.ts +5 -0
  46. package/dist/config/ipDetector.js +15 -0
  47. package/dist/config/ipDetector.js.map +1 -0
  48. package/dist/config/log.d.ts +11 -0
  49. package/dist/config/log.js +20 -0
  50. package/dist/config/log.js.map +1 -0
  51. package/dist/config/mongo.d.ts +4 -0
  52. package/dist/config/mongo.js +4 -0
  53. package/dist/config/mongo.js.map +1 -0
  54. package/dist/config/rateLimiter.d.ts +13 -0
  55. package/dist/config/rateLimiter.js +17 -0
  56. package/dist/config/rateLimiter.js.map +1 -0
  57. package/dist/config/redis.d.ts +5 -0
  58. package/dist/config/redis.js +5 -0
  59. package/dist/config/redis.js.map +1 -0
  60. package/dist/config/validate.d.ts +4 -0
  61. package/dist/config/validate.js +4 -0
  62. package/dist/config/validate.js.map +1 -0
  63. package/dist/controllers/Auth.d.ts +131 -0
  64. package/dist/controllers/Auth.js +186 -0
  65. package/dist/controllers/Auth.js.map +1 -0
  66. package/dist/controllers/Home.d.ts +15 -0
  67. package/dist/controllers/Home.js +22 -0
  68. package/dist/controllers/Home.js.map +1 -0
  69. package/dist/controllers/index.d.ts +16 -0
  70. package/dist/controllers/index.js +59 -0
  71. package/dist/controllers/index.js.map +1 -0
  72. package/dist/folderConfig.d.ts +34 -0
  73. package/dist/folderConfig.js +14 -0
  74. package/dist/folderConfig.js.map +1 -0
  75. package/dist/helpers/appInstance.d.ts +3 -0
  76. package/dist/helpers/appInstance.js +8 -0
  77. package/dist/helpers/appInstance.js.map +1 -0
  78. package/dist/helpers/crypto.d.ts +3 -0
  79. package/dist/helpers/crypto.js +17 -0
  80. package/dist/helpers/crypto.js.map +1 -0
  81. package/dist/helpers/files.d.ts +16 -0
  82. package/dist/helpers/files.js +76 -0
  83. package/dist/helpers/files.js.map +1 -0
  84. package/dist/helpers/logger.d.ts +4 -0
  85. package/dist/helpers/logger.js +20 -0
  86. package/dist/helpers/logger.js.map +1 -0
  87. package/dist/helpers/redis/clearNamespace.d.ts +2 -0
  88. package/dist/helpers/redis/clearNamespace.js +14 -0
  89. package/dist/helpers/redis/clearNamespace.js.map +1 -0
  90. package/dist/helpers/yup.d.ts +13 -0
  91. package/dist/helpers/yup.js +21 -0
  92. package/dist/helpers/yup.js.map +1 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +7 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/models/Lock.d.ts +90 -0
  97. package/dist/models/Lock.js +97 -0
  98. package/dist/models/Lock.js.map +1 -0
  99. package/dist/models/Migration.d.ts +13 -0
  100. package/dist/models/Migration.js +14 -0
  101. package/dist/models/Migration.js.map +1 -0
  102. package/dist/models/Sequence.d.ts +28 -0
  103. package/dist/models/Sequence.js +19 -0
  104. package/dist/models/Sequence.js.map +1 -0
  105. package/dist/models/User.d.ts +656 -0
  106. package/dist/models/User.js +291 -0
  107. package/dist/models/User.js.map +1 -0
  108. package/dist/models/UserOld.d.ts +179 -0
  109. package/dist/models/UserOld.js +230 -0
  110. package/dist/models/UserOld.js.map +1 -0
  111. package/dist/modules/AbstractCommand.d.ts +51 -0
  112. package/dist/modules/AbstractCommand.js +60 -0
  113. package/dist/modules/AbstractCommand.js.map +1 -0
  114. package/dist/modules/AbstractConnector.d.ts +5 -0
  115. package/dist/modules/AbstractConnector.js +8 -0
  116. package/dist/modules/AbstractConnector.js.map +1 -0
  117. package/dist/modules/AbstractController.d.ts +94 -0
  118. package/dist/modules/AbstractController.js +323 -0
  119. package/dist/modules/AbstractController.js.map +1 -0
  120. package/dist/modules/AbstractModel.d.ts +29 -0
  121. package/dist/modules/AbstractModel.js +42 -0
  122. package/dist/modules/AbstractModel.js.map +1 -0
  123. package/dist/modules/Base.d.ts +29 -0
  124. package/dist/modules/Base.js +58 -0
  125. package/dist/modules/Base.js.map +1 -0
  126. package/dist/modules/BaseCli.d.ts +25 -0
  127. package/dist/modules/BaseCli.js +147 -0
  128. package/dist/modules/BaseCli.js.map +1 -0
  129. package/dist/modules/BaseModel.d.ts +55 -0
  130. package/dist/modules/BaseModel.js +37 -0
  131. package/dist/modules/BaseModel.js.map +1 -0
  132. package/dist/server.d.ts +123 -0
  133. package/dist/server.js +468 -0
  134. package/dist/server.js.map +1 -0
  135. package/dist/services/cache/Cache.d.ts +31 -0
  136. package/dist/services/cache/Cache.js +113 -0
  137. package/dist/services/cache/Cache.js.map +1 -0
  138. package/dist/services/documentation/DocumentationGenerator.d.ts +11 -0
  139. package/dist/services/documentation/DocumentationGenerator.js +130 -0
  140. package/dist/services/documentation/DocumentationGenerator.js.map +1 -0
  141. package/dist/services/http/HttpServer.d.ts +35 -0
  142. package/dist/services/http/HttpServer.js +70 -0
  143. package/dist/services/http/HttpServer.js.map +1 -0
  144. package/dist/services/http/middleware/AbstractMiddleware.d.ts +25 -0
  145. package/dist/services/http/middleware/AbstractMiddleware.js +41 -0
  146. package/dist/services/http/middleware/AbstractMiddleware.js.map +1 -0
  147. package/dist/services/http/middleware/Auth.d.ts +9 -0
  148. package/dist/services/http/middleware/Auth.js +18 -0
  149. package/dist/services/http/middleware/Auth.js.map +1 -0
  150. package/dist/services/http/middleware/Cors.d.ts +12 -0
  151. package/dist/services/http/middleware/Cors.js +36 -0
  152. package/dist/services/http/middleware/Cors.js.map +1 -0
  153. package/dist/services/http/middleware/GetUserByToken.d.ts +20 -0
  154. package/dist/services/http/middleware/GetUserByToken.js +39 -0
  155. package/dist/services/http/middleware/GetUserByToken.js.map +1 -0
  156. package/dist/services/http/middleware/I18n.d.ts +23 -0
  157. package/dist/services/http/middleware/I18n.js +61 -0
  158. package/dist/services/http/middleware/I18n.js.map +1 -0
  159. package/dist/services/http/middleware/IpDetector.d.ts +14 -0
  160. package/dist/services/http/middleware/IpDetector.js +55 -0
  161. package/dist/services/http/middleware/IpDetector.js.map +1 -0
  162. package/dist/services/http/middleware/Pagination.d.ts +27 -0
  163. package/dist/services/http/middleware/Pagination.js +46 -0
  164. package/dist/services/http/middleware/Pagination.js.map +1 -0
  165. package/dist/services/http/middleware/PrepareAppInfo.d.ts +8 -0
  166. package/dist/services/http/middleware/PrepareAppInfo.js +17 -0
  167. package/dist/services/http/middleware/PrepareAppInfo.js.map +1 -0
  168. package/dist/services/http/middleware/RateLimiter.d.ts +26 -0
  169. package/dist/services/http/middleware/RateLimiter.js +118 -0
  170. package/dist/services/http/middleware/RateLimiter.js.map +1 -0
  171. package/dist/services/http/middleware/RequestLogger.d.ts +8 -0
  172. package/dist/services/http/middleware/RequestLogger.js +18 -0
  173. package/dist/services/http/middleware/RequestLogger.js.map +1 -0
  174. package/dist/services/http/middleware/RequestParser.d.ts +8 -0
  175. package/dist/services/http/middleware/RequestParser.js +35 -0
  176. package/dist/services/http/middleware/RequestParser.js.map +1 -0
  177. package/dist/services/http/middleware/Role.d.ts +12 -0
  178. package/dist/services/http/middleware/Role.js +24 -0
  179. package/dist/services/http/middleware/Role.js.map +1 -0
  180. package/dist/services/i18n/I18n.d.ts +15 -0
  181. package/dist/services/i18n/I18n.js +58 -0
  182. package/dist/services/i18n/I18n.js.map +1 -0
  183. package/dist/services/logging/SentryTransport.d.ts +14 -0
  184. package/dist/services/logging/SentryTransport.js +57 -0
  185. package/dist/services/logging/SentryTransport.js.map +1 -0
  186. package/dist/services/validate/ValidateService.d.ts +31 -0
  187. package/dist/services/validate/ValidateService.js +95 -0
  188. package/dist/services/validate/ValidateService.js.map +1 -0
  189. package/dist/services/validate/drivers/AbstractValidator.d.ts +14 -0
  190. package/dist/services/validate/drivers/AbstractValidator.js +29 -0
  191. package/dist/services/validate/drivers/AbstractValidator.js.map +1 -0
  192. package/dist/services/validate/drivers/CustomValidator.d.ts +14 -0
  193. package/dist/services/validate/drivers/CustomValidator.js +48 -0
  194. package/dist/services/validate/drivers/CustomValidator.js.map +1 -0
  195. package/dist/services/validate/drivers/YupValidator.d.ts +13 -0
  196. package/dist/services/validate/drivers/YupValidator.js +86 -0
  197. package/dist/services/validate/drivers/YupValidator.js.map +1 -0
  198. package/dist/tests/frameworkVitestSetup.d.ts +1 -0
  199. package/dist/tests/frameworkVitestSetup.js +9 -0
  200. package/dist/tests/frameworkVitestSetup.js.map +1 -0
  201. package/dist/tests/globalSetupVitest.d.ts +3 -0
  202. package/dist/tests/globalSetupVitest.js +29 -0
  203. package/dist/tests/globalSetupVitest.js.map +1 -0
  204. package/dist/tests/setupVitest.d.ts +1 -0
  205. package/dist/tests/setupVitest.js +91 -0
  206. package/dist/tests/setupVitest.js.map +1 -0
  207. package/dist/tests/testHelpers.d.ts +340 -0
  208. package/dist/tests/testHelpers.js +48 -0
  209. package/dist/tests/testHelpers.js.map +1 -0
  210. package/package.json +45 -39
  211. package/Cli.js +0 -22
  212. package/cluster.js +0 -27
  213. package/commands/CreateUser.js +0 -75
  214. package/commands/Documentation.js +0 -17
  215. package/commands/DropIndex.js +0 -29
  216. package/commands/GenerateRandomBytes.js +0 -21
  217. package/commands/GetOpenApiJson.js +0 -325
  218. package/commands/SyncIndexes.js +0 -39
  219. package/commands/migration/Create.js +0 -61
  220. package/commands/migration/Migrate.js +0 -55
  221. package/config/auth.js +0 -9
  222. package/config/http.js +0 -9
  223. package/config/i18n.js +0 -12
  224. package/config/ipDetector.js +0 -14
  225. package/config/log.js +0 -22
  226. package/config/mail.js +0 -29
  227. package/config/mongo.js +0 -3
  228. package/config/rateLimiter.js +0 -16
  229. package/config/redis.js +0 -4
  230. package/config/validate.js +0 -3
  231. package/controllers/Auth.js +0 -210
  232. package/controllers/Home.js +0 -28
  233. package/controllers/index.js +0 -60
  234. package/folderConfig.js +0 -14
  235. package/helpers/files.js +0 -79
  236. package/helpers/logger.js +0 -17
  237. package/helpers/redis/clearNamespace.js +0 -14
  238. package/helpers/yup.js +0 -24
  239. package/index.js +0 -8
  240. package/jsconfig.json +0 -9
  241. package/locales/en/translation.json +0 -27
  242. package/locales/ru/translation.json +0 -27
  243. package/migrations/.gitkeep +0 -0
  244. package/models/Migration.js +0 -15
  245. package/models/Sequence.js +0 -22
  246. package/models/User.js +0 -263
  247. package/modules/AbstractCommand.js +0 -43
  248. package/modules/AbstractConnector.js +0 -9
  249. package/modules/AbstractController.js +0 -413
  250. package/modules/AbstractModel.d.ts +0 -48
  251. package/modules/AbstractModel.js +0 -92
  252. package/modules/Base.d.ts +0 -37
  253. package/modules/Base.js +0 -63
  254. package/modules/BaseCli.js +0 -97
  255. package/server.d.ts +0 -98
  256. package/server.js +0 -438
  257. package/services/cache/Cache.d.ts +0 -35
  258. package/services/cache/Cache.js +0 -124
  259. package/services/documentation/DocumentationGenerator.js +0 -169
  260. package/services/http/HttpServer.js +0 -96
  261. package/services/http/middleware/AbstractMiddleware.js +0 -51
  262. package/services/http/middleware/Auth.js +0 -20
  263. package/services/http/middleware/Cors.js +0 -46
  264. package/services/http/middleware/GetUserByToken.js +0 -47
  265. package/services/http/middleware/I18n.js +0 -117
  266. package/services/http/middleware/IpDetector.js +0 -59
  267. package/services/http/middleware/Pagination.js +0 -57
  268. package/services/http/middleware/PrepareAppInfo.js +0 -18
  269. package/services/http/middleware/RateLimiter.js +0 -134
  270. package/services/http/middleware/RequestLogger.js +0 -22
  271. package/services/http/middleware/RequestParser.js +0 -40
  272. package/services/http/middleware/Role.js +0 -29
  273. package/services/messaging/email/index.js +0 -217
  274. package/services/messaging/email/resources/.gitkeep +0 -1
  275. package/services/messaging/email/templates/emptyTemplate/html.pug +0 -9
  276. package/services/messaging/email/templates/emptyTemplate/subject.pug +0 -1
  277. package/services/messaging/email/templates/emptyTemplate/text.pug +0 -1
  278. package/services/messaging/email/templates/recovery/html.pug +0 -8
  279. package/services/messaging/email/templates/recovery/subject.pug +0 -2
  280. package/services/messaging/email/templates/recovery/text.pug +0 -3
  281. package/services/messaging/email/templates/verification/html.pug +0 -10
  282. package/services/messaging/email/templates/verification/subject.pug +0 -1
  283. package/services/messaging/email/templates/verification/text.pug +0 -1
  284. package/services/messaging/index.js +0 -3
  285. package/services/validate/ValidateService.js +0 -157
  286. package/services/validate/drivers/AbstractValidator.js +0 -37
  287. package/services/validate/drivers/CustomValidator.js +0 -51
  288. package/services/validate/drivers/YupValidator.js +0 -103
  289. package/tests/globalSetupVitest.js +0 -35
  290. package/tests/setup.js +0 -118
  291. package/tests/setupVitest.js +0 -109
  292. package/types/Expand.d.ts +0 -11
  293. package/types/TFoldersConfig.d.ts +0 -17
  294. package/views/404.pug +0 -3
  295. package/views/home.pug +0 -3
  296. package/views/layouts/base.pug +0 -39
  297. package/vitest.config.js +0 -16
  298. /package/{commands → dist/migrations}/.gitkeep +0 -0
@@ -1,59 +0,0 @@
1
- import { BlockList } from 'node:net';
2
-
3
- import AbstractMiddleware from './AbstractMiddleware.js';
4
-
5
- class IpDetector extends AbstractMiddleware {
6
- static get description() {
7
- return 'Detect real user IP address. Support proxy and load balancer';
8
- }
9
-
10
- constructor(app, params) {
11
- super(app, params);
12
- const { trustedProxy } = this.app.getConfig('ipDetector');
13
-
14
- this.blockList = new BlockList();
15
-
16
- for (const subnet of trustedProxy) {
17
- const addressType = subnet.includes(':') ? 'ipv6' : 'ipv4';
18
- if (subnet.includes('/')) {
19
- // CIDR
20
- const [realSubnet, prefixLength] = subnet.split('/');
21
- this.blockList.addSubnet(
22
- realSubnet,
23
- parseInt(prefixLength, 10),
24
- addressType,
25
- );
26
- } else if (subnet.includes('-')) {
27
- // RANGE
28
- const [start, end] = subnet.split('-');
29
- this.blockList.addRange(start, end, addressType);
30
- } else {
31
- // just an address
32
- this.blockList.addAddress(subnet, addressType);
33
- }
34
- }
35
- }
36
-
37
- async middleware(req, res, next) {
38
- const { headers } = this.app.getConfig('ipDetector');
39
- const initialIp = req.socket.remoteAddress;
40
- req.appInfo.ip = initialIp;
41
- const addressType = initialIp.includes(':') ? 'ipv6' : 'ipv4';
42
-
43
- if (this.blockList.check(initialIp, addressType)) {
44
- // we can trust this source
45
- for (const header of headers) {
46
- // in a range
47
- const ipHeader = req.headers[header.toLowerCase()];
48
- if (ipHeader) {
49
- const [firstIp] = ipHeader.split(',').map((ip) => ip.trim());
50
- req.appInfo.ip = firstIp;
51
- break;
52
- }
53
- }
54
- }
55
- next();
56
- }
57
- }
58
-
59
- export default IpDetector;
@@ -1,57 +0,0 @@
1
- import yup from 'yup';
2
- import AbstractMiddleware from './AbstractMiddleware.js';
3
- /**
4
- * Middleware for reusing pagination
5
- */
6
- class Pagination extends AbstractMiddleware {
7
- static get description() {
8
- return 'Pagination middleware. You can use limit=10 and maxLimit=100 parameters';
9
- }
10
-
11
- // eslint-disable-next-line class-methods-use-this
12
- get relatedQueryParameters() {
13
- return yup.object().shape({
14
- page: yup.number(),
15
- limit: yup.number(),
16
- });
17
- }
18
-
19
- async middleware(req, res, next) {
20
- let { limit, maxLimit } = this.params;
21
-
22
- limit = (typeof limit !== 'number' ? parseInt(limit, 10) : limit) || 10;
23
- maxLimit =
24
- (typeof maxLimit !== 'number' ? parseInt(maxLimit, 10) : maxLimit) || 100;
25
-
26
- req.appInfo.pagination = {};
27
- req.appInfo.pagination.page =
28
- typeof req?.query?.page === 'string'
29
- ? parseInt(req?.query?.page, 10) || 1
30
- : 1;
31
-
32
- req.appInfo.pagination.limit =
33
- typeof req?.query?.limit === 'string'
34
- ? parseInt(req?.query?.limit, 10) || 0
35
- : limit;
36
-
37
- if (req.appInfo.pagination.limit > maxLimit) {
38
- req.appInfo.pagination.limit = maxLimit;
39
- }
40
-
41
- if (req.appInfo.pagination.page < 1) {
42
- req.appInfo.pagination.page = 1;
43
- }
44
-
45
- if (req.appInfo.pagination.limit < 0) {
46
- req.appInfo.pagination.limit = 0;
47
- }
48
-
49
- req.appInfo.pagination.skip =
50
- req.appInfo.pagination.page * req.appInfo.pagination.limit -
51
- req.appInfo.pagination.limit;
52
-
53
- return next();
54
- }
55
- }
56
-
57
- export default Pagination;
@@ -1,18 +0,0 @@
1
- import AbstractMiddleware from './AbstractMiddleware.js';
2
-
3
- class PrepareAppInfo extends AbstractMiddleware {
4
- static get description() {
5
- return 'Basic middleware that creates "req.appInfo" object';
6
- }
7
-
8
- async middleware(req, res, next) {
9
- if (!req.appInfo) {
10
- req.appInfo = {
11
- app: this.app,
12
- };
13
- }
14
- next();
15
- }
16
- }
17
-
18
- export default PrepareAppInfo;
@@ -1,134 +0,0 @@
1
- import {
2
- RateLimiterMemory,
3
- RateLimiterRedis,
4
- RateLimiterMongo,
5
- } from 'rate-limiter-flexible';
6
- import merge from 'deepmerge';
7
- import redis from 'redis';
8
- import mongoose from 'mongoose';
9
- import AbstractMiddleware from './AbstractMiddleware.js';
10
-
11
- class RateLimiter extends AbstractMiddleware {
12
- static get description() {
13
- return 'Rate limiter middleware. Limit amount of request. Please refer to documentation';
14
- }
15
-
16
- constructor(app, params) {
17
- super(app, params);
18
- const limiterOptions = this.app.getConfig('rateLimiter');
19
-
20
- this.finalOptions = merge(limiterOptions, params);
21
- this.limiter = null;
22
-
23
- switch (this.finalOptions.driver) {
24
- case 'memory':
25
- this.limiter = new RateLimiterMemory(this.finalOptions.limiterOptions);
26
- break;
27
-
28
- case 'redis':
29
- this.limiter = this.initRedisLimiter();
30
- break;
31
-
32
- case 'mongo':
33
- this.limiter = new RateLimiterMongo({
34
- storeClient: mongoose.connection,
35
- ...this.finalOptions.limiterOptions,
36
- });
37
- break;
38
-
39
- default:
40
- this.logger.error(
41
- `Unknwon option for driver ${this.finalOptions.driver}`,
42
- );
43
- break;
44
- }
45
- }
46
-
47
- initRedisLimiter() {
48
- const redisConfig = this.app.getConfig('redis');
49
- const redisClient = redis.createClient({
50
- url: redisConfig.url,
51
- });
52
-
53
- // TODO: change it
54
- (async () => {
55
- await redisClient.connect();
56
- })();
57
-
58
- redisClient.on('error', (error, b, c) => {
59
- this.logger.error(error, b, c);
60
- });
61
- redisClient.on('connect', () => {
62
- this.logger.info('Redis connection success');
63
- });
64
-
65
- this.app.events.on('shutdown', async () => {
66
- await redisClient.disconnect();
67
- });
68
-
69
- return new RateLimiterRedis({
70
- storeClient: redisClient,
71
- useRedisPackage: true,
72
- ...this.finalOptions.limiterOptions,
73
- });
74
- }
75
-
76
- gerenateConsumeKey(req) {
77
- const { ip, route, user, request } = this.finalOptions.consumeKeyComponents;
78
-
79
- const key = [];
80
- if (ip) {
81
- if (!req.appInfo.ip) {
82
- this.logger.error(
83
- `RateLimiter: Can't get remote address from request. Please check that you used IpDetecor middleware before RateLimiter`,
84
- );
85
- } else {
86
- key.push(req.appInfo.ip);
87
- }
88
- }
89
- if (route) {
90
- key.push(`${req.baseUrl ?? ''}${req.path ?? ''}`); // to avoid quesry params
91
- }
92
- if (user && req.appInfo?.user) {
93
- key.push(req.appInfo?.user.id);
94
- }
95
-
96
- if (request && request.length) {
97
- request.forEach((val) => {
98
- if (req.body && req.body[val]) {
99
- key.push(req.body[val]);
100
- }
101
- // if (req.appInfo.request && req.appInfo.request[val]) {
102
- // key.push(req.appInfo.request[val]);
103
- // }
104
- });
105
- }
106
-
107
- return key.join('_');
108
- }
109
-
110
- async middleware(req, res, next) {
111
- if (!this.limiter) {
112
- this.logger.info(
113
- `RateLimiter not inited correclty! Please check init logs `,
114
- );
115
- return res.status(500).json({ message: 'RateLimiter error' });
116
- }
117
-
118
- const { namespace } = this.app.getConfig('redis');
119
-
120
- const consumeKey = `${namespace}-${this.gerenateConsumeKey(req)}`;
121
-
122
- const consumeResult = await this.limiter
123
- .consume(consumeKey, this.finalOptions.consumePoints)
124
- .catch(() => {
125
- this.logger.warn(`Too many requests. Consume key: ${consumeKey}`);
126
- });
127
- if (consumeResult) {
128
- return next();
129
- }
130
- return res.status(429).json({ message: 'Too Many Requests' });
131
- }
132
- }
133
-
134
- export default RateLimiter;
@@ -1,22 +0,0 @@
1
- import AbstractMiddleware from './AbstractMiddleware.js';
2
-
3
- class RequestLogger extends AbstractMiddleware {
4
- static get description() {
5
- return 'Log info about the request';
6
- }
7
-
8
- async middleware(req, res, next) {
9
- const startTime = performance.now();
10
- const text = `Request is [${req.method}] ${req.url}`;
11
- this.logger.info(text);
12
- res.on('finish', () => {
13
- const end = performance.now();
14
- this.logger.info(
15
- `Finished ${text}. Status: ${res.statusCode}. [${(end - startTime).toFixed(2)} ms]`,
16
- );
17
- });
18
- next();
19
- }
20
- }
21
-
22
- export default RequestLogger;
@@ -1,40 +0,0 @@
1
- import formidable from 'formidable';
2
- import AbstractMiddleware from './AbstractMiddleware.js';
3
-
4
- class RequestParser extends AbstractMiddleware {
5
- static get description() {
6
- return 'Parses incoming request. Based on Formidable library';
7
- }
8
-
9
- async middleware(req, res, next) {
10
- const time = Date.now();
11
- this.logger.verbose(`Parsing request`);
12
- // TODO update this to https://github.com/node-formidable/formidable/issues/412#issuecomment-1367914268 in node v20 (in 2023?)
13
-
14
- const form = formidable(this.params); // not in construstor as reuse formidable affects performance
15
- let fields;
16
- let files;
17
- try {
18
- [fields, files] = await form.parse(req);
19
- } catch (err) {
20
- this.logger.error(`Parsing failed ${err}`);
21
- return res.status(400).json({
22
- message: `Error to parse your request. You provided invalid content type or content-length. Please check your request headers and content type.`,
23
- });
24
- // return next(err);
25
- }
26
- this.logger.verbose(
27
- `Parsing multipart/formdata request DONE ${Date.now() - time}ms`,
28
- );
29
-
30
- req.body = {
31
- // todo avoid body in next versions
32
- ...(req.body || {}),
33
- ...fields,
34
- ...files,
35
- };
36
- return next();
37
- }
38
- }
39
-
40
- export default RequestParser;
@@ -1,29 +0,0 @@
1
- import AbstractMiddleware from './AbstractMiddleware.js';
2
-
3
- class RoleMiddleware extends AbstractMiddleware {
4
- static get description() {
5
- return 'Check user role (user.roles property). If the user has no role then stop request and return error. OR logic (any role will pass user)';
6
- }
7
-
8
- async middleware(req, res, next) {
9
- const { user } = req.appInfo;
10
-
11
- if (!user) {
12
- return res.status(401).json({ message: 'User should be provided' });
13
- }
14
-
15
- let hasRole = false;
16
- user.roles.forEach((role) => {
17
- if (this.params.roles.includes(role)) {
18
- hasRole = true;
19
- }
20
- });
21
-
22
- if (!hasRole) {
23
- return res.status(403).json({ message: 'You do not have access' });
24
- }
25
- return next();
26
- }
27
- }
28
-
29
- export default RoleMiddleware;
@@ -1,217 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import * as url from 'node:url';
4
- import { promisify } from 'node:util';
5
- import nodemailer from 'nodemailer';
6
- import sendMail from 'nodemailer-sendmail-transport';
7
- import stub from 'nodemailer-stub-transport';
8
- import pug from 'pug';
9
- import juice from 'juice';
10
- import { convert } from 'html-to-text';
11
- import Base from '../../../modules/Base.js';
12
-
13
- const mailTransports = {
14
- sendMail,
15
- stub,
16
- smtp: (data) => data,
17
- };
18
-
19
- class Mail extends Base {
20
- /**
21
- * Construct mail class
22
- * @param {object} app
23
- * @param {string} template template name
24
- * @param {object} [templateData={}] data to render in template. Object with value that available inside template
25
- * @param {object} [i18n] data to render in template
26
- */
27
- constructor(app, template, templateData = {}, i18n = null) {
28
- super(app);
29
- const dirname = url.fileURLToPath(new URL('.', import.meta.url));
30
- if (!path.isAbsolute(template)) {
31
- if (
32
- fs.existsSync(
33
- `${this.app.foldersConfig.emails}/${path.basename(template)}`,
34
- )
35
- ) {
36
- this.template = `${this.app.foldersConfig.emails}/${path.basename(
37
- template,
38
- )}`;
39
- } else if (
40
- fs.existsSync(
41
- path.join(dirname, `/templates/${path.basename(template)}`),
42
- )
43
- ) {
44
- this.template = path.join(
45
- dirname,
46
- `/templates/${path.basename(template)}`,
47
- );
48
- } else {
49
- this.template = path.join(dirname, `/templates/emptyTemplate`);
50
- this.logger.error(
51
- `Template '${template}' not found. Using 'emptyTemplate' as a fallback`,
52
- );
53
- }
54
- }
55
- this.templateData = templateData;
56
- this.i18n = i18n ?? {
57
- t: (str) => str,
58
- locale: 'en', // todo change it to config
59
- };
60
- this.locale = this.i18n?.language;
61
- }
62
-
63
- /**
64
- * Render template
65
- * @param {object} type and fullpath
66
- * @param {object} templateData
67
- * @returns string
68
- */
69
- // eslint-disable-next-line class-methods-use-this
70
- async #renderTemplateFile({ type, fullPath } = {}, templateData = {}) {
71
- if (!type) {
72
- return null;
73
- }
74
-
75
- switch (type) {
76
- case 'html':
77
- case 'text':
78
- case 'css':
79
- return fs.promises.readFile(fullPath, { encoding: 'utf8' });
80
- case 'pug': {
81
- const compiledFunction = pug.compileFile(fullPath);
82
- return compiledFunction(templateData);
83
- }
84
- default:
85
- throw new Error(`Template type ${type} is not supported`);
86
- }
87
- }
88
-
89
- /**
90
- * Render template
91
- * @return {Promise}
92
- */
93
- async renderTemplate() {
94
- const files = await fs.promises.readdir(this.template);
95
- const templates = {};
96
- for (const file of files) {
97
- const [name, extension] = file.split('.');
98
- templates[name] = {
99
- type: extension,
100
- fullPath: path.join(this.template, file),
101
- };
102
- }
103
-
104
- if (!templates.html || !templates.subject) {
105
- throw new Error(
106
- 'Template HTML and Subject must be provided. Please follow documentation for details https://framework.adaptivestone.com/docs/email',
107
- );
108
- }
109
- const mailConfig = this.app.getConfig('mail');
110
-
111
- const templateDataToRender = {
112
- locale: this.locale,
113
- t: this.i18n.t.bind(this.i18n),
114
- ...mailConfig.globalVariablesToTemplates,
115
- ...this.templateData,
116
- };
117
-
118
- const [htmlRendered, subjectRendered, textRendered, extraCss] =
119
- await Promise.all([
120
- this.#renderTemplateFile(templates.html, templateDataToRender),
121
- this.#renderTemplateFile(templates.subject, templateDataToRender),
122
- this.#renderTemplateFile(templates.text, templateDataToRender),
123
- this.#renderTemplateFile(templates.style),
124
- ]);
125
-
126
- juice.tableElements = ['TABLE'];
127
-
128
- const juiceResourcesAsync = promisify(juice.juiceResources);
129
-
130
- const inlinedHTML = await juiceResourcesAsync(htmlRendered, {
131
- preserveImportant: true,
132
- webResources: mailConfig.webResources,
133
- extraCss,
134
- });
135
- return {
136
- htmlRaw: htmlRendered,
137
- subject: subjectRendered,
138
- text: textRendered,
139
- inlinedHTML,
140
- };
141
- }
142
-
143
- /**
144
- * Send email
145
- * @param {string} to email send to
146
- * @param {string} [from = mailConfig.from]
147
- * @param {object} [aditionalNodemailerOptions = {}] additional option to nodemailer
148
- * @return {Promise}
149
- */
150
- async send(to, from = null, aditionalNodemailerOptions = {}) {
151
- const { subject, text, inlinedHTML } = await this.renderTemplate();
152
-
153
- return this.constructor.sendRaw(
154
- this.app,
155
- to,
156
- subject,
157
- inlinedHTML,
158
- text,
159
- from,
160
- aditionalNodemailerOptions,
161
- );
162
- }
163
-
164
- /**
165
- * Send provided text (html) to email. Low level function. All data should be prepared before sending (like inline styles)
166
- * @param {import('../../../server.js').default['app']} app application
167
- * @param {string} to send to
168
- * @param {string} subject email topic
169
- * @param {string} html hmlt body of emain
170
- * @param {string} [text] if not provided will be generated from html string
171
- * @param {string} [from = mailConfig.from] from. If not provided will be grabbed from config
172
- * @param {object} [additionalNodeMailerOption = {}] any otipns to pass to nodemailer https://nodemailer.com/message/
173
- */
174
- static async sendRaw(
175
- app,
176
- to,
177
- subject,
178
- html,
179
- text = null,
180
- from = null,
181
- additionalNodeMailerOption = {},
182
- ) {
183
- if (!app || !to || !subject || !html) {
184
- throw new Error('App, to, subject and html is required fields.');
185
- }
186
- const mailConfig = app.getConfig('mail');
187
- if (!from) {
188
- // eslint-disable-next-line no-param-reassign
189
- from = mailConfig.from;
190
- }
191
-
192
- if (!text) {
193
- // eslint-disable-next-line no-param-reassign
194
- text = convert(html, {
195
- selectors: [{ selector: 'img', format: 'skip' }],
196
- });
197
- }
198
- const transportConfig = mailConfig.transports[mailConfig.transport];
199
- const transport = mailTransports[mailConfig.transport];
200
- const transporter = nodemailer.createTransport(transport(transportConfig));
201
-
202
- return transporter.sendMail({
203
- from,
204
- to,
205
- subject,
206
- text,
207
- html,
208
- ...additionalNodeMailerOption,
209
- });
210
- }
211
-
212
- static get loggerGroup() {
213
- return 'email_';
214
- }
215
- }
216
-
217
- export default Mail;
@@ -1 +0,0 @@
1
- This folder for you resources to inline
@@ -1,9 +0,0 @@
1
- doctype html
2
- html(lang='en')
3
- head
4
- meta(charset='UTF-8')
5
- title New message
6
- body
7
- h1 Good day
8
- p
9
- | Sorry, message template not found
@@ -1 +0,0 @@
1
- = `New message`
@@ -1,8 +0,0 @@
1
- doctype html
2
- html(lang='en')
3
- head
4
- meta(charset='UTF-8')
5
- body
6
- h1 #{t('email.passwordRecovery')}
7
- p #{t('email.passwordChanged')} #{link}
8
-
@@ -1,2 +0,0 @@
1
- = `${t('email.passwordRecovery')}`
2
-
@@ -1,3 +0,0 @@
1
- .
2
- #{t('email.greeating')}
3
- #{t('email.passwordRecovery')} #{link}
@@ -1,10 +0,0 @@
1
- doctype html
2
- html(lang='en')
3
- head
4
- meta(charset='UTF-8')
5
- title верификация емейла
6
- body
7
- h1 Добрый день #{username}
8
- p
9
- | Для верификации емейла перейдите по ссылке
10
- a(href='#{link}') #{link}
@@ -1 +0,0 @@
1
- = `Верификаия емейла`
@@ -1 +0,0 @@
1
- = `Добрый день {{username}} Для верификации емейла перейдите по ссылке ${link}`
@@ -1,3 +0,0 @@
1
- import email from './email/index.js';
2
-
3
- export { email };