node-server-engine 1.1.2 → 1.1.3

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 (469) hide show
  1. package/.env.example +193 -193
  2. package/.mocharc.js +13 -13
  3. package/.nycrc +18 -18
  4. package/.prettierrc +7 -7
  5. package/Dockerfile +30 -30
  6. package/README.md +991 -1025
  7. package/babel.config.json +35 -35
  8. package/dist/const/DebeziumEvent.js.map +1 -1
  9. package/dist/const/LogSeverity.js.map +1 -1
  10. package/dist/const/index.js.map +1 -1
  11. package/dist/const/metrics.js.map +1 -1
  12. package/dist/const/mime.js.map +1 -1
  13. package/dist/const/tokenIssuer.js.map +1 -1
  14. package/dist/db/migrations/20241030121500-create-sequelize-meta-table.js.map +1 -1
  15. package/dist/db/models/SequelizeMeta.js.map +1 -1
  16. package/dist/db/models/index.js.map +1 -1
  17. package/dist/entities/ElasticSearch/ElasticSearch.js +7 -7
  18. package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
  19. package/dist/entities/ElasticSearch/ElasticSearch.types.js.map +1 -1
  20. package/dist/entities/ElasticSearch/index.js.map +1 -1
  21. package/dist/entities/Endpoint/Endpoint.js +8 -8
  22. package/dist/entities/Endpoint/Endpoint.js.map +1 -1
  23. package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
  24. package/dist/entities/Endpoint/index.js.map +1 -1
  25. package/dist/entities/EngineError/EngineError.js +2 -2
  26. package/dist/entities/EngineError/EngineError.js.map +1 -1
  27. package/dist/entities/EngineError/EngineError.types.js.map +1 -1
  28. package/dist/entities/EngineError/index.js.map +1 -1
  29. package/dist/entities/KeySet/KeySet.js +3 -3
  30. package/dist/entities/KeySet/KeySet.js.map +1 -1
  31. package/dist/entities/KeySet/KeySet.types.js.map +1 -1
  32. package/dist/entities/KeySet/index.js.map +1 -1
  33. package/dist/entities/LifecycleController/LifecycleController.js.map +1 -1
  34. package/dist/entities/LifecycleController/LifecycleController.types.js.map +1 -1
  35. package/dist/entities/LifecycleController/index.js.map +1 -1
  36. package/dist/entities/Localizator/Localizator.js +7 -7
  37. package/dist/entities/Localizator/Localizator.js.map +1 -1
  38. package/dist/entities/Localizator/Localizator.types.js.map +1 -1
  39. package/dist/entities/Localizator/guessNamingConvention/guessNamingConvention.js.map +1 -1
  40. package/dist/entities/Localizator/guessNamingConvention/index.js.map +1 -1
  41. package/dist/entities/Localizator/index.js.map +1 -1
  42. package/dist/entities/MessageHandler/MessageHandler.js +2 -2
  43. package/dist/entities/MessageHandler/MessageHandler.js.map +1 -1
  44. package/dist/entities/MessageHandler/MessageHandler.types.js.map +1 -1
  45. package/dist/entities/MessageHandler/index.js.map +1 -1
  46. package/dist/entities/PubSub/PubSub.js +25 -25
  47. package/dist/entities/PubSub/PubSub.js.map +1 -1
  48. package/dist/entities/PubSub/PubSub.types.js.map +1 -1
  49. package/dist/entities/PubSub/handleMessage/handleMessage.js +6 -6
  50. package/dist/entities/PubSub/handleMessage/handleMessage.js.map +1 -1
  51. package/dist/entities/PubSub/handleMessage/index.js.map +1 -1
  52. package/dist/entities/PubSub/index.js.map +1 -1
  53. package/dist/entities/PushNotification/PushNotification.js +4 -4
  54. package/dist/entities/PushNotification/PushNotification.js.map +1 -1
  55. package/dist/entities/PushNotification/PushNotification.types.js.map +1 -1
  56. package/dist/entities/PushNotification/index.js.map +1 -1
  57. package/dist/entities/Redis/Redis.js +8 -8
  58. package/dist/entities/Redis/Redis.js.map +1 -1
  59. package/dist/entities/Redis/Redis.types.js.map +1 -1
  60. package/dist/entities/Redis/Redis.validate.js +2 -2
  61. package/dist/entities/Redis/Redis.validate.js.map +1 -1
  62. package/dist/entities/Redis/index.js.map +1 -1
  63. package/dist/entities/Sequelize/Sequelize.config.js +42 -2
  64. package/dist/entities/Sequelize/Sequelize.config.js.map +1 -1
  65. package/dist/entities/Sequelize/Sequelize.js +3 -3
  66. package/dist/entities/Sequelize/Sequelize.js.map +1 -1
  67. package/dist/entities/Sequelize/Sequelize.types.js.map +1 -1
  68. package/dist/entities/Sequelize/Sequelize.validate.js +2 -2
  69. package/dist/entities/Sequelize/Sequelize.validate.js.map +1 -1
  70. package/dist/entities/Sequelize/index.js.map +1 -1
  71. package/dist/entities/Server/Server.const.js.map +1 -1
  72. package/dist/entities/Server/Server.js +2 -2
  73. package/dist/entities/Server/Server.js.map +1 -1
  74. package/dist/entities/Server/Server.types.js.map +1 -1
  75. package/dist/entities/Server/index.js.map +1 -1
  76. package/dist/entities/SocketClient/SocketClient.js +15 -15
  77. package/dist/entities/SocketClient/SocketClient.js.map +1 -1
  78. package/dist/entities/SocketClient/SocketClient.types.js.map +1 -1
  79. package/dist/entities/SocketClient/index.js.map +1 -1
  80. package/dist/entities/SocketClient/parseMessage/index.js.map +1 -1
  81. package/dist/entities/SocketClient/parseMessage/parseMessage.js +2 -2
  82. package/dist/entities/SocketClient/parseMessage/parseMessage.js.map +1 -1
  83. package/dist/entities/Storage/Storage.js +20 -20
  84. package/dist/entities/Storage/Storage.js.map +1 -1
  85. package/dist/entities/Storage/Storage.types.js.map +1 -1
  86. package/dist/entities/Storage/index.js.map +1 -1
  87. package/dist/entities/ValidationError/ValidationError.js.map +1 -1
  88. package/dist/entities/ValidationError/index.js.map +1 -1
  89. package/dist/entities/WebError/WebError.js +4 -4
  90. package/dist/entities/WebError/WebError.js.map +1 -1
  91. package/dist/entities/WebError/WebError.types.js.map +1 -1
  92. package/dist/entities/WebError/index.js.map +1 -1
  93. package/dist/entities/index.js.map +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/metrics/debug.js.map +1 -1
  96. package/dist/metrics/index.js.map +1 -1
  97. package/dist/metrics/request.js.map +1 -1
  98. package/dist/middleware/authAdmin/authAdmin.js.map +1 -1
  99. package/dist/middleware/authAdmin/authAdmin.types.js.map +1 -1
  100. package/dist/middleware/authAdmin/index.js.map +1 -1
  101. package/dist/middleware/authHmac/authHmac.js.map +1 -1
  102. package/dist/middleware/authHmac/authHmac.types.js.map +1 -1
  103. package/dist/middleware/authHmac/index.js.map +1 -1
  104. package/dist/middleware/authJwt/authJwt.js.map +1 -1
  105. package/dist/middleware/authJwt/authJwt.types.js.map +1 -1
  106. package/dist/middleware/authJwt/index.js.map +1 -1
  107. package/dist/middleware/authStatic/authStatic.js +3 -3
  108. package/dist/middleware/authStatic/authStatic.js.map +1 -1
  109. package/dist/middleware/authStatic/index.js.map +1 -1
  110. package/dist/middleware/authTls/authTls.js +8 -8
  111. package/dist/middleware/authTls/authTls.js.map +1 -1
  112. package/dist/middleware/authTls/authTls.types.js.map +1 -1
  113. package/dist/middleware/authTls/index.js.map +1 -1
  114. package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
  115. package/dist/middleware/error/error.js.map +1 -1
  116. package/dist/middleware/error/index.js.map +1 -1
  117. package/dist/middleware/fileUploader/compressAvatar/compressAvatar.js +2 -2
  118. package/dist/middleware/fileUploader/compressAvatar/compressAvatar.js.map +1 -1
  119. package/dist/middleware/fileUploader/compressAvatar/compressAvatar.types.js.map +1 -1
  120. package/dist/middleware/fileUploader/compressAvatar/index.js.map +1 -1
  121. package/dist/middleware/fileUploader/fileUploader.js +12 -12
  122. package/dist/middleware/fileUploader/fileUploader.js.map +1 -1
  123. package/dist/middleware/fileUploader/fileUploader.types.js.map +1 -1
  124. package/dist/middleware/fileUploader/index.js.map +1 -1
  125. package/dist/middleware/fileUploader/isMultiPart/index.js.map +1 -1
  126. package/dist/middleware/fileUploader/isMultiPart/isMultipart.js.map +1 -1
  127. package/dist/middleware/fileUploader/validate/index.js.map +1 -1
  128. package/dist/middleware/fileUploader/validate/validate.js.map +1 -1
  129. package/dist/middleware/fourOhFour/fourOhFour.js.map +1 -1
  130. package/dist/middleware/fourOhFour/index.js.map +1 -1
  131. package/dist/middleware/geminiFileUploader/geminiFileUploader.js.map +1 -1
  132. package/dist/middleware/geminiFileUploader/index.js.map +1 -1
  133. package/dist/middleware/healthCheck/healthCheck.js +2 -2
  134. package/dist/middleware/healthCheck/healthCheck.js.map +1 -1
  135. package/dist/middleware/healthCheck/index.js.map +1 -1
  136. package/dist/middleware/index.js.map +1 -1
  137. package/dist/middleware/metrics/index.js.map +1 -1
  138. package/dist/middleware/metrics/metrics.js.map +1 -1
  139. package/dist/middleware/requestMetrics/index.js.map +1 -1
  140. package/dist/middleware/requestMetrics/requestMetrics.js.map +1 -1
  141. package/dist/middleware/swaggerDocs/index.js.map +1 -1
  142. package/dist/middleware/swaggerDocs/swaggerDocs.js +7 -7
  143. package/dist/middleware/swaggerDocs/swaggerDocs.js.map +1 -1
  144. package/dist/middleware/swaggerDocs/swaggerDocs.types.js.map +1 -1
  145. package/dist/middleware/userResolver/index.js.map +1 -1
  146. package/dist/middleware/userResolver/userResolver.js.map +1 -1
  147. package/dist/middleware/validate/index.js.map +1 -1
  148. package/dist/middleware/validate/validate.js.map +1 -1
  149. package/dist/middleware/version/index.js.map +1 -1
  150. package/dist/middleware/version/version.js +3 -3
  151. package/dist/middleware/version/version.js.map +1 -1
  152. package/dist/utils/checkEnvironment/index.js +13 -13
  153. package/dist/utils/checkEnvironment/index.js.map +1 -1
  154. package/dist/utils/createHttpServer/createHttpServer.js.map +1 -1
  155. package/dist/utils/createHttpServer/createHttpServer.validate.js +2 -2
  156. package/dist/utils/createHttpServer/createHttpServer.validate.js.map +1 -1
  157. package/dist/utils/createHttpServer/index.js.map +1 -1
  158. package/dist/utils/createSortedObject/createSortedObject.js.map +1 -1
  159. package/dist/utils/createSortedObject/index.js.map +1 -1
  160. package/dist/utils/dbMigration/dbMigration.js +8 -8
  161. package/dist/utils/dbMigration/dbMigration.js.map +1 -1
  162. package/dist/utils/dbMigration/dbMigration.types.js.map +1 -1
  163. package/dist/utils/dbMigration/index.js.map +1 -1
  164. package/dist/utils/dbMigration/migrateMetadataTable/index.js.map +1 -1
  165. package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.d.ts +2 -2
  166. package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.js +47 -15
  167. package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.js.map +1 -1
  168. package/dist/utils/envAssert/envAssert.js +6 -6
  169. package/dist/utils/envAssert/envAssert.js.map +1 -1
  170. package/dist/utils/envAssert/index.js.map +1 -1
  171. package/dist/utils/envAssert/validators/hostList.js +2 -2
  172. package/dist/utils/envAssert/validators/hostList.js.map +1 -1
  173. package/dist/utils/envAssert/validators/index.js.map +1 -1
  174. package/dist/utils/envAssert/validators/ipList.js +2 -2
  175. package/dist/utils/envAssert/validators/ipList.js.map +1 -1
  176. package/dist/utils/envAssert/validators/path.js +2 -2
  177. package/dist/utils/envAssert/validators/path.js.map +1 -1
  178. package/dist/utils/envAssert/validators/string.js +2 -2
  179. package/dist/utils/envAssert/validators/string.js.map +1 -1
  180. package/dist/utils/envAssert/validators/stringList.js +3 -3
  181. package/dist/utils/envAssert/validators/stringList.js.map +1 -1
  182. package/dist/utils/filter/filter.js +4 -4
  183. package/dist/utils/filter/filter.js.map +1 -1
  184. package/dist/utils/filter/index.js.map +1 -1
  185. package/dist/utils/getDynamicLink/getDynamicLink.js.map +1 -1
  186. package/dist/utils/getDynamicLink/getDynamicLink.types.js.map +1 -1
  187. package/dist/utils/getDynamicLink/getDynamicLink.validate.js.map +1 -1
  188. package/dist/utils/getDynamicLink/index.js.map +1 -1
  189. package/dist/utils/hmac/checkEnv/checkEnv.js +2 -2
  190. package/dist/utils/hmac/checkEnv/checkEnv.js.map +1 -1
  191. package/dist/utils/hmac/checkEnv/index.js.map +1 -1
  192. package/dist/utils/hmac/createHmac/createHmac.js.map +1 -1
  193. package/dist/utils/hmac/createHmac/index.js.map +1 -1
  194. package/dist/utils/hmac/index.js.map +1 -1
  195. package/dist/utils/hmac/index.types.js.map +1 -1
  196. package/dist/utils/hmac/signPayload/index.js.map +1 -1
  197. package/dist/utils/hmac/signPayload/signPayload.js.map +1 -1
  198. package/dist/utils/hmac/verifySignature/index.js.map +1 -1
  199. package/dist/utils/hmac/verifySignature/verifySignature.js.map +1 -1
  200. package/dist/utils/index.js.map +1 -1
  201. package/dist/utils/jwt/index.js.map +1 -1
  202. package/dist/utils/jwt/jwt.js.map +1 -1
  203. package/dist/utils/jwt/jwt.types.js.map +1 -1
  204. package/dist/utils/report/index.js.map +1 -1
  205. package/dist/utils/report/output.js.map +1 -1
  206. package/dist/utils/report/output.types.js.map +1 -1
  207. package/dist/utils/report/report.js.map +1 -1
  208. package/dist/utils/report/report.types.js.map +1 -1
  209. package/dist/utils/request/index.js.map +1 -1
  210. package/dist/utils/request/request.js.map +1 -1
  211. package/dist/utils/semverCompare/index.js.map +1 -1
  212. package/dist/utils/semverCompare/semverCompare.js +5 -5
  213. package/dist/utils/semverCompare/semverCompare.js.map +1 -1
  214. package/dist/utils/sendEmail/index.js.map +1 -1
  215. package/dist/utils/sendEmail/sendEmail.js +8 -8
  216. package/dist/utils/sendEmail/sendEmail.js.map +1 -1
  217. package/dist/utils/sendEmail/sendEmail.types.js.map +1 -1
  218. package/dist/utils/sendPush/index.js.map +1 -1
  219. package/dist/utils/sendPush/sendPush.js +5 -5
  220. package/dist/utils/sendPush/sendPush.js.map +1 -1
  221. package/dist/utils/sendPush/sendPush.types.js.map +1 -1
  222. package/dist/utils/tlsConfig/index.js.map +1 -1
  223. package/dist/utils/tlsConfig/tlsConfig.js +2 -2
  224. package/dist/utils/tlsConfig/tlsConfig.js.map +1 -1
  225. package/dist/utils/tlsConfig/tlsConfig.types.js.map +1 -1
  226. package/dist/utils/tlsConfig/tlsConfig.validate.js +2 -2
  227. package/dist/utils/tlsConfig/tlsConfig.validate.js.map +1 -1
  228. package/dist/utils/tlsRequest/index.js.map +1 -1
  229. package/dist/utils/tlsRequest/tlsRequest.js.map +1 -1
  230. package/dist/utils/trimPathSlash/index.js.map +1 -1
  231. package/dist/utils/trimPathSlash/trimPathSlash.js +4 -4
  232. package/dist/utils/trimPathSlash/trimPathSlash.js.map +1 -1
  233. package/eslint.config.mjs +11 -11
  234. package/package.json +164 -161
  235. package/src/const/DebeziumEvent.ts +6 -6
  236. package/src/const/LogSeverity.ts +7 -7
  237. package/src/const/index.ts +5 -5
  238. package/src/const/metrics.ts +6 -6
  239. package/src/const/mime.ts +37 -37
  240. package/src/const/tokenIssuer.ts +9 -9
  241. package/src/db/migrations/20241030121500-create-sequelize-meta-table.ts +29 -29
  242. package/src/db/models/SequelizeMeta.ts +16 -16
  243. package/src/db/models/index.ts +2 -2
  244. package/src/entities/ElasticSearch/ElasticSearch.ts +103 -103
  245. package/src/entities/ElasticSearch/ElasticSearch.types.ts +7 -7
  246. package/src/entities/ElasticSearch/index.ts +2 -2
  247. package/src/entities/Endpoint/Endpoint.test.ts +337 -337
  248. package/src/entities/Endpoint/Endpoint.ts +202 -202
  249. package/src/entities/Endpoint/Endpoint.types.ts +205 -205
  250. package/src/entities/Endpoint/index.ts +2 -2
  251. package/src/entities/EngineError/EngineError.ts +28 -28
  252. package/src/entities/EngineError/EngineError.types.ts +15 -15
  253. package/src/entities/EngineError/index.ts +2 -2
  254. package/src/entities/KeySet/KeySet.test.ts +126 -126
  255. package/src/entities/KeySet/KeySet.ts +172 -172
  256. package/src/entities/KeySet/KeySet.types.ts +28 -28
  257. package/src/entities/KeySet/index.ts +2 -2
  258. package/src/entities/LifecycleController/LifecycleController.test.ts +48 -48
  259. package/src/entities/LifecycleController/LifecycleController.ts +24 -24
  260. package/src/entities/LifecycleController/LifecycleController.types.ts +5 -5
  261. package/src/entities/LifecycleController/index.ts +2 -2
  262. package/src/entities/Localizator/Localizator.ts +139 -139
  263. package/src/entities/Localizator/Localizator.types.ts +52 -52
  264. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.test.ts +165 -165
  265. package/src/entities/Localizator/guessNamingConvention/guessNamingConvention.ts +58 -58
  266. package/src/entities/Localizator/guessNamingConvention/index.ts +1 -1
  267. package/src/entities/Localizator/index.ts +2 -2
  268. package/src/entities/MessageHandler/MessageHandler.test.ts +130 -130
  269. package/src/entities/MessageHandler/MessageHandler.ts +72 -72
  270. package/src/entities/MessageHandler/MessageHandler.types.ts +15 -15
  271. package/src/entities/MessageHandler/index.ts +2 -2
  272. package/src/entities/PubSub/PubSub.test.ts +297 -297
  273. package/src/entities/PubSub/PubSub.ts +202 -202
  274. package/src/entities/PubSub/PubSub.types.ts +76 -76
  275. package/src/entities/PubSub/handleMessage/handleMessage.test.ts +102 -102
  276. package/src/entities/PubSub/handleMessage/handleMessage.ts +65 -65
  277. package/src/entities/PubSub/handleMessage/index.ts +1 -1
  278. package/src/entities/PubSub/index.ts +2 -2
  279. package/src/entities/PushNotification/PushNotification.test.ts +35 -35
  280. package/src/entities/PushNotification/PushNotification.ts +44 -44
  281. package/src/entities/PushNotification/PushNotification.types.ts +25 -25
  282. package/src/entities/PushNotification/index.ts +2 -2
  283. package/src/entities/Redis/Redis.ts +71 -71
  284. package/src/entities/Redis/Redis.types.ts +19 -19
  285. package/src/entities/Redis/Redis.validate.ts +17 -17
  286. package/src/entities/Redis/index.ts +2 -2
  287. package/src/entities/Sequelize/Sequelize.config.ts +59 -29
  288. package/src/entities/Sequelize/Sequelize.test.ts +21 -21
  289. package/src/entities/Sequelize/Sequelize.ts +75 -75
  290. package/src/entities/Sequelize/Sequelize.types.ts +10 -10
  291. package/src/entities/Sequelize/Sequelize.validate.ts +15 -15
  292. package/src/entities/Sequelize/index.ts +2 -2
  293. package/src/entities/Server/Server.const.ts +56 -56
  294. package/src/entities/Server/Server.test.ts +272 -272
  295. package/src/entities/Server/Server.ts +445 -445
  296. package/src/entities/Server/Server.types.ts +88 -88
  297. package/src/entities/Server/index.ts +2 -2
  298. package/src/entities/SocketClient/SocketClient.test.ts +392 -392
  299. package/src/entities/SocketClient/SocketClient.ts +401 -401
  300. package/src/entities/SocketClient/SocketClient.types.ts +62 -62
  301. package/src/entities/SocketClient/index.ts +2 -2
  302. package/src/entities/SocketClient/parseMessage/index.ts +1 -1
  303. package/src/entities/SocketClient/parseMessage/parseMessage.test.ts +20 -20
  304. package/src/entities/SocketClient/parseMessage/parseMessage.ts +26 -26
  305. package/src/entities/Storage/Storage.test.ts +58 -58
  306. package/src/entities/Storage/Storage.ts +219 -219
  307. package/src/entities/Storage/Storage.types.ts +57 -57
  308. package/src/entities/Storage/index.ts +2 -2
  309. package/src/entities/ValidationError/ValidationError.ts +34 -34
  310. package/src/entities/ValidationError/index.ts +1 -1
  311. package/src/entities/WebError/WebError.test.ts +18 -18
  312. package/src/entities/WebError/WebError.ts +23 -23
  313. package/src/entities/WebError/WebError.types.ts +9 -9
  314. package/src/entities/WebError/index.ts +2 -2
  315. package/src/entities/index.ts +16 -16
  316. package/src/index.ts +4 -4
  317. package/src/metrics/debug.ts +10 -10
  318. package/src/metrics/index.ts +2 -2
  319. package/src/metrics/request.ts +17 -17
  320. package/src/middleware/authAdmin/authAdmin.test.ts +199 -199
  321. package/src/middleware/authAdmin/authAdmin.ts +114 -114
  322. package/src/middleware/authAdmin/authAdmin.types.ts +19 -19
  323. package/src/middleware/authAdmin/index.ts +2 -2
  324. package/src/middleware/authHmac/authHmac.test.ts +86 -86
  325. package/src/middleware/authHmac/authHmac.ts +56 -56
  326. package/src/middleware/authHmac/authHmac.types.ts +7 -7
  327. package/src/middleware/authHmac/index.ts +2 -2
  328. package/src/middleware/authJwt/authJwt.test.ts +54 -54
  329. package/src/middleware/authJwt/authJwt.ts +55 -55
  330. package/src/middleware/authJwt/authJwt.types.ts +14 -14
  331. package/src/middleware/authJwt/index.ts +2 -2
  332. package/src/middleware/authStatic/authStatic.test.ts +36 -36
  333. package/src/middleware/authStatic/authStatic.ts +45 -45
  334. package/src/middleware/authStatic/index.ts +1 -1
  335. package/src/middleware/authTls/authTls.test.ts +138 -138
  336. package/src/middleware/authTls/authTls.ts +106 -106
  337. package/src/middleware/authTls/authTls.types.ts +13 -13
  338. package/src/middleware/authTls/index.ts +2 -2
  339. package/src/middleware/checkPermission/checkPermission.ts +32 -32
  340. package/src/middleware/error/error.test.ts +60 -60
  341. package/src/middleware/error/error.ts +25 -25
  342. package/src/middleware/error/index.ts +1 -1
  343. package/src/middleware/fileUploader/compressAvatar/compressAvatar.ts +25 -25
  344. package/src/middleware/fileUploader/compressAvatar/compressAvatar.types.ts +12 -12
  345. package/src/middleware/fileUploader/compressAvatar/index.ts +2 -2
  346. package/src/middleware/fileUploader/fileUploader.test.ts +310 -310
  347. package/src/middleware/fileUploader/fileUploader.ts +303 -303
  348. package/src/middleware/fileUploader/fileUploader.types.ts +52 -52
  349. package/src/middleware/fileUploader/index.ts +2 -2
  350. package/src/middleware/fileUploader/isMultiPart/index.ts +1 -1
  351. package/src/middleware/fileUploader/isMultiPart/isMultipart.ts +9 -9
  352. package/src/middleware/fileUploader/validate/index.ts +1 -1
  353. package/src/middleware/fileUploader/validate/validate.ts +27 -27
  354. package/src/middleware/fourOhFour/fourOhFour.test.ts +14 -14
  355. package/src/middleware/fourOhFour/fourOhFour.ts +13 -13
  356. package/src/middleware/fourOhFour/index.ts +1 -1
  357. package/src/middleware/geminiFileUploader/geminiFileUploader.ts +117 -117
  358. package/src/middleware/geminiFileUploader/index.ts +1 -1
  359. package/src/middleware/healthCheck/healthCheck.test.ts +12 -12
  360. package/src/middleware/healthCheck/healthCheck.ts +14 -14
  361. package/src/middleware/healthCheck/index.ts +1 -1
  362. package/src/middleware/index.ts +17 -17
  363. package/src/middleware/metrics/index.ts +1 -1
  364. package/src/middleware/metrics/metrics.test.ts +46 -46
  365. package/src/middleware/metrics/metrics.ts +24 -24
  366. package/src/middleware/requestMetrics/index.ts +1 -1
  367. package/src/middleware/requestMetrics/requestMetrics.test.ts +77 -77
  368. package/src/middleware/requestMetrics/requestMetrics.ts +20 -20
  369. package/src/middleware/swaggerDocs/index.ts +2 -2
  370. package/src/middleware/swaggerDocs/swaggerDocs.ts +114 -114
  371. package/src/middleware/swaggerDocs/swaggerDocs.types.ts +41 -41
  372. package/src/middleware/userResolver/index.ts +1 -1
  373. package/src/middleware/userResolver/userResolver.test.ts +35 -35
  374. package/src/middleware/userResolver/userResolver.ts +35 -35
  375. package/src/middleware/validate/index.ts +1 -1
  376. package/src/middleware/validate/validate.test.ts +43 -43
  377. package/src/middleware/validate/validate.ts +25 -25
  378. package/src/middleware/version/index.ts +1 -1
  379. package/src/middleware/version/version.test.ts +23 -23
  380. package/src/middleware/version/version.ts +12 -12
  381. package/src/utils/checkEnvironment/index.ts +49 -49
  382. package/src/utils/createHttpServer/createHttpServer.test.ts +24 -24
  383. package/src/utils/createHttpServer/createHttpServer.ts +34 -34
  384. package/src/utils/createHttpServer/createHttpServer.validate.ts +17 -17
  385. package/src/utils/createHttpServer/index.ts +1 -1
  386. package/src/utils/createSortedObject/createSortedObject.ts +20 -20
  387. package/src/utils/createSortedObject/createSortedObjet.test.ts +47 -47
  388. package/src/utils/createSortedObject/index.ts +1 -1
  389. package/src/utils/dbMigration/dbMigration.test.ts +209 -209
  390. package/src/utils/dbMigration/dbMigration.ts +199 -199
  391. package/src/utils/dbMigration/dbMigration.types.ts +11 -11
  392. package/src/utils/dbMigration/index.ts +2 -2
  393. package/src/utils/dbMigration/migrateMetadataTable/index.ts +1 -1
  394. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.test.ts +59 -59
  395. package/src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts +102 -70
  396. package/src/utils/envAssert/envAssert.ts +31 -31
  397. package/src/utils/envAssert/index.ts +1 -1
  398. package/src/utils/envAssert/validators/hostList.ts +17 -17
  399. package/src/utils/envAssert/validators/index.ts +5 -5
  400. package/src/utils/envAssert/validators/ipList.ts +13 -13
  401. package/src/utils/envAssert/validators/path.ts +13 -13
  402. package/src/utils/envAssert/validators/string.ts +9 -9
  403. package/src/utils/envAssert/validators/stringList.ts +13 -13
  404. package/src/utils/filter/filter.ts +17 -17
  405. package/src/utils/filter/index.ts +1 -1
  406. package/src/utils/getDynamicLink/getDynamicLink.test.ts +51 -51
  407. package/src/utils/getDynamicLink/getDynamicLink.ts +28 -28
  408. package/src/utils/getDynamicLink/getDynamicLink.types.ts +11 -11
  409. package/src/utils/getDynamicLink/getDynamicLink.validate.ts +6 -6
  410. package/src/utils/getDynamicLink/index.ts +2 -2
  411. package/src/utils/hmac/checkEnv/checkEnv.test.ts +18 -18
  412. package/src/utils/hmac/checkEnv/checkEnv.ts +9 -9
  413. package/src/utils/hmac/checkEnv/index.ts +1 -1
  414. package/src/utils/hmac/createHmac/createHmac.ts +33 -33
  415. package/src/utils/hmac/createHmac/index.ts +1 -1
  416. package/src/utils/hmac/index.ts +4 -4
  417. package/src/utils/hmac/index.types.ts +13 -13
  418. package/src/utils/hmac/signPayload/index.ts +1 -1
  419. package/src/utils/hmac/signPayload/signPayload.ts +16 -16
  420. package/src/utils/hmac/verifySignature/index.ts +1 -1
  421. package/src/utils/hmac/verifySignature/verifySignature.ts +24 -24
  422. package/src/utils/index.ts +26 -26
  423. package/src/utils/jwt/index.ts +2 -2
  424. package/src/utils/jwt/jwt.test.ts +41 -41
  425. package/src/utils/jwt/jwt.ts +204 -204
  426. package/src/utils/jwt/jwt.types.ts +21 -21
  427. package/src/utils/report/index.ts +3 -3
  428. package/src/utils/report/output.ts +45 -45
  429. package/src/utils/report/output.types.ts +70 -70
  430. package/src/utils/report/report.test.ts +133 -133
  431. package/src/utils/report/report.ts +134 -134
  432. package/src/utils/report/report.types.ts +13 -13
  433. package/src/utils/request/index.ts +1 -1
  434. package/src/utils/request/request.test.ts +26 -26
  435. package/src/utils/request/request.ts +48 -48
  436. package/src/utils/semverCompare/index.ts +1 -1
  437. package/src/utils/semverCompare/semverCompare.test.ts +49 -49
  438. package/src/utils/semverCompare/semverCompare.ts +60 -60
  439. package/src/utils/sendEmail/index.ts +1 -1
  440. package/src/utils/sendEmail/sendEmail.ts +27 -27
  441. package/src/utils/sendEmail/sendEmail.types.ts +7 -7
  442. package/src/utils/sendPush/index.ts +2 -2
  443. package/src/utils/sendPush/sendPush.ts +20 -20
  444. package/src/utils/sendPush/sendPush.types.ts +25 -25
  445. package/src/utils/tlsConfig/index.ts +2 -2
  446. package/src/utils/tlsConfig/tlsConfig.test.ts +32 -32
  447. package/src/utils/tlsConfig/tlsConfig.ts +47 -47
  448. package/src/utils/tlsConfig/tlsConfig.types.ts +11 -11
  449. package/src/utils/tlsConfig/tlsConfig.validate.ts +25 -25
  450. package/src/utils/tlsRequest/index.ts +1 -1
  451. package/src/utils/tlsRequest/tlsRequest.test.ts +63 -63
  452. package/src/utils/tlsRequest/tlsRequest.ts +12 -12
  453. package/src/utils/trimPathSlash/index.ts +1 -1
  454. package/src/utils/trimPathSlash/trimPathSlash.test.ts +26 -26
  455. package/src/utils/trimPathSlash/trimPathSlash.ts +8 -8
  456. package/test/env.ts +56 -56
  457. package/test/factory/index.ts +8 -8
  458. package/test/factory/sequelizeMeta.ts +12 -12
  459. package/test/hooks.ts +37 -37
  460. package/test/index.ts +3 -3
  461. package/test/stub/index.ts +3 -3
  462. package/test/stub/stubLocales.ts +68 -68
  463. package/test/stub/stubPubSub.ts +7 -7
  464. package/test/stub/stubStorage.ts +77 -77
  465. package/test/stub/stubStorage.types.ts +11 -11
  466. package/test/utils/app.ts +31 -31
  467. package/test/utils/index.ts +1 -1
  468. package/tsconfig.build.json +5 -5
  469. package/tsconfig.json +32 -32
@@ -1,126 +1,126 @@
1
- import { randomUUID, createPublicKey } from 'crypto';
2
- import { readFileSync } from 'fs';
3
- import { readFile } from 'fs/promises';
4
- import { AxiosResponse } from 'axios';
5
- import { expect } from 'chai';
6
- import { faker } from '@faker-js/faker';
7
- import { stub, SinonStub } from 'sinon';
8
- import { KeySet } from './KeySet';
9
- import { JWKS } from './KeySet.types';
10
- import * as request from 'utils/request/request';
11
- import * as tlsRequest from 'utils/tlsRequest/tlsRequest';
12
-
13
- // We test with both an RSA key and an EC key
14
- const TEST_JWKS = {
15
- data: {
16
- keys: [
17
- {
18
- alg: 'RS256',
19
- kty: 'RSA',
20
- use: 'sig',
21
- n:
22
- 'u18mjw63ELk8xA4C2Qbi1WTtqcx853iRv9Gfd-zKKmlU2wStnOGnIfnHkrNbl5y8vTMNBKNuqLh3Y_el' +
23
- 'PVSUIWGcy3KByw7VRnBTAze2bsmI0Dvz-89Ar1C2g0Ui6DOYyEa0iiXer4gSQgJ5ddsbIAMJMBT5j96G' +
24
- '1mhbjM2mqekORRyjCZHGeNbofnTvKcJRTStsBPXQ2WEkAf6J1eNZ2-QnNYMVVO44-KXfhQsfaqRoporj' +
25
- '4LvTkNX0kkxyfC3V1R8Qrk-_pHhzPtKtQxiRj2axTVXFoj5I1Po7WgQz2_vBZnWZ-0AIzHXN6F_fmMhy' +
26
- 'PBPk3pbuN7cHBe2cKh_nHQ',
27
- e: 'AQAB',
28
- kid: 'Q0ZCQzEwRTFCOUE3QjI0MUZEREQ0N0I4MTI3OTVFRDkyNTIxQjQ3MA'
29
- },
30
- {
31
- crv: 'P-256',
32
- kty: 'EC',
33
- x: 'ruky13qVa2GM9jnWsBYP_OTsk6fyV_HWC2AjvUkyCv8',
34
- y: 'kIAW58dw6pjO1dy4czpNdsaL8DUc3RKo6Hmses5O_Bc',
35
- kid: '3d-GYUhTwkAfCi9JdvMieQ',
36
- alg: 'EC256',
37
- use: 'sig'
38
- }
39
- ]
40
- }
41
- };
42
-
43
- const TEST_PEMS = TEST_JWKS.data.keys.map((key) =>
44
- createPublicKey({ key, format: 'jwk' }).export({
45
- format: 'pem',
46
- type: 'spki'
47
- })
48
- );
49
-
50
- describe('Entity - KeySet', function () {
51
- let url: string;
52
- let requestStub: SinonStub;
53
- let tlsRequestStub: SinonStub;
54
-
55
- beforeEach(() => {
56
- url = faker.internet.url();
57
-
58
- requestStub = stub(request, 'request').resolves(
59
- TEST_JWKS as unknown as AxiosResponse<JWKS>
60
- );
61
- tlsRequestStub = stub(tlsRequest, 'tlsRequest').resolves(
62
- TEST_JWKS as unknown as AxiosResponse<JWKS>
63
- );
64
- });
65
-
66
- it('should create a key set when fetching', async () => {
67
- const keySet = new KeySet(url);
68
- await keySet.init();
69
-
70
- const keys = keySet.getKeys();
71
- expect(Object.values(keys)).to.have.length(2);
72
- Object.values(keys).forEach((key) => {
73
- expect(TEST_PEMS).to.include(key);
74
- });
75
- });
76
-
77
- it('should make a regular request by default', async () => {
78
- const keySet = new KeySet(url);
79
-
80
- await keySet.init();
81
-
82
- expect(requestStub).to.have.been.calledOnceWithExactly({
83
- url,
84
- method: 'get'
85
- });
86
- expect(tlsRequestStub).to.not.have.been.called;
87
- });
88
-
89
- it('should make a TLS request for internal keysets', async () => {
90
- const keySet = new KeySet(url, { internal: true });
91
-
92
- await keySet.init();
93
-
94
- expect(tlsRequestStub).to.have.been.calledOnceWithExactly({
95
- url,
96
- method: 'get'
97
- });
98
- expect(requestStub).to.not.have.been.called;
99
- });
100
-
101
- it('should read a key from a PEM string', async () => {
102
- const pem = await readFile(
103
- process.env.ADMIN_API_ECDSA_PUBLIC_KEY as string,
104
- 'utf-8'
105
- );
106
-
107
- const keySet = new KeySet(pem, { pem: true });
108
-
109
- await keySet.init();
110
-
111
- expect(tlsRequestStub).to.not.have.been.called;
112
- expect(requestStub).to.not.have.been.called;
113
- expect(Object.keys(keySet.getKeys())).to.have.length(1);
114
- for (const key of Object.values(keySet.getKeys())) {
115
- expect(key).to.equal(pem);
116
- }
117
- });
118
-
119
- it('should not fail if the init did not complete and a key is asked', () => {
120
- const keySet = new KeySet(faker.internet.url());
121
-
122
- const result = keySet.getKey(randomUUID());
123
-
124
- expect(result).to.be.undefined;
125
- });
126
- });
1
+ import { randomUUID, createPublicKey } from 'crypto';
2
+ import { readFileSync } from 'fs';
3
+ import { readFile } from 'fs/promises';
4
+ import { AxiosResponse } from 'axios';
5
+ import { expect } from 'chai';
6
+ import { faker } from '@faker-js/faker';
7
+ import { stub, SinonStub } from 'sinon';
8
+ import { KeySet } from './KeySet';
9
+ import { JWKS } from './KeySet.types';
10
+ import * as request from 'utils/request/request';
11
+ import * as tlsRequest from 'utils/tlsRequest/tlsRequest';
12
+
13
+ // We test with both an RSA key and an EC key
14
+ const TEST_JWKS = {
15
+ data: {
16
+ keys: [
17
+ {
18
+ alg: 'RS256',
19
+ kty: 'RSA',
20
+ use: 'sig',
21
+ n:
22
+ 'u18mjw63ELk8xA4C2Qbi1WTtqcx853iRv9Gfd-zKKmlU2wStnOGnIfnHkrNbl5y8vTMNBKNuqLh3Y_el' +
23
+ 'PVSUIWGcy3KByw7VRnBTAze2bsmI0Dvz-89Ar1C2g0Ui6DOYyEa0iiXer4gSQgJ5ddsbIAMJMBT5j96G' +
24
+ '1mhbjM2mqekORRyjCZHGeNbofnTvKcJRTStsBPXQ2WEkAf6J1eNZ2-QnNYMVVO44-KXfhQsfaqRoporj' +
25
+ '4LvTkNX0kkxyfC3V1R8Qrk-_pHhzPtKtQxiRj2axTVXFoj5I1Po7WgQz2_vBZnWZ-0AIzHXN6F_fmMhy' +
26
+ 'PBPk3pbuN7cHBe2cKh_nHQ',
27
+ e: 'AQAB',
28
+ kid: 'Q0ZCQzEwRTFCOUE3QjI0MUZEREQ0N0I4MTI3OTVFRDkyNTIxQjQ3MA'
29
+ },
30
+ {
31
+ crv: 'P-256',
32
+ kty: 'EC',
33
+ x: 'ruky13qVa2GM9jnWsBYP_OTsk6fyV_HWC2AjvUkyCv8',
34
+ y: 'kIAW58dw6pjO1dy4czpNdsaL8DUc3RKo6Hmses5O_Bc',
35
+ kid: '3d-GYUhTwkAfCi9JdvMieQ',
36
+ alg: 'EC256',
37
+ use: 'sig'
38
+ }
39
+ ]
40
+ }
41
+ };
42
+
43
+ const TEST_PEMS = TEST_JWKS.data.keys.map((key) =>
44
+ createPublicKey({ key, format: 'jwk' }).export({
45
+ format: 'pem',
46
+ type: 'spki'
47
+ })
48
+ );
49
+
50
+ describe('Entity - KeySet', function () {
51
+ let url: string;
52
+ let requestStub: SinonStub;
53
+ let tlsRequestStub: SinonStub;
54
+
55
+ beforeEach(() => {
56
+ url = faker.internet.url();
57
+
58
+ requestStub = stub(request, 'request').resolves(
59
+ TEST_JWKS as unknown as AxiosResponse<JWKS>
60
+ );
61
+ tlsRequestStub = stub(tlsRequest, 'tlsRequest').resolves(
62
+ TEST_JWKS as unknown as AxiosResponse<JWKS>
63
+ );
64
+ });
65
+
66
+ it('should create a key set when fetching', async () => {
67
+ const keySet = new KeySet(url);
68
+ await keySet.init();
69
+
70
+ const keys = keySet.getKeys();
71
+ expect(Object.values(keys)).to.have.length(2);
72
+ Object.values(keys).forEach((key) => {
73
+ expect(TEST_PEMS).to.include(key);
74
+ });
75
+ });
76
+
77
+ it('should make a regular request by default', async () => {
78
+ const keySet = new KeySet(url);
79
+
80
+ await keySet.init();
81
+
82
+ expect(requestStub).to.have.been.calledOnceWithExactly({
83
+ url,
84
+ method: 'get'
85
+ });
86
+ expect(tlsRequestStub).to.not.have.been.called;
87
+ });
88
+
89
+ it('should make a TLS request for internal keysets', async () => {
90
+ const keySet = new KeySet(url, { internal: true });
91
+
92
+ await keySet.init();
93
+
94
+ expect(tlsRequestStub).to.have.been.calledOnceWithExactly({
95
+ url,
96
+ method: 'get'
97
+ });
98
+ expect(requestStub).to.not.have.been.called;
99
+ });
100
+
101
+ it('should read a key from a PEM string', async () => {
102
+ const pem = await readFile(
103
+ process.env.ADMIN_API_ECDSA_PUBLIC_KEY as string,
104
+ 'utf-8'
105
+ );
106
+
107
+ const keySet = new KeySet(pem, { pem: true });
108
+
109
+ await keySet.init();
110
+
111
+ expect(tlsRequestStub).to.not.have.been.called;
112
+ expect(requestStub).to.not.have.been.called;
113
+ expect(Object.keys(keySet.getKeys())).to.have.length(1);
114
+ for (const key of Object.values(keySet.getKeys())) {
115
+ expect(key).to.equal(pem);
116
+ }
117
+ });
118
+
119
+ it('should not fail if the init did not complete and a key is asked', () => {
120
+ const keySet = new KeySet(faker.internet.url());
121
+
122
+ const result = keySet.getKey(randomUUID());
123
+
124
+ expect(result).to.be.undefined;
125
+ });
126
+ });
@@ -1,172 +1,172 @@
1
- import { createPublicKey, createHash } from 'crypto';
2
- import { readFileSync } from 'fs';
3
- import { Method } from 'axios';
4
- import { KeySetOptions, KeySetValues, JWKS } from './KeySet.types';
5
- import { LogSeverity } from 'const';
6
- import { EngineError } from 'entities/EngineError';
7
- import { reportDebug, reportError } from 'utils/report';
8
- import { request } from 'utils/request';
9
- import { tlsRequest } from 'utils/tlsRequest';
10
-
11
- const namespace = 'engine:keySet';
12
-
13
- // Number of seconds between each key refresh
14
- const KEY_REFRESH_INTERVAL = 300;
15
-
16
- /**
17
- * Fetch Json Web Key Sets and cache them
18
- * Keys can then be used for Json Web Token authentication
19
- */
20
- export class KeySet {
21
- /** Latest known value for the keys in the set, indexed by the key id */
22
- private keySet: KeySetValues = {};
23
- /** URL at which the key set can be fetched */
24
- private url: string;
25
- /** This resource is located on a service inside of our private cluster */
26
- private internal: boolean;
27
- /** This URL is actually a path to a local key file encoded in PEM */
28
- private file: boolean;
29
- /** This input is actually a full PEM string representation of a key */
30
- private pem: boolean;
31
- /** Timer for the key fetching interval */
32
- private interval?: NodeJS.Timeout | string | number | undefined;
33
-
34
- /** Create a new Key Set */
35
- public constructor(url: string, options: KeySetOptions = {}) {
36
- this.url = url;
37
- this.internal = options.internal ?? false;
38
- this.file = options.file ?? false;
39
- this.pem = options.pem ?? false;
40
- }
41
-
42
- /** Calculate key ID from PEM string */
43
- private static calculateKeyId(pem: string): string {
44
- // We use the md5 hash of the PEM file to defined the key ID
45
- const hash = createHash('md5');
46
- hash.update(pem.trim());
47
- const kid = hash.digest('base64url');
48
- reportDebug({
49
- namespace,
50
- message: `Calculated Key ID: "${kid}"`,
51
- data: { key: pem }
52
- });
53
- return kid;
54
- }
55
-
56
- /** Initialize a KeySet, should be run on server startup to avoid any misconfiguration */
57
- public async init(): Promise<void> {
58
- await this.fetch();
59
- this.interval = setInterval(() => {
60
- (async (): Promise<void> => {
61
- try {
62
- await this.fetch();
63
- } catch (error) {
64
- reportError(error);
65
- }
66
- })().catch((error) => {
67
- reportError(error);
68
- });
69
- }, KEY_REFRESH_INTERVAL * 1000);
70
- }
71
-
72
- /** Clear any pending timers to avoid pending process */
73
- public shutdown(): void {
74
- if (this.interval) clearInterval(this.interval);
75
- }
76
-
77
- /** Get the PEM encoded version of a key by its id */
78
- public getKey(keyId: string): string | undefined {
79
- return this.keySet[keyId];
80
- }
81
-
82
- /** Get all the keys in the set mapped by their ID */
83
- public getKeys(): KeySetValues {
84
- return this.keySet;
85
- }
86
-
87
- /** Fetch the latest version of the key set */
88
- private async fetch(): Promise<void> {
89
- reportDebug({
90
- namespace,
91
- message: `Fetching JWKS`,
92
- data: { url: this.url }
93
- });
94
-
95
- if (this.pem) {
96
- // Read the key from the parameter directly
97
- reportDebug({
98
- namespace,
99
- message: 'Processing key from given PEM string'
100
- });
101
-
102
- const kid = KeySet.calculateKeyId(this.url);
103
-
104
- this.keySet = { [kid]: this.url };
105
- } else if (this.file) {
106
- // Read the key from a file
107
- reportDebug({
108
- namespace,
109
- message: `Reading key on disk at path "${this.url}"`
110
- });
111
- const set = JSON.parse(readFileSync(this.url, 'utf-8'));
112
-
113
- // Check that the returned data has the shape of a JWKS
114
- if (!(set.keys && set.keys instanceof Array))
115
- throw new EngineError({
116
- severity: LogSeverity.ERROR,
117
- message: 'Fetched key set is not in an appropriate format',
118
- data: { url: this.url, set }
119
- });
120
-
121
- // Create a node.crypto public key object for each key in the set
122
- this.keySet = set.keys.reduce(
123
- (set: { [x: string]: string; }, key: { kid: string | number; }) => {
124
- set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
125
- format: 'pem',
126
- type: 'spki'
127
- }) as string;
128
- return set;
129
- },
130
- {} as Record<string, string>
131
- );
132
- } else {
133
- // Fetch key by making a network request
134
- reportDebug({
135
- namespace,
136
- message: `Making network request to "${this.url}"`
137
- });
138
-
139
- const requestOptions = { url: this.url, method: 'get' as Method };
140
- // For services inside of our cluster we use the TLS authenticated request method
141
- const { data: set } = await (this.internal
142
- ? tlsRequest<JWKS>(requestOptions)
143
- : request<JWKS>(requestOptions));
144
-
145
- // Check that the returned data has the shape of a JWKS
146
- if (!(set.keys && set.keys instanceof Array))
147
- throw new EngineError({
148
- severity: LogSeverity.ERROR,
149
- message: 'Fetched key set is not in an appropriate format',
150
- data: { url: this.url, set }
151
- });
152
-
153
- // Create a node.crypto public key object for each key in the set
154
- this.keySet = set.keys.reduce(
155
- (set, key) => {
156
- set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
157
- format: 'pem',
158
- type: 'spki'
159
- }) as string;
160
- return set;
161
- },
162
- {} as Record<string, string>
163
- );
164
- }
165
-
166
- reportDebug({
167
- namespace,
168
- message: `Stored ${Object.keys(this.keySet).length} keys`,
169
- data: { keyIds: Object.keys(this.keySet) }
170
- });
171
- }
172
- }
1
+ import { createPublicKey, createHash } from 'crypto';
2
+ import { readFileSync } from 'fs';
3
+ import { Method } from 'axios';
4
+ import { KeySetOptions, KeySetValues, JWKS } from './KeySet.types';
5
+ import { LogSeverity } from 'const';
6
+ import { EngineError } from 'entities/EngineError';
7
+ import { reportDebug, reportError } from 'utils/report';
8
+ import { request } from 'utils/request';
9
+ import { tlsRequest } from 'utils/tlsRequest';
10
+
11
+ const namespace = 'engine:keySet';
12
+
13
+ // Number of seconds between each key refresh
14
+ const KEY_REFRESH_INTERVAL = 300;
15
+
16
+ /**
17
+ * Fetch Json Web Key Sets and cache them
18
+ * Keys can then be used for Json Web Token authentication
19
+ */
20
+ export class KeySet {
21
+ /** Latest known value for the keys in the set, indexed by the key id */
22
+ private keySet: KeySetValues = {};
23
+ /** URL at which the key set can be fetched */
24
+ private url: string;
25
+ /** This resource is located on a service inside of our private cluster */
26
+ private internal: boolean;
27
+ /** This URL is actually a path to a local key file encoded in PEM */
28
+ private file: boolean;
29
+ /** This input is actually a full PEM string representation of a key */
30
+ private pem: boolean;
31
+ /** Timer for the key fetching interval */
32
+ private interval?: NodeJS.Timeout | string | number | undefined;
33
+
34
+ /** Create a new Key Set */
35
+ public constructor(url: string, options: KeySetOptions = {}) {
36
+ this.url = url;
37
+ this.internal = options.internal ?? false;
38
+ this.file = options.file ?? false;
39
+ this.pem = options.pem ?? false;
40
+ }
41
+
42
+ /** Calculate key ID from PEM string */
43
+ private static calculateKeyId(pem: string): string {
44
+ // We use the md5 hash of the PEM file to defined the key ID
45
+ const hash = createHash('md5');
46
+ hash.update(pem.trim());
47
+ const kid = hash.digest('base64url');
48
+ reportDebug({
49
+ namespace,
50
+ message: `Calculated Key ID: "${kid}"`,
51
+ data: { key: pem }
52
+ });
53
+ return kid;
54
+ }
55
+
56
+ /** Initialize a KeySet, should be run on server startup to avoid any misconfiguration */
57
+ public async init(): Promise<void> {
58
+ await this.fetch();
59
+ this.interval = setInterval(() => {
60
+ (async (): Promise<void> => {
61
+ try {
62
+ await this.fetch();
63
+ } catch (error) {
64
+ reportError(error);
65
+ }
66
+ })().catch((error) => {
67
+ reportError(error);
68
+ });
69
+ }, KEY_REFRESH_INTERVAL * 1000);
70
+ }
71
+
72
+ /** Clear any pending timers to avoid pending process */
73
+ public shutdown(): void {
74
+ if (this.interval) clearInterval(this.interval);
75
+ }
76
+
77
+ /** Get the PEM encoded version of a key by its id */
78
+ public getKey(keyId: string): string | undefined {
79
+ return this.keySet[keyId];
80
+ }
81
+
82
+ /** Get all the keys in the set mapped by their ID */
83
+ public getKeys(): KeySetValues {
84
+ return this.keySet;
85
+ }
86
+
87
+ /** Fetch the latest version of the key set */
88
+ private async fetch(): Promise<void> {
89
+ reportDebug({
90
+ namespace,
91
+ message: `Fetching JWKS`,
92
+ data: { url: this.url }
93
+ });
94
+
95
+ if (this.pem) {
96
+ // Read the key from the parameter directly
97
+ reportDebug({
98
+ namespace,
99
+ message: 'Processing key from given PEM string'
100
+ });
101
+
102
+ const kid = KeySet.calculateKeyId(this.url);
103
+
104
+ this.keySet = { [kid]: this.url };
105
+ } else if (this.file) {
106
+ // Read the key from a file
107
+ reportDebug({
108
+ namespace,
109
+ message: `Reading key on disk at path "${this.url}"`
110
+ });
111
+ const set = JSON.parse(readFileSync(this.url, 'utf-8'));
112
+
113
+ // Check that the returned data has the shape of a JWKS
114
+ if (!(set.keys && set.keys instanceof Array))
115
+ throw new EngineError({
116
+ severity: LogSeverity.ERROR,
117
+ message: 'Fetched key set is not in an appropriate format',
118
+ data: { url: this.url, set }
119
+ });
120
+
121
+ // Create a node.crypto public key object for each key in the set
122
+ this.keySet = set.keys.reduce(
123
+ (set: { [x: string]: string; }, key: { kid: string | number; }) => {
124
+ set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
125
+ format: 'pem',
126
+ type: 'spki'
127
+ }) as string;
128
+ return set;
129
+ },
130
+ {} as Record<string, string>
131
+ );
132
+ } else {
133
+ // Fetch key by making a network request
134
+ reportDebug({
135
+ namespace,
136
+ message: `Making network request to "${this.url}"`
137
+ });
138
+
139
+ const requestOptions = { url: this.url, method: 'get' as Method };
140
+ // For services inside of our cluster we use the TLS authenticated request method
141
+ const { data: set } = await (this.internal
142
+ ? tlsRequest<JWKS>(requestOptions)
143
+ : request<JWKS>(requestOptions));
144
+
145
+ // Check that the returned data has the shape of a JWKS
146
+ if (!(set.keys && set.keys instanceof Array))
147
+ throw new EngineError({
148
+ severity: LogSeverity.ERROR,
149
+ message: 'Fetched key set is not in an appropriate format',
150
+ data: { url: this.url, set }
151
+ });
152
+
153
+ // Create a node.crypto public key object for each key in the set
154
+ this.keySet = set.keys.reduce(
155
+ (set, key) => {
156
+ set[key.kid] = createPublicKey({ key, format: 'jwk' }).export({
157
+ format: 'pem',
158
+ type: 'spki'
159
+ }) as string;
160
+ return set;
161
+ },
162
+ {} as Record<string, string>
163
+ );
164
+ }
165
+
166
+ reportDebug({
167
+ namespace,
168
+ message: `Stored ${Object.keys(this.keySet).length} keys`,
169
+ data: { keyIds: Object.keys(this.keySet) }
170
+ });
171
+ }
172
+ }
@@ -1,28 +1,28 @@
1
- import { JsonWebKey } from 'crypto';
2
-
3
- /** KeySet initialization options */
4
- export interface KeySetOptions {
5
- /** This resource is located on a service inside of our private cluster */
6
- internal?: boolean;
7
- /** This URL is actually a path to a local key file encoded in PEM */
8
- file?: boolean;
9
- /** This input is actually a full PEM string representation of a key */
10
- pem?: boolean;
11
- }
12
-
13
- /** Keep a mapping ok keyId => PEM */
14
- export interface KeySetValues {
15
- [id: string]: string;
16
- }
17
-
18
- /** Object holding JWK keys */
19
- export interface JWKS {
20
- /** Key set is JWKS format */
21
- keys: Array<JWK>;
22
- }
23
-
24
- /** JWK key with custom claims */
25
- interface JWK extends JsonWebKey {
26
- /** ID of the key */
27
- kid: string;
28
- }
1
+ import { JsonWebKey } from 'crypto';
2
+
3
+ /** KeySet initialization options */
4
+ export interface KeySetOptions {
5
+ /** This resource is located on a service inside of our private cluster */
6
+ internal?: boolean;
7
+ /** This URL is actually a path to a local key file encoded in PEM */
8
+ file?: boolean;
9
+ /** This input is actually a full PEM string representation of a key */
10
+ pem?: boolean;
11
+ }
12
+
13
+ /** Keep a mapping ok keyId => PEM */
14
+ export interface KeySetValues {
15
+ [id: string]: string;
16
+ }
17
+
18
+ /** Object holding JWK keys */
19
+ export interface JWKS {
20
+ /** Key set is JWKS format */
21
+ keys: Array<JWK>;
22
+ }
23
+
24
+ /** JWK key with custom claims */
25
+ interface JWK extends JsonWebKey {
26
+ /** ID of the key */
27
+ kid: string;
28
+ }
@@ -1,2 +1,2 @@
1
- export * from './KeySet';
2
- export * from './KeySet.types';
1
+ export * from './KeySet';
2
+ export * from './KeySet.types';