@intlayer/backend 5.5.11 → 5.7.0

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 (513) hide show
  1. package/README.md +3 -0
  2. package/dist/cjs/controllers/ai.controller.cjs +10 -7
  3. package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
  4. package/dist/cjs/controllers/dictionary.controller.cjs +50 -58
  5. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  6. package/dist/cjs/controllers/eventListener.controller.cjs +2 -18
  7. package/dist/cjs/controllers/eventListener.controller.cjs.map +1 -1
  8. package/dist/cjs/controllers/newsletter.controller.cjs +38 -3
  9. package/dist/cjs/controllers/newsletter.controller.cjs.map +1 -1
  10. package/dist/cjs/controllers/oAuth2.controller.cjs +3 -3
  11. package/dist/cjs/controllers/oAuth2.controller.cjs.map +1 -1
  12. package/dist/cjs/controllers/organization.controller.cjs +92 -106
  13. package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
  14. package/dist/cjs/controllers/project.controller.cjs +81 -83
  15. package/dist/cjs/controllers/project.controller.cjs.map +1 -1
  16. package/dist/cjs/controllers/projectAccessKey.controller.cjs +30 -24
  17. package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
  18. package/dist/cjs/controllers/search.controller.cjs.map +1 -1
  19. package/dist/cjs/controllers/stripe.controller.cjs +4 -25
  20. package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
  21. package/dist/cjs/controllers/tag.controller.cjs +27 -16
  22. package/dist/cjs/controllers/tag.controller.cjs.map +1 -1
  23. package/dist/cjs/controllers/user.controller.cjs +88 -24
  24. package/dist/cjs/controllers/user.controller.cjs.map +1 -1
  25. package/dist/cjs/emails/InviteUserEmail.cjs +30 -12
  26. package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
  27. package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs +266 -0
  28. package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs.map +1 -0
  29. package/dist/cjs/emails/ResetUserPassword.cjs +27 -15
  30. package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
  31. package/dist/cjs/emails/ValidateUserEmail.cjs +27 -36
  32. package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
  33. package/dist/cjs/emails/Welcome.cjs +27 -15
  34. package/dist/cjs/emails/Welcome.cjs.map +1 -1
  35. package/dist/cjs/emails/index.cjs +7 -5
  36. package/dist/cjs/emails/index.cjs.map +1 -1
  37. package/dist/cjs/export.cjs +2 -5
  38. package/dist/cjs/export.cjs.map +1 -1
  39. package/dist/cjs/index.cjs +61 -111
  40. package/dist/cjs/index.cjs.map +1 -1
  41. package/dist/cjs/middlewares/oAuth2.middleware.cjs +26 -38
  42. package/dist/cjs/middlewares/oAuth2.middleware.cjs.map +1 -1
  43. package/dist/cjs/middlewares/request.middleware.cjs.map +1 -1
  44. package/dist/cjs/middlewares/sessionAuth.middleware.cjs +17 -138
  45. package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
  46. package/dist/cjs/models/dictionary.model.cjs.map +1 -1
  47. package/dist/cjs/models/discussion.model.cjs.map +1 -1
  48. package/dist/cjs/models/oAuth2.model.cjs +4 -1
  49. package/dist/cjs/models/oAuth2.model.cjs.map +1 -1
  50. package/dist/cjs/models/organization.model.cjs +1 -4
  51. package/dist/cjs/models/organization.model.cjs.map +1 -1
  52. package/dist/cjs/models/project.model.cjs +4 -1
  53. package/dist/cjs/models/project.model.cjs.map +1 -1
  54. package/dist/cjs/models/session.model.cjs +34 -0
  55. package/dist/cjs/models/session.model.cjs.map +1 -0
  56. package/dist/cjs/models/tag.model.cjs.map +1 -1
  57. package/dist/cjs/models/user.model.cjs.map +1 -1
  58. package/dist/cjs/routes/ai.routes.cjs +3 -1
  59. package/dist/cjs/routes/ai.routes.cjs.map +1 -1
  60. package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
  61. package/dist/cjs/routes/eventListener.routes.cjs +1 -1
  62. package/dist/cjs/routes/eventListener.routes.cjs.map +1 -1
  63. package/dist/cjs/routes/newsletter.routes.cjs.map +1 -1
  64. package/dist/cjs/routes/organization.routes.cjs +8 -8
  65. package/dist/cjs/routes/organization.routes.cjs.map +1 -1
  66. package/dist/cjs/routes/project.routes.cjs +23 -14
  67. package/dist/cjs/routes/project.routes.cjs.map +1 -1
  68. package/dist/cjs/routes/search.routes.cjs.map +1 -1
  69. package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
  70. package/dist/cjs/routes/tags.routes.cjs +4 -4
  71. package/dist/cjs/routes/tags.routes.cjs.map +1 -1
  72. package/dist/cjs/routes/user.routes.cjs +12 -12
  73. package/dist/cjs/routes/user.routes.cjs.map +1 -1
  74. package/dist/cjs/schemas/dictionary.schema.cjs +18 -1
  75. package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
  76. package/dist/cjs/schemas/discussion.schema.cjs +18 -1
  77. package/dist/cjs/schemas/discussion.schema.cjs.map +1 -1
  78. package/dist/cjs/schemas/oAuth2.schema.cjs +18 -1
  79. package/dist/cjs/schemas/oAuth2.schema.cjs.map +1 -1
  80. package/dist/cjs/schemas/organization.schema.cjs +21 -1
  81. package/dist/cjs/schemas/organization.schema.cjs.map +1 -1
  82. package/dist/cjs/schemas/plans.schema.cjs +18 -1
  83. package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
  84. package/dist/cjs/schemas/project.schema.cjs +19 -14
  85. package/dist/cjs/schemas/project.schema.cjs.map +1 -1
  86. package/dist/cjs/schemas/session.schema.cjs +63 -0
  87. package/dist/cjs/schemas/session.schema.cjs.map +1 -0
  88. package/dist/cjs/schemas/tag.schema.cjs +18 -1
  89. package/dist/cjs/schemas/tag.schema.cjs.map +1 -1
  90. package/dist/cjs/schemas/user.schema.cjs +18 -48
  91. package/dist/cjs/schemas/user.schema.cjs.map +1 -1
  92. package/dist/cjs/services/dictionary.service.cjs +6 -5
  93. package/dist/cjs/services/dictionary.service.cjs.map +1 -1
  94. package/dist/cjs/services/email.service.cjs +13 -0
  95. package/dist/cjs/services/email.service.cjs.map +1 -1
  96. package/dist/cjs/services/oAuth2.service.cjs +49 -10
  97. package/dist/cjs/services/oAuth2.service.cjs.map +1 -1
  98. package/dist/cjs/services/organization.service.cjs +16 -15
  99. package/dist/cjs/services/organization.service.cjs.map +1 -1
  100. package/dist/cjs/services/project.service.cjs +1 -1
  101. package/dist/cjs/services/project.service.cjs.map +1 -1
  102. package/dist/cjs/services/projectAccessKey.service.cjs +17 -33
  103. package/dist/cjs/services/projectAccessKey.service.cjs.map +1 -1
  104. package/dist/cjs/services/subscription.service.cjs +10 -10
  105. package/dist/cjs/services/subscription.service.cjs.map +1 -1
  106. package/dist/cjs/services/tag.service.cjs.map +1 -1
  107. package/dist/cjs/services/user.service.cjs +2 -42
  108. package/dist/cjs/services/user.service.cjs.map +1 -1
  109. package/dist/cjs/types/dictionary.types.cjs.map +1 -1
  110. package/dist/cjs/types/discussion.types.cjs.map +1 -1
  111. package/dist/cjs/types/oAuth2.types.cjs.map +1 -1
  112. package/dist/cjs/types/organization.types.cjs.map +1 -1
  113. package/dist/cjs/types/plan.types.cjs.map +1 -1
  114. package/dist/cjs/types/project.types.cjs.map +1 -1
  115. package/dist/cjs/types/session.types.cjs.map +1 -1
  116. package/dist/cjs/types/tag.types.cjs.map +1 -1
  117. package/dist/cjs/types/user.types.cjs.map +1 -1
  118. package/dist/cjs/utils/AI/aiSdk.cjs.map +1 -1
  119. package/dist/cjs/utils/AI/askDocQuestion/PROMPT.md +7 -1
  120. package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs +32 -14
  121. package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs.map +1 -1
  122. package/dist/cjs/utils/AI/askDocQuestion/embeddings.json +88086 -76800
  123. package/dist/cjs/utils/AI/autocomplete/PROMPT.md +18 -2
  124. package/dist/cjs/utils/AI/autocomplete/index.cjs +8 -5
  125. package/dist/cjs/utils/AI/autocomplete/index.cjs.map +1 -1
  126. package/dist/cjs/utils/access.cjs +2 -0
  127. package/dist/cjs/utils/access.cjs.map +1 -0
  128. package/dist/cjs/utils/accessControl.cjs +7 -0
  129. package/dist/cjs/utils/accessControl.cjs.map +1 -1
  130. package/dist/cjs/utils/auth/getAuth.cjs +248 -0
  131. package/dist/cjs/utils/auth/getAuth.cjs.map +1 -0
  132. package/dist/cjs/utils/cors.cjs +55 -0
  133. package/dist/cjs/utils/cors.cjs.map +1 -0
  134. package/dist/cjs/utils/ensureMongoDocumentToObject.cjs.map +1 -1
  135. package/dist/cjs/utils/errors/ErrorHandler.cjs +2 -2
  136. package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
  137. package/dist/cjs/utils/errors/errorCodes.cjs +114 -153
  138. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  139. package/dist/cjs/utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs.map +1 -1
  140. package/dist/cjs/utils/filtersAndPagination/getProjectFiltersAndPagination.cjs.map +1 -1
  141. package/dist/cjs/utils/filtersAndPagination/getTagFiltersAndPagination.cjs.map +1 -1
  142. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs +1 -1
  143. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs.map +1 -1
  144. package/dist/cjs/utils/mapper/dictionary.cjs.map +1 -1
  145. package/dist/cjs/utils/mapper/organization.cjs +10 -8
  146. package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
  147. package/dist/cjs/utils/mapper/project.cjs +5 -18
  148. package/dist/cjs/utils/mapper/project.cjs.map +1 -1
  149. package/dist/cjs/utils/mapper/tag.cjs +4 -2
  150. package/dist/cjs/utils/mapper/tag.cjs.map +1 -1
  151. package/dist/cjs/utils/mapper/user.cjs +6 -3
  152. package/dist/cjs/utils/mapper/user.cjs.map +1 -1
  153. package/dist/cjs/utils/mergeFunctionTypes.cjs +17 -0
  154. package/dist/cjs/utils/mergeFunctionTypes.cjs.map +1 -0
  155. package/dist/cjs/utils/mongoDB/connectDB.cjs +3 -1
  156. package/dist/cjs/utils/mongoDB/connectDB.cjs.map +1 -1
  157. package/dist/cjs/utils/mongoDB/types.cjs +17 -0
  158. package/dist/cjs/utils/mongoDB/types.cjs.map +1 -0
  159. package/dist/cjs/utils/oAuth2.cjs.map +1 -1
  160. package/dist/cjs/utils/permissions.cjs +166 -0
  161. package/dist/cjs/utils/permissions.cjs.map +1 -0
  162. package/dist/cjs/utils/rateLimiter.cjs +88 -0
  163. package/dist/cjs/utils/rateLimiter.cjs.map +1 -0
  164. package/dist/esm/controllers/ai.controller.mjs +10 -7
  165. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  166. package/dist/esm/controllers/dictionary.controller.mjs +50 -58
  167. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  168. package/dist/esm/controllers/eventListener.controller.mjs +2 -8
  169. package/dist/esm/controllers/eventListener.controller.mjs.map +1 -1
  170. package/dist/esm/controllers/newsletter.controller.mjs +38 -3
  171. package/dist/esm/controllers/newsletter.controller.mjs.map +1 -1
  172. package/dist/esm/controllers/oAuth2.controller.mjs +2 -2
  173. package/dist/esm/controllers/oAuth2.controller.mjs.map +1 -1
  174. package/dist/esm/controllers/organization.controller.mjs +95 -106
  175. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  176. package/dist/esm/controllers/project.controller.mjs +81 -83
  177. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  178. package/dist/esm/controllers/projectAccessKey.controller.mjs +30 -24
  179. package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
  180. package/dist/esm/controllers/search.controller.mjs.map +1 -1
  181. package/dist/esm/controllers/stripe.controller.mjs +4 -25
  182. package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
  183. package/dist/esm/controllers/tag.controller.mjs +27 -16
  184. package/dist/esm/controllers/tag.controller.mjs.map +1 -1
  185. package/dist/esm/controllers/user.controller.mjs +85 -22
  186. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  187. package/dist/esm/emails/InviteUserEmail.mjs +32 -14
  188. package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
  189. package/dist/esm/emails/OAuthTokenCreatedEmail.mjs +254 -0
  190. package/dist/esm/emails/OAuthTokenCreatedEmail.mjs.map +1 -0
  191. package/dist/esm/emails/ResetUserPassword.mjs +29 -17
  192. package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
  193. package/dist/esm/emails/ValidateUserEmail.mjs +29 -38
  194. package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
  195. package/dist/esm/emails/Welcome.mjs +29 -17
  196. package/dist/esm/emails/Welcome.mjs.map +1 -1
  197. package/dist/esm/emails/index.mjs +3 -2
  198. package/dist/esm/emails/index.mjs.map +1 -1
  199. package/dist/esm/export.mjs +1 -3
  200. package/dist/esm/export.mjs.map +1 -1
  201. package/dist/esm/index.mjs +60 -111
  202. package/dist/esm/index.mjs.map +1 -1
  203. package/dist/esm/middlewares/oAuth2.middleware.mjs +27 -36
  204. package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
  205. package/dist/esm/middlewares/request.middleware.mjs.map +1 -1
  206. package/dist/esm/middlewares/sessionAuth.middleware.mjs +16 -127
  207. package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
  208. package/dist/esm/models/dictionary.model.mjs.map +1 -1
  209. package/dist/esm/models/discussion.model.mjs.map +1 -1
  210. package/dist/esm/models/oAuth2.model.mjs +4 -1
  211. package/dist/esm/models/oAuth2.model.mjs.map +1 -1
  212. package/dist/esm/models/organization.model.mjs +1 -4
  213. package/dist/esm/models/organization.model.mjs.map +1 -1
  214. package/dist/esm/models/project.model.mjs +4 -1
  215. package/dist/esm/models/project.model.mjs.map +1 -1
  216. package/dist/esm/models/session.model.mjs +10 -0
  217. package/dist/esm/models/session.model.mjs.map +1 -0
  218. package/dist/esm/models/tag.model.mjs.map +1 -1
  219. package/dist/esm/models/user.model.mjs.map +1 -1
  220. package/dist/esm/routes/ai.routes.mjs +3 -1
  221. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  222. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  223. package/dist/esm/routes/eventListener.routes.mjs +1 -1
  224. package/dist/esm/routes/eventListener.routes.mjs.map +1 -1
  225. package/dist/esm/routes/newsletter.routes.mjs.map +1 -1
  226. package/dist/esm/routes/organization.routes.mjs +8 -8
  227. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  228. package/dist/esm/routes/project.routes.mjs +23 -14
  229. package/dist/esm/routes/project.routes.mjs.map +1 -1
  230. package/dist/esm/routes/search.routes.mjs.map +1 -1
  231. package/dist/esm/routes/stripe.routes.mjs.map +1 -1
  232. package/dist/esm/routes/tags.routes.mjs +4 -4
  233. package/dist/esm/routes/tags.routes.mjs.map +1 -1
  234. package/dist/esm/routes/user.routes.mjs +14 -14
  235. package/dist/esm/routes/user.routes.mjs.map +1 -1
  236. package/dist/esm/schemas/dictionary.schema.mjs +18 -1
  237. package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
  238. package/dist/esm/schemas/discussion.schema.mjs +18 -1
  239. package/dist/esm/schemas/discussion.schema.mjs.map +1 -1
  240. package/dist/esm/schemas/oAuth2.schema.mjs +18 -1
  241. package/dist/esm/schemas/oAuth2.schema.mjs.map +1 -1
  242. package/dist/esm/schemas/organization.schema.mjs +21 -1
  243. package/dist/esm/schemas/organization.schema.mjs.map +1 -1
  244. package/dist/esm/schemas/plans.schema.mjs +18 -1
  245. package/dist/esm/schemas/plans.schema.mjs.map +1 -1
  246. package/dist/esm/schemas/project.schema.mjs +21 -15
  247. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  248. package/dist/esm/schemas/session.schema.mjs +39 -0
  249. package/dist/esm/schemas/session.schema.mjs.map +1 -0
  250. package/dist/esm/schemas/tag.schema.mjs +21 -4
  251. package/dist/esm/schemas/tag.schema.mjs.map +1 -1
  252. package/dist/esm/schemas/user.schema.mjs +18 -48
  253. package/dist/esm/schemas/user.schema.mjs.map +1 -1
  254. package/dist/esm/services/dictionary.service.mjs +6 -5
  255. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  256. package/dist/esm/services/email.service.mjs +33 -16
  257. package/dist/esm/services/email.service.mjs.map +1 -1
  258. package/dist/esm/services/oAuth2.service.mjs +47 -10
  259. package/dist/esm/services/oAuth2.service.mjs.map +1 -1
  260. package/dist/esm/services/organization.service.mjs +16 -14
  261. package/dist/esm/services/organization.service.mjs.map +1 -1
  262. package/dist/esm/services/project.service.mjs +1 -1
  263. package/dist/esm/services/project.service.mjs.map +1 -1
  264. package/dist/esm/services/projectAccessKey.service.mjs +15 -31
  265. package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
  266. package/dist/esm/services/subscription.service.mjs +10 -10
  267. package/dist/esm/services/subscription.service.mjs.map +1 -1
  268. package/dist/esm/services/tag.service.mjs.map +1 -1
  269. package/dist/esm/services/user.service.mjs +2 -40
  270. package/dist/esm/services/user.service.mjs.map +1 -1
  271. package/dist/esm/types/user.types.mjs.map +1 -1
  272. package/dist/esm/utils/AI/aiSdk.mjs.map +1 -1
  273. package/dist/esm/utils/AI/askDocQuestion/PROMPT.md +7 -1
  274. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs +32 -14
  275. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -1
  276. package/dist/esm/utils/AI/askDocQuestion/embeddings.json +88086 -76800
  277. package/dist/esm/utils/AI/autocomplete/PROMPT.md +18 -2
  278. package/dist/esm/utils/AI/autocomplete/index.mjs +8 -5
  279. package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -1
  280. package/dist/esm/utils/access.mjs +1 -0
  281. package/dist/esm/utils/access.mjs.map +1 -0
  282. package/dist/esm/utils/accessControl.mjs +7 -0
  283. package/dist/esm/utils/accessControl.mjs.map +1 -1
  284. package/dist/esm/utils/auth/getAuth.mjs +227 -0
  285. package/dist/esm/utils/auth/getAuth.mjs.map +1 -0
  286. package/dist/esm/utils/cors.mjs +31 -0
  287. package/dist/esm/utils/cors.mjs.map +1 -0
  288. package/dist/esm/utils/ensureMongoDocumentToObject.mjs.map +1 -1
  289. package/dist/esm/utils/errors/ErrorHandler.mjs +2 -2
  290. package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
  291. package/dist/esm/utils/errors/errorCodes.mjs +114 -153
  292. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  293. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
  294. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
  295. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -1
  296. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs +1 -1
  297. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
  298. package/dist/esm/utils/mapper/dictionary.mjs.map +1 -1
  299. package/dist/esm/utils/mapper/organization.mjs +8 -7
  300. package/dist/esm/utils/mapper/organization.mjs.map +1 -1
  301. package/dist/esm/utils/mapper/project.mjs +5 -18
  302. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  303. package/dist/esm/utils/mapper/tag.mjs +4 -2
  304. package/dist/esm/utils/mapper/tag.mjs.map +1 -1
  305. package/dist/esm/utils/mapper/user.mjs +6 -3
  306. package/dist/esm/utils/mapper/user.mjs.map +1 -1
  307. package/dist/esm/utils/mergeFunctionTypes.mjs +1 -0
  308. package/dist/esm/utils/mergeFunctionTypes.mjs.map +1 -0
  309. package/dist/esm/utils/mongoDB/connectDB.mjs +3 -1
  310. package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
  311. package/dist/esm/utils/mongoDB/types.mjs +1 -0
  312. package/dist/esm/utils/mongoDB/types.mjs.map +1 -0
  313. package/dist/esm/utils/oAuth2.mjs +3 -3
  314. package/dist/esm/utils/oAuth2.mjs.map +1 -1
  315. package/dist/esm/utils/permissions.mjs +138 -0
  316. package/dist/esm/utils/permissions.mjs.map +1 -0
  317. package/dist/esm/utils/rateLimiter.mjs +53 -0
  318. package/dist/esm/utils/rateLimiter.mjs.map +1 -0
  319. package/dist/types/controllers/ai.controller.d.ts +12 -10
  320. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  321. package/dist/types/controllers/dictionary.controller.d.ts +8 -9
  322. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  323. package/dist/types/controllers/eventListener.controller.d.ts +2 -3
  324. package/dist/types/controllers/eventListener.controller.d.ts.map +1 -1
  325. package/dist/types/controllers/newsletter.controller.d.ts +5 -6
  326. package/dist/types/controllers/newsletter.controller.d.ts.map +1 -1
  327. package/dist/types/controllers/oAuth2.controller.d.ts +3 -3
  328. package/dist/types/controllers/oAuth2.controller.d.ts.map +1 -1
  329. package/dist/types/controllers/organization.controller.d.ts +22 -23
  330. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  331. package/dist/types/controllers/project.controller.d.ts +13 -14
  332. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  333. package/dist/types/controllers/projectAccessKey.controller.d.ts +5 -6
  334. package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
  335. package/dist/types/controllers/search.controller.d.ts +2 -3
  336. package/dist/types/controllers/search.controller.d.ts.map +1 -1
  337. package/dist/types/controllers/stripe.controller.d.ts +5 -6
  338. package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
  339. package/dist/types/controllers/tag.controller.d.ts +9 -10
  340. package/dist/types/controllers/tag.controller.d.ts.map +1 -1
  341. package/dist/types/controllers/user.controller.d.ts +16 -19
  342. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  343. package/dist/types/emails/InviteUserEmail.d.ts.map +1 -1
  344. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +21 -0
  345. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts.map +1 -0
  346. package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
  347. package/dist/types/emails/Welcome.d.ts.map +1 -1
  348. package/dist/types/emails/index.d.ts +3 -2
  349. package/dist/types/emails/index.d.ts.map +1 -1
  350. package/dist/types/export.d.ts +2 -3
  351. package/dist/types/export.d.ts.map +1 -1
  352. package/dist/types/index.d.ts +1 -3
  353. package/dist/types/index.d.ts.map +1 -1
  354. package/dist/types/middlewares/oAuth2.middleware.d.ts +1 -2
  355. package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
  356. package/dist/types/middlewares/request.middleware.d.ts +3 -3
  357. package/dist/types/middlewares/request.middleware.d.ts.map +1 -1
  358. package/dist/types/middlewares/sessionAuth.middleware.d.ts +3 -25
  359. package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
  360. package/dist/types/models/dictionary.model.d.ts +6 -5
  361. package/dist/types/models/dictionary.model.d.ts.map +1 -1
  362. package/dist/types/models/discussion.model.d.ts +7 -2
  363. package/dist/types/models/discussion.model.d.ts.map +1 -1
  364. package/dist/types/models/oAuth2.model.d.ts +3 -2
  365. package/dist/types/models/oAuth2.model.d.ts.map +1 -1
  366. package/dist/types/models/organization.model.d.ts +2 -12
  367. package/dist/types/models/organization.model.d.ts.map +1 -1
  368. package/dist/types/models/project.model.d.ts +2 -11
  369. package/dist/types/models/project.model.d.ts.map +1 -1
  370. package/dist/types/models/session.model.d.ts +3 -0
  371. package/dist/types/models/session.model.d.ts.map +1 -0
  372. package/dist/types/models/tag.model.d.ts.map +1 -1
  373. package/dist/types/models/user.model.d.ts.map +1 -1
  374. package/dist/types/routes/ai.routes.d.ts.map +1 -1
  375. package/dist/types/routes/organization.routes.d.ts +4 -4
  376. package/dist/types/routes/project.routes.d.ts +4 -4
  377. package/dist/types/routes/project.routes.d.ts.map +1 -1
  378. package/dist/types/routes/tags.routes.d.ts +2 -2
  379. package/dist/types/routes/user.routes.d.ts +6 -7
  380. package/dist/types/routes/user.routes.d.ts.map +1 -1
  381. package/dist/types/schemas/dictionary.schema.d.ts +6 -8
  382. package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
  383. package/dist/types/schemas/discussion.schema.d.ts +7 -5
  384. package/dist/types/schemas/discussion.schema.d.ts.map +1 -1
  385. package/dist/types/schemas/oAuth2.schema.d.ts +4 -3
  386. package/dist/types/schemas/oAuth2.schema.d.ts.map +1 -1
  387. package/dist/types/schemas/organization.schema.d.ts +6 -10
  388. package/dist/types/schemas/organization.schema.d.ts.map +1 -1
  389. package/dist/types/schemas/plans.schema.d.ts +6 -8
  390. package/dist/types/schemas/plans.schema.d.ts.map +1 -1
  391. package/dist/types/schemas/project.schema.d.ts +5 -17
  392. package/dist/types/schemas/project.schema.d.ts.map +1 -1
  393. package/dist/types/schemas/session.schema.d.ts +14 -0
  394. package/dist/types/schemas/session.schema.d.ts.map +1 -0
  395. package/dist/types/schemas/tag.schema.d.ts +6 -8
  396. package/dist/types/schemas/tag.schema.d.ts.map +1 -1
  397. package/dist/types/schemas/user.schema.d.ts +7 -5
  398. package/dist/types/schemas/user.schema.d.ts.map +1 -1
  399. package/dist/types/services/dictionary.service.d.ts +9 -9
  400. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  401. package/dist/types/services/email.service.d.ts +4 -0
  402. package/dist/types/services/email.service.d.ts.map +1 -1
  403. package/dist/types/services/oAuth2.service.d.ts +23 -14
  404. package/dist/types/services/oAuth2.service.d.ts.map +1 -1
  405. package/dist/types/services/organization.service.d.ts +6 -12
  406. package/dist/types/services/organization.service.d.ts.map +1 -1
  407. package/dist/types/services/project.service.d.ts +5 -5
  408. package/dist/types/services/project.service.d.ts.map +1 -1
  409. package/dist/types/services/projectAccessKey.service.d.ts +5 -5
  410. package/dist/types/services/projectAccessKey.service.d.ts.map +1 -1
  411. package/dist/types/services/subscription.service.d.ts +1 -1
  412. package/dist/types/services/subscription.service.d.ts.map +1 -1
  413. package/dist/types/services/tag.service.d.ts +6 -6
  414. package/dist/types/services/tag.service.d.ts.map +1 -1
  415. package/dist/types/services/user.service.d.ts +7 -21
  416. package/dist/types/services/user.service.d.ts.map +1 -1
  417. package/dist/types/types/dictionary.types.d.ts +11 -9
  418. package/dist/types/types/dictionary.types.d.ts.map +1 -1
  419. package/dist/types/types/discussion.types.d.ts +5 -2
  420. package/dist/types/types/discussion.types.d.ts.map +1 -1
  421. package/dist/types/types/oAuth2.types.d.ts +5 -2
  422. package/dist/types/types/oAuth2.types.d.ts.map +1 -1
  423. package/dist/types/types/organization.types.d.ts +11 -8
  424. package/dist/types/types/organization.types.d.ts.map +1 -1
  425. package/dist/types/types/plan.types.d.ts +6 -3
  426. package/dist/types/types/plan.types.d.ts.map +1 -1
  427. package/dist/types/types/project.types.d.ts +25 -25
  428. package/dist/types/types/project.types.d.ts.map +1 -1
  429. package/dist/types/types/session.types.d.ts +31 -17
  430. package/dist/types/types/session.types.d.ts.map +1 -1
  431. package/dist/types/types/tag.types.d.ts +8 -6
  432. package/dist/types/types/tag.types.d.ts.map +1 -1
  433. package/dist/types/types/user.types.d.ts +14 -21
  434. package/dist/types/types/user.types.d.ts.map +1 -1
  435. package/dist/types/utils/AI/aiSdk.d.ts +2 -2
  436. package/dist/types/utils/AI/aiSdk.d.ts.map +1 -1
  437. package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts +2 -0
  438. package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -1
  439. package/dist/types/utils/AI/autocomplete/index.d.ts +4 -1
  440. package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -1
  441. package/dist/types/utils/access.d.ts +1 -0
  442. package/dist/types/utils/access.d.ts.map +1 -0
  443. package/dist/types/utils/accessControl.d.ts +9 -9
  444. package/dist/types/utils/accessControl.d.ts.map +1 -1
  445. package/dist/types/utils/auth/getAuth.d.ts +7 -0
  446. package/dist/types/utils/auth/getAuth.d.ts.map +1 -0
  447. package/dist/types/utils/cors.d.ts +3 -0
  448. package/dist/types/utils/cors.d.ts.map +1 -0
  449. package/dist/types/utils/ensureMongoDocumentToObject.d.ts +2 -2
  450. package/dist/types/utils/ensureMongoDocumentToObject.d.ts.map +1 -1
  451. package/dist/types/utils/errors/ErrorHandler.d.ts +1 -1
  452. package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
  453. package/dist/types/utils/errors/errorCodes.d.ts +57 -96
  454. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  455. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts +1 -1
  456. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
  457. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts +1 -1
  458. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
  459. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +1 -1
  460. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -1
  461. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts +1 -1
  462. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
  463. package/dist/types/utils/mapper/dictionary.d.ts +1 -1
  464. package/dist/types/utils/mapper/dictionary.d.ts.map +1 -1
  465. package/dist/types/utils/mapper/organization.d.ts +3 -2
  466. package/dist/types/utils/mapper/organization.d.ts.map +1 -1
  467. package/dist/types/utils/mapper/project.d.ts +4 -5
  468. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  469. package/dist/types/utils/mapper/tag.d.ts +1 -1
  470. package/dist/types/utils/mapper/tag.d.ts.map +1 -1
  471. package/dist/types/utils/mapper/user.d.ts +2 -2
  472. package/dist/types/utils/mapper/user.d.ts.map +1 -1
  473. package/dist/types/utils/mergeFunctionTypes.d.ts +18 -0
  474. package/dist/types/utils/mergeFunctionTypes.d.ts.map +1 -0
  475. package/dist/types/utils/mongoDB/connectDB.d.ts +1 -1
  476. package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
  477. package/dist/types/utils/mongoDB/types.d.ts +11 -0
  478. package/dist/types/utils/mongoDB/types.d.ts.map +1 -0
  479. package/dist/types/utils/permissions.d.ts +115 -0
  480. package/dist/types/utils/permissions.d.ts.map +1 -0
  481. package/dist/types/utils/rateLimiter.d.ts +4 -0
  482. package/dist/types/utils/rateLimiter.d.ts.map +1 -0
  483. package/package.json +16 -14
  484. package/dist/cjs/controllers/sessionAuth.controller.cjs +0 -839
  485. package/dist/cjs/controllers/sessionAuth.controller.cjs.map +0 -1
  486. package/dist/cjs/routes/sessionAuth.routes.cjs +0 -154
  487. package/dist/cjs/routes/sessionAuth.routes.cjs.map +0 -1
  488. package/dist/cjs/services/sessionAuth.service.cjs +0 -385
  489. package/dist/cjs/services/sessionAuth.service.cjs.map +0 -1
  490. package/dist/cjs/utils/CSRF.cjs +0 -50
  491. package/dist/cjs/utils/CSRF.cjs.map +0 -1
  492. package/dist/cjs/utils/cookies.cjs +0 -59
  493. package/dist/cjs/utils/cookies.cjs.map +0 -1
  494. package/dist/esm/controllers/sessionAuth.controller.mjs +0 -790
  495. package/dist/esm/controllers/sessionAuth.controller.mjs.map +0 -1
  496. package/dist/esm/routes/sessionAuth.routes.mjs +0 -142
  497. package/dist/esm/routes/sessionAuth.routes.mjs.map +0 -1
  498. package/dist/esm/services/sessionAuth.service.mjs +0 -337
  499. package/dist/esm/services/sessionAuth.service.mjs.map +0 -1
  500. package/dist/esm/utils/CSRF.mjs +0 -24
  501. package/dist/esm/utils/CSRF.mjs.map +0 -1
  502. package/dist/esm/utils/cookies.mjs +0 -32
  503. package/dist/esm/utils/cookies.mjs.map +0 -1
  504. package/dist/types/controllers/sessionAuth.controller.d.ts +0 -140
  505. package/dist/types/controllers/sessionAuth.controller.d.ts.map +0 -1
  506. package/dist/types/routes/sessionAuth.routes.d.ts +0 -77
  507. package/dist/types/routes/sessionAuth.routes.d.ts.map +0 -1
  508. package/dist/types/services/sessionAuth.service.d.ts +0 -141
  509. package/dist/types/services/sessionAuth.service.d.ts.map +0 -1
  510. package/dist/types/utils/CSRF.d.ts +0 -3
  511. package/dist/types/utils/CSRF.d.ts.map +0 -1
  512. package/dist/types/utils/cookies.d.ts +0 -12
  513. package/dist/types/utils/cookies.d.ts.map +0 -1
@@ -6,10 +6,26 @@ You're the assistant and you will have to complete your own text.
6
6
  - You should try to guess the next word(s) or complete the sentence.
7
7
  - Your completion should not exceed one sentence.
8
8
  - Minimize the completion length if you're unsure about the user's input.
9
+ - Avoid duplication of the current line in the suggestion.
10
+ - Avoid dialog-like completions.
9
11
 
10
- The user input will be provided in the next user message:
12
+ The user input will be provided in the next user message.
11
13
 
12
- Exmaple of entry:
14
+ Use the following context to generate the completion:
15
+
16
+ Context before the cursor:
17
+
18
+ {{contextBefore}}
19
+
20
+ Current line up to cursor:
21
+
22
+ {{currentLine}}
23
+
24
+ Context after the cursor:
25
+
26
+ {{contextAfter}}
27
+
28
+ Example of entry:
13
29
 
14
30
  ```json
15
31
  { "role": "user", "content": "Lorem ipsum " }
@@ -11,25 +11,28 @@ const aiDefaultOptions = {
11
11
  provider: AIProvider.OPENAI,
12
12
  model: "gpt-4o-mini",
13
13
  temperature: 0.7,
14
- maxTokens: 6
14
+ maxTokens: 128
15
15
  };
16
16
  const autocomplete = async ({
17
17
  text,
18
18
  aiConfig,
19
- applicationContext
19
+ applicationContext,
20
+ contextBefore,
21
+ currentLine,
22
+ contextAfter
20
23
  }) => {
21
24
  const prompt = CHAT_GPT_PROMPT.replace(
22
25
  "{{applicationContext}}",
23
26
  applicationContext ?? ""
24
- );
27
+ ).replace("{{contextBefore}}", contextBefore ?? "").replace("{{currentLine}}", currentLine ?? "").replace("{{contextAfter}}", contextAfter ?? "");
25
28
  const { text: newContent, usage } = await generateText({
26
29
  ...aiConfig,
27
30
  messages: [
28
31
  { role: "system", content: prompt },
29
32
  { role: "assistant", content: text }
30
33
  ],
31
- maxTokens: 6
32
- // Generate next 6 tokens
34
+ maxTokens: aiConfig.maxTokens ?? 128
35
+ // Generate next tokens
33
36
  });
34
37
  logger.info(`${usage?.totalTokens ?? 0} tokens used in the request`);
35
38
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/utils/AI/autocomplete/index.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { generateText } from 'ai';\nimport { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { AIConfig, AIOptions, AIProvider } from '../aiSdk';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// Get the content of a file at the specified path\nconst getFileContent = (filePath: string) =>\n readFileSync(join(__dirname, filePath), { encoding: 'utf-8' });\n\nexport type AutocompleteOptions = {\n text: string;\n aiConfig: AIConfig;\n applicationContext?: string;\n};\n\nexport type AutocompleteFileResultData = {\n autocompletion: string;\n tokenUsed: number;\n};\n\n// The prompt template to send to the AI model\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\nexport const aiDefaultOptions: AIOptions = {\n provider: AIProvider.OPENAI,\n model: 'gpt-4o-mini',\n temperature: 0.7,\n maxTokens: 6,\n};\n\n/**\n * Autocompletes a content declaration file by constructing a prompt for AI models.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies.\n */\nexport const autocomplete = async ({\n text,\n aiConfig,\n applicationContext,\n}: AutocompleteOptions): Promise<AutocompleteFileResultData | undefined> => {\n // Prepare the prompt for AI by replacing placeholders with actual values.\n const prompt = CHAT_GPT_PROMPT.replace(\n '{{applicationContext}}',\n applicationContext ?? ''\n );\n\n // Use the AI SDK to generate the completion\n const { text: newContent, usage } = await generateText({\n ...aiConfig,\n messages: [\n { role: 'system', content: prompt },\n { role: 'assistant', content: text },\n ],\n maxTokens: 6, // Generate next 6 tokens\n });\n\n logger.info(`${usage?.totalTokens ?? 0} tokens used in the request`);\n\n return {\n autocompletion: newContent,\n tokenUsed: usage?.totalTokens ?? 0,\n };\n};\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAC9B,SAA8B,kBAAkB;AAEhD,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAGxD,MAAM,iBAAiB,CAAC,aACtB,aAAa,KAAK,WAAW,QAAQ,GAAG,EAAE,UAAU,QAAQ,CAAC;AAc/D,MAAM,kBAAkB,eAAe,aAAa;AAE7C,MAAM,mBAA8B;AAAA,EACzC,UAAU,WAAW;AAAA,EACrB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,WAAW;AACb;AAOO,MAAM,eAAe,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,MAA4E;AAE1E,QAAM,SAAS,gBAAgB;AAAA,IAC7B;AAAA,IACA,sBAAsB;AAAA,EACxB;AAGA,QAAM,EAAE,MAAM,YAAY,MAAM,IAAI,MAAM,aAAa;AAAA,IACrD,GAAG;AAAA,IACH,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,MAClC,EAAE,MAAM,aAAa,SAAS,KAAK;AAAA,IACrC;AAAA,IACA,WAAW;AAAA;AAAA,EACb,CAAC;AAED,SAAO,KAAK,GAAG,OAAO,eAAe,CAAC,6BAA6B;AAEnE,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,WAAW,OAAO,eAAe;AAAA,EACnC;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/utils/AI/autocomplete/index.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { generateText } from 'ai';\nimport { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { AIConfig, AIOptions, AIProvider } from '../aiSdk';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// Get the content of a file at the specified path\nconst getFileContent = (filePath: string) =>\n readFileSync(join(__dirname, filePath), { encoding: 'utf-8' });\n\nexport type AutocompleteOptions = {\n text: string;\n aiConfig: AIConfig;\n applicationContext?: string;\n contextBefore?: string;\n currentLine?: string;\n contextAfter?: string;\n};\n\nexport type AutocompleteFileResultData = {\n autocompletion: string;\n tokenUsed: number;\n};\n\n// The prompt template to send to the AI model\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\nexport const aiDefaultOptions: AIOptions = {\n provider: AIProvider.OPENAI,\n model: 'gpt-4o-mini',\n temperature: 0.7,\n maxTokens: 128,\n};\n\n/**\n * Autocompletes a content declaration file by constructing a prompt for AI models.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies.\n */\nexport const autocomplete = async ({\n text,\n aiConfig,\n applicationContext,\n contextBefore,\n currentLine,\n contextAfter,\n}: AutocompleteOptions): Promise<AutocompleteFileResultData | undefined> => {\n // Prepare the prompt for AI by replacing placeholders with actual values.\n const prompt = CHAT_GPT_PROMPT.replace(\n '{{applicationContext}}',\n applicationContext ?? ''\n )\n .replace('{{contextBefore}}', contextBefore ?? '')\n .replace('{{currentLine}}', currentLine ?? '')\n .replace('{{contextAfter}}', contextAfter ?? '');\n\n // Use the AI SDK to generate the completion\n const { text: newContent, usage } = await generateText({\n ...aiConfig,\n messages: [\n { role: 'system', content: prompt },\n { role: 'assistant', content: text },\n ],\n maxTokens: aiConfig.maxTokens ?? 128, // Generate next tokens\n });\n\n logger.info(`${usage?.totalTokens ?? 0} tokens used in the request`);\n\n return {\n autocompletion: newContent,\n tokenUsed: usage?.totalTokens ?? 0,\n };\n};\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAC9B,SAA8B,kBAAkB;AAEhD,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAGxD,MAAM,iBAAiB,CAAC,aACtB,aAAa,KAAK,WAAW,QAAQ,GAAG,EAAE,UAAU,QAAQ,CAAC;AAiB/D,MAAM,kBAAkB,eAAe,aAAa;AAE7C,MAAM,mBAA8B;AAAA,EACzC,UAAU,WAAW;AAAA,EACrB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,WAAW;AACb;AAOO,MAAM,eAAe,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA4E;AAE1E,QAAM,SAAS,gBAAgB;AAAA,IAC7B;AAAA,IACA,sBAAsB;AAAA,EACxB,EACG,QAAQ,qBAAqB,iBAAiB,EAAE,EAChD,QAAQ,mBAAmB,eAAe,EAAE,EAC5C,QAAQ,oBAAoB,gBAAgB,EAAE;AAGjD,QAAM,EAAE,MAAM,YAAY,MAAM,IAAI,MAAM,aAAa;AAAA,IACrD,GAAG;AAAA,IACH,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,MAClC,EAAE,MAAM,aAAa,SAAS,KAAK;AAAA,IACrC;AAAA,IACA,WAAW,SAAS,aAAa;AAAA;AAAA,EACnC,CAAC;AAED,SAAO,KAAK,GAAG,OAAO,eAAe,CAAC,6BAA6B;AAEnE,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,WAAW,OAAO,eAAe;AAAA,EACnC;AACF;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=access.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -8,6 +8,7 @@ var AccessRule = /* @__PURE__ */ ((AccessRule2) => {
8
8
  AccessRule2["hasOrganization"] = "has-organization";
9
9
  AccessRule2["hasProject"] = "has-project";
10
10
  AccessRule2["hasBearer"] = "has-bearer";
11
+ AccessRule2["oauth2"] = "oauth2";
11
12
  return AccessRule2;
12
13
  })(AccessRule || {});
13
14
  const accessControl = (res, accessRule) => {
@@ -47,6 +48,12 @@ const accessControl = (res, accessRule) => {
47
48
  messages.push("Project is not set");
48
49
  }
49
50
  }
51
+ if (accessRuleArray.includes("oauth2" /* oauth2 */)) {
52
+ if (authType !== "oauth2") {
53
+ success = false;
54
+ messages.push("OAuth2 authentication is required");
55
+ }
56
+ }
50
57
  const knownRules = Object.values(AccessRule);
51
58
  const unknownRules = accessRuleArray.filter(
52
59
  (rule) => !knownRules.includes(rule)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/accessControl.ts"],"sourcesContent":["import { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport type { NextFunction, Request } from 'express';\nimport { HttpStatusCodes } from './httpStatusCodes';\n\nexport enum AccessRule {\n none = 'none',\n authenticated = 'authenticated',\n admin = 'admin',\n noneAuthenticated = 'none-authenticated',\n hasOrganization = 'has-organization',\n hasProject = 'has-project',\n hasBearer = 'has-bearer',\n}\n\nexport const accessControl = <R extends AccessRule | AccessRule[]>(\n res: ResponseWithInformation,\n accessRule: R\n) => {\n const accessRuleArray: AccessRule[] = Array.isArray(accessRule)\n ? accessRule\n : [accessRule];\n\n const localsAuthInformation = res.locals;\n const { user, organization, project, authType } = localsAuthInformation;\n\n // If 'none' access rule is present, immediately return success\n if (accessRuleArray.includes(AccessRule.none)) {\n return {\n success: true,\n message: null,\n data: { user, organization, project, authType },\n };\n }\n\n let success = true;\n const messages: string[] = [];\n\n // Check for 'authenticated' access rule\n if (accessRuleArray.includes(AccessRule.authenticated)) {\n if (!user) {\n success = false;\n messages.push('User is not authenticated');\n }\n }\n\n // Check for 'admin' access rule\n // if (accessRuleArray.includes(AccessRule.admin)) {\n // if (!user?.role.includes('admin')) {\n // success = false;\n // messages.push('User is not an admin');\n // }\n // }\n\n // Check for 'none-authenticated' access rule\n if (accessRuleArray.includes(AccessRule.noneAuthenticated)) {\n if (user) {\n success = false;\n messages.push('User is authenticated');\n }\n }\n\n // Check for 'has-organization' access rule\n if (accessRuleArray.includes(AccessRule.hasOrganization)) {\n if (!organization) {\n success = false;\n messages.push('Organization is not set');\n }\n }\n\n // Check for 'has-project' access rule\n if (accessRuleArray.includes(AccessRule.hasProject)) {\n if (!project) {\n success = false;\n messages.push('Project is not set');\n }\n }\n\n // Handle unknown access rules\n const knownRules = Object.values(AccessRule);\n const unknownRules = accessRuleArray.filter(\n (rule) => !knownRules.includes(rule)\n );\n if (unknownRules.length > 0) {\n success = false;\n messages.push(`Unknown access rules: ${unknownRules.join(', ')}`);\n }\n\n return {\n success,\n message: messages.join(', '),\n data: { user, organization, project, authType },\n };\n};\n\n/**\n * Middleware to control API access based on access rules.\n *\n * This middleware allows for multiple access rules to be passed, either as individual `AccessRule` or\n * an array of `AccessRule` groups. Access is granted if at least one of the following conditions is met:\n *\n * - The user satisfies all `AccessRule` within any group of rules passed as an array.\n * - The user satisfies any single `AccessRule` passed individually.\n *\n * Example usage:\n *\n * ```typescript\n * // Allow access if the user has both `hasProject` and `hasOrganization`, or if they have `admin` rights\n * app.use('/protected-route', apiAccessControlMiddleWare([AccessRule.hasProject, AccessRule.hasOrganization], AccessRule.admin));\n * ```\n *\n * In this example:\n * - The user will be granted access if they have both `hasProject` and `hasOrganization`.\n * - Alternatively, the user will also be granted access if they have `admin` privileges.\n *\n * @param {...(AccessRule | AccessRule[])[]} accessRules - One or more access rules or groups of access rules.\n * - Single `AccessRule`: The user must satisfy this rule for access to be granted.\n * - Array of `AccessRule`: The user must satisfy all rules in the array for access to be granted.\n * @returns {Function} Express middleware function that checks if the user has the required access.\n *\n * If the user does not meet any of the provided access rules, a 403 Forbidden status is returned.\n *\n * @example\n * // Example 1: Require admin privileges\n * app.use('/admin', apiAccessControlMiddleWare(AccessRule.admin));\n *\n * @example\n * // Example 2: Require both project and organization access, or admin privileges\n * app.use('/dashboard', apiAccessControlMiddleWare([AccessRule.hasProject, AccessRule.hasOrganization], AccessRule.admin));\n */\nexport const accessControlMiddleWare =\n (...accessRules: (AccessRule | AccessRule[])[]) =>\n (\n _req: Request<unknown>,\n res: ResponseWithInformation,\n next: NextFunction\n ): void => {\n let hasAccess = false;\n\n // Iterate over each access rule group (either single AccessRule or an array of AccessRules)\n for (const ruleGroup of accessRules) {\n if (Array.isArray(ruleGroup)) {\n // If ruleGroup is an array, check if all rules in the group are satisfied\n const accessResults = ruleGroup.map(\n (rule) => accessControl(res, rule).success\n );\n hasAccess = accessResults.every((result) => result); // All rules must be satisfied in this case\n } else {\n // Single rule: just check this one\n const accessResult = accessControl(res, ruleGroup);\n if (accessResult.success) {\n hasAccess = true;\n }\n }\n\n // If access is granted at any point, stop further checks\n if (hasAccess) {\n break;\n }\n }\n\n // If no access rule group was satisfied, deny access\n if (!hasAccess) {\n logger.error('Access denied');\n\n const errorStatusCode = HttpStatusCodes.FORBIDDEN_403;\n res.sendStatus(errorStatusCode);\n return;\n }\n\n next();\n };\n"],"mappings":"AAAA,SAAS,cAAc;AAGvB,SAAS,uBAAuB;AAEzB,IAAK,aAAL,kBAAKA,gBAAL;AACL,EAAAA,YAAA,UAAO;AACP,EAAAA,YAAA,mBAAgB;AAChB,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,uBAAoB;AACpB,EAAAA,YAAA,qBAAkB;AAClB,EAAAA,YAAA,gBAAa;AACb,EAAAA,YAAA,eAAY;AAPF,SAAAA;AAAA,GAAA;AAUL,MAAM,gBAAgB,CAC3B,KACA,eACG;AACH,QAAM,kBAAgC,MAAM,QAAQ,UAAU,IAC1D,aACA,CAAC,UAAU;AAEf,QAAM,wBAAwB,IAAI;AAClC,QAAM,EAAE,MAAM,cAAc,SAAS,SAAS,IAAI;AAGlD,MAAI,gBAAgB,SAAS,iBAAe,GAAG;AAC7C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM,EAAE,MAAM,cAAc,SAAS,SAAS;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,UAAU;AACd,QAAM,WAAqB,CAAC;AAG5B,MAAI,gBAAgB,SAAS,mCAAwB,GAAG;AACtD,QAAI,CAAC,MAAM;AACT,gBAAU;AACV,eAAS,KAAK,2BAA2B;AAAA,IAC3C;AAAA,EACF;AAWA,MAAI,gBAAgB,SAAS,4CAA4B,GAAG;AAC1D,QAAI,MAAM;AACR,gBAAU;AACV,eAAS,KAAK,uBAAuB;AAAA,IACvC;AAAA,EACF;AAGA,MAAI,gBAAgB,SAAS,wCAA0B,GAAG;AACxD,QAAI,CAAC,cAAc;AACjB,gBAAU;AACV,eAAS,KAAK,yBAAyB;AAAA,IACzC;AAAA,EACF;AAGA,MAAI,gBAAgB,SAAS,8BAAqB,GAAG;AACnD,QAAI,CAAC,SAAS;AACZ,gBAAU;AACV,eAAS,KAAK,oBAAoB;AAAA,IACpC;AAAA,EACF;AAGA,QAAM,aAAa,OAAO,OAAO,UAAU;AAC3C,QAAM,eAAe,gBAAgB;AAAA,IACnC,CAAC,SAAS,CAAC,WAAW,SAAS,IAAI;AAAA,EACrC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,cAAU;AACV,aAAS,KAAK,yBAAyB,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,SAAS,KAAK,IAAI;AAAA,IAC3B,MAAM,EAAE,MAAM,cAAc,SAAS,SAAS;AAAA,EAChD;AACF;AAqCO,MAAM,0BACX,IAAI,gBACJ,CACE,MACA,KACA,SACS;AACT,MAAI,YAAY;AAGhB,aAAW,aAAa,aAAa;AACnC,QAAI,MAAM,QAAQ,SAAS,GAAG;AAE5B,YAAM,gBAAgB,UAAU;AAAA,QAC9B,CAAC,SAAS,cAAc,KAAK,IAAI,EAAE;AAAA,MACrC;AACA,kBAAY,cAAc,MAAM,CAAC,WAAW,MAAM;AAAA,IACpD,OAAO;AAEL,YAAM,eAAe,cAAc,KAAK,SAAS;AACjD,UAAI,aAAa,SAAS;AACxB,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,QAAI,WAAW;AACb;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,WAAW;AACd,WAAO,MAAM,eAAe;AAE5B,UAAM,kBAAkB,gBAAgB;AACxC,QAAI,WAAW,eAAe;AAC9B;AAAA,EACF;AAEA,OAAK;AACP;","names":["AccessRule"]}
1
+ {"version":3,"sources":["../../../src/utils/accessControl.ts"],"sourcesContent":["import { logger } from '@logger';\n\nimport type { NextFunction, Request, Response } from 'express';\nimport { HttpStatusCodes } from './httpStatusCodes';\n\nexport enum AccessRule {\n none = 'none',\n authenticated = 'authenticated',\n admin = 'admin',\n noneAuthenticated = 'none-authenticated',\n hasOrganization = 'has-organization',\n hasProject = 'has-project',\n hasBearer = 'has-bearer',\n oauth2 = 'oauth2',\n}\n\nexport const accessControl = <R extends AccessRule | AccessRule[]>(\n res: Response,\n accessRule: R\n) => {\n const accessRuleArray: AccessRule[] = Array.isArray(accessRule)\n ? accessRule\n : [accessRule];\n\n const localsAuthInformation = res.locals;\n const { user, organization, project, authType } = localsAuthInformation;\n\n // If 'none' access rule is present, immediately return success\n if (accessRuleArray.includes(AccessRule.none)) {\n return {\n success: true,\n message: null,\n data: { user, organization, project, authType },\n };\n }\n\n let success = true;\n const messages: string[] = [];\n\n // Check for 'authenticated' access rule\n if (accessRuleArray.includes(AccessRule.authenticated)) {\n if (!user) {\n success = false;\n messages.push('User is not authenticated');\n }\n }\n\n // Check for 'admin' access rule\n // if (accessRuleArray.includes(AccessRule.admin)) {\n // if (!user?.role.includes('admin')) {\n // success = false;\n // messages.push('User is not an admin');\n // }\n // }\n\n // Check for 'none-authenticated' access rule\n if (accessRuleArray.includes(AccessRule.noneAuthenticated)) {\n if (user) {\n success = false;\n messages.push('User is authenticated');\n }\n }\n\n // Check for 'has-organization' access rule\n if (accessRuleArray.includes(AccessRule.hasOrganization)) {\n if (!organization) {\n success = false;\n messages.push('Organization is not set');\n }\n }\n\n // Check for 'has-project' access rule\n if (accessRuleArray.includes(AccessRule.hasProject)) {\n if (!project) {\n success = false;\n messages.push('Project is not set');\n }\n }\n\n // Check for 'oauth2' access rule\n if (accessRuleArray.includes(AccessRule.oauth2)) {\n if (authType !== 'oauth2') {\n success = false;\n messages.push('OAuth2 authentication is required');\n }\n }\n\n // Handle unknown access rules\n const knownRules = Object.values(AccessRule);\n const unknownRules = accessRuleArray.filter(\n (rule) => !knownRules.includes(rule)\n );\n if (unknownRules.length > 0) {\n success = false;\n messages.push(`Unknown access rules: ${unknownRules.join(', ')}`);\n }\n\n return {\n success,\n message: messages.join(', '),\n data: { user, organization, project, authType },\n };\n};\n\n/**\n * Middleware to control API access based on access rules.\n *\n * This middleware allows for multiple access rules to be passed, either as individual `AccessRule` or\n * an array of `AccessRule` groups. Access is granted if at least one of the following conditions is met:\n *\n * - The user satisfies all `AccessRule` within any group of rules passed as an array.\n * - The user satisfies any single `AccessRule` passed individually.\n *\n * Example usage:\n *\n * ```typescript\n * // Allow access if the user has both `hasProject` and `hasOrganization`, or if they have `admin` rights\n * app.use('/protected-route', apiAccessControlMiddleWare([AccessRule.hasProject, AccessRule.hasOrganization], AccessRule.admin));\n * ```\n *\n * In this example:\n * - The user will be granted access if they have both `hasProject` and `hasOrganization`.\n * - Alternatively, the user will also be granted access if they have `admin` privileges.\n *\n * @param {...(AccessRule | AccessRule[])[]} accessRules - One or more access rules or groups of access rules.\n * - Single `AccessRule`: The user must satisfy this rule for access to be granted.\n * - Array of `AccessRule`: The user must satisfy all rules in the array for access to be granted.\n * @returns {Function} Express middleware function that checks if the user has the required access.\n *\n * If the user does not meet any of the provided access rules, a 403 Forbidden status is returned.\n *\n * @example\n * // Example 1: Require admin privileges\n * app.use('/admin', apiAccessControlMiddleWare(AccessRule.admin));\n *\n * @example\n * // Example 2: Require both project and organization access, or admin privileges\n * app.use('/dashboard', apiAccessControlMiddleWare([AccessRule.hasProject, AccessRule.hasOrganization], AccessRule.admin));\n */\nexport const accessControlMiddleWare =\n (...accessRules: (AccessRule | AccessRule[])[]) =>\n (_req: Request<unknown>, res: Response, next: NextFunction): void => {\n let hasAccess = false;\n\n // Iterate over each access rule group (either single AccessRule or an array of AccessRules)\n for (const ruleGroup of accessRules) {\n if (Array.isArray(ruleGroup)) {\n // If ruleGroup is an array, check if all rules in the group are satisfied\n const accessResults = ruleGroup.map(\n (rule) => accessControl(res, rule).success\n );\n hasAccess = accessResults.every((result) => result); // All rules must be satisfied in this case\n } else {\n // Single rule: just check this one\n const accessResult = accessControl(res, ruleGroup);\n if (accessResult.success) {\n hasAccess = true;\n }\n }\n\n // If access is granted at any point, stop further checks\n if (hasAccess) {\n break;\n }\n }\n\n // If no access rule group was satisfied, deny access\n if (!hasAccess) {\n logger.error('Access denied');\n\n const errorStatusCode = HttpStatusCodes.FORBIDDEN_403;\n res.sendStatus(errorStatusCode);\n return;\n }\n\n next();\n };\n"],"mappings":"AAAA,SAAS,cAAc;AAGvB,SAAS,uBAAuB;AAEzB,IAAK,aAAL,kBAAKA,gBAAL;AACL,EAAAA,YAAA,UAAO;AACP,EAAAA,YAAA,mBAAgB;AAChB,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,uBAAoB;AACpB,EAAAA,YAAA,qBAAkB;AAClB,EAAAA,YAAA,gBAAa;AACb,EAAAA,YAAA,eAAY;AACZ,EAAAA,YAAA,YAAS;AARC,SAAAA;AAAA,GAAA;AAWL,MAAM,gBAAgB,CAC3B,KACA,eACG;AACH,QAAM,kBAAgC,MAAM,QAAQ,UAAU,IAC1D,aACA,CAAC,UAAU;AAEf,QAAM,wBAAwB,IAAI;AAClC,QAAM,EAAE,MAAM,cAAc,SAAS,SAAS,IAAI;AAGlD,MAAI,gBAAgB,SAAS,iBAAe,GAAG;AAC7C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM,EAAE,MAAM,cAAc,SAAS,SAAS;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,UAAU;AACd,QAAM,WAAqB,CAAC;AAG5B,MAAI,gBAAgB,SAAS,mCAAwB,GAAG;AACtD,QAAI,CAAC,MAAM;AACT,gBAAU;AACV,eAAS,KAAK,2BAA2B;AAAA,IAC3C;AAAA,EACF;AAWA,MAAI,gBAAgB,SAAS,4CAA4B,GAAG;AAC1D,QAAI,MAAM;AACR,gBAAU;AACV,eAAS,KAAK,uBAAuB;AAAA,IACvC;AAAA,EACF;AAGA,MAAI,gBAAgB,SAAS,wCAA0B,GAAG;AACxD,QAAI,CAAC,cAAc;AACjB,gBAAU;AACV,eAAS,KAAK,yBAAyB;AAAA,IACzC;AAAA,EACF;AAGA,MAAI,gBAAgB,SAAS,8BAAqB,GAAG;AACnD,QAAI,CAAC,SAAS;AACZ,gBAAU;AACV,eAAS,KAAK,oBAAoB;AAAA,IACpC;AAAA,EACF;AAGA,MAAI,gBAAgB,SAAS,qBAAiB,GAAG;AAC/C,QAAI,aAAa,UAAU;AACzB,gBAAU;AACV,eAAS,KAAK,mCAAmC;AAAA,IACnD;AAAA,EACF;AAGA,QAAM,aAAa,OAAO,OAAO,UAAU;AAC3C,QAAM,eAAe,gBAAgB;AAAA,IACnC,CAAC,SAAS,CAAC,WAAW,SAAS,IAAI;AAAA,EACrC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,cAAU;AACV,aAAS,KAAK,yBAAyB,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,SAAS,KAAK,IAAI;AAAA,IAC3B,MAAM,EAAE,MAAM,cAAc,SAAS,SAAS;AAAA,EAChD;AACF;AAqCO,MAAM,0BACX,IAAI,gBACJ,CAAC,MAAwB,KAAe,SAA6B;AACnE,MAAI,YAAY;AAGhB,aAAW,aAAa,aAAa;AACnC,QAAI,MAAM,QAAQ,SAAS,GAAG;AAE5B,YAAM,gBAAgB,UAAU;AAAA,QAC9B,CAAC,SAAS,cAAc,KAAK,IAAI,EAAE;AAAA,MACrC;AACA,kBAAY,cAAc,MAAM,CAAC,WAAW,MAAM;AAAA,IACpD,OAAO;AAEL,YAAM,eAAe,cAAc,KAAK,SAAS;AACjD,UAAI,aAAa,SAAS;AACxB,oBAAY;AAAA,MACd;AAAA,IACF;AAGA,QAAI,WAAW;AACb;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,WAAW;AACd,WAAO,MAAM,eAAe;AAE5B,UAAM,kBAAkB,gBAAgB;AACxC,QAAI,WAAW,eAAe;AAC9B;AAAA,EACF;AAEA,OAAK;AACP;","names":["AccessRule"]}
@@ -0,0 +1,227 @@
1
+ import { sendVerificationUpdate } from "./../../controllers/user.controller.mjs";
2
+ import { logger } from "./../../logger/index.mjs";
3
+ import { sendEmail } from "./../../services/email.service.mjs";
4
+ import { getOrganizationById } from "./../../services/organization.service.mjs";
5
+ import { getProjectById } from "./../../services/project.service.mjs";
6
+ import { getUserById } from "./../../services/user.service.mjs";
7
+ import { mapOrganizationToAPI } from "./../../utils/mapper/organization.mjs";
8
+ import { mapProjectToAPI } from "./../../utils/mapper/project.mjs";
9
+ import { mapUserToAPI } from "./../../utils/mapper/user.mjs";
10
+ import {
11
+ computeEffectivePermission,
12
+ getSessionRoles,
13
+ intersectPermissions
14
+ } from "./../../utils/permissions.mjs";
15
+ import { betterAuth } from "better-auth";
16
+ import { mongodbAdapter } from "better-auth/adapters/mongodb";
17
+ import { createAuthMiddleware } from "better-auth/api";
18
+ import { customSession } from "better-auth/plugins";
19
+ const formatSession = (session) => {
20
+ const roles = getSessionRoles(session);
21
+ let permissions = computeEffectivePermission(roles);
22
+ if (session.permissions) {
23
+ permissions = intersectPermissions(permissions, session.permissions);
24
+ }
25
+ const resultSession = {
26
+ user: mapUserToAPI(session.user),
27
+ organization: mapOrganizationToAPI(session.organization),
28
+ project: mapProjectToAPI(session.project),
29
+ authType: "session",
30
+ permissions,
31
+ roles
32
+ };
33
+ return resultSession;
34
+ };
35
+ const getAuth = (dbClient) => {
36
+ if (!dbClient) {
37
+ throw new Error("MongoDB connection not established");
38
+ }
39
+ const auth = betterAuth({
40
+ appName: "Intlayer",
41
+ database: mongodbAdapter(dbClient.db()),
42
+ /**
43
+ * User model
44
+ */
45
+ user: {
46
+ modelName: "users"
47
+ },
48
+ databaseHooks: {
49
+ user: {
50
+ create: {
51
+ // Runs once, immediately after the INSERT
52
+ after: async (user) => {
53
+ if (!user?.emailVerified) return;
54
+ await sendEmail({
55
+ type: "welcome",
56
+ to: user.email,
57
+ username: user.name ?? user.email.split("@")[0],
58
+ loginLink: `${process.env.CLIENT_URL}/auth/login`,
59
+ locale: user.lang
60
+ });
61
+ logger.info("Welcome e\u2011mail delivered", {
62
+ email: user.email
63
+ });
64
+ }
65
+ }
66
+ }
67
+ },
68
+ hooks: {
69
+ after: createAuthMiddleware(async (ctx) => {
70
+ const { path, context } = ctx;
71
+ const newUser = context.newSession?.user;
72
+ const existingUser = context.session?.user;
73
+ const user = newUser ?? existingUser;
74
+ if (!user) return;
75
+ if (["/verify-email"].includes(path)) {
76
+ sendVerificationUpdate(user);
77
+ logger.info("SSE verification update sent", {
78
+ email: user.email,
79
+ userId: user.id
80
+ });
81
+ await sendEmail({
82
+ type: "welcome",
83
+ to: user.email,
84
+ username: user.name ?? user.email.split("@")[0],
85
+ loginLink: `${process.env.CLIENT_URL}/auth/login`,
86
+ locale: user.lang
87
+ });
88
+ logger.info("Welcome e\u2011mail delivered", {
89
+ email: user.email
90
+ });
91
+ }
92
+ })
93
+ },
94
+ advanced: {
95
+ // 1️⃣ Change or drop the global prefix
96
+ // cookiePrefix: "intlayer", // => intlayer.session_token
97
+ cookiePrefix: "intlayer",
98
+ // => session_token (no prefix)
99
+ // 2️⃣ Override just the session‑token cookie
100
+ cookies: {
101
+ session_token: {
102
+ // name: 'intlayer_session_token', // final name depends on the prefix above
103
+ // attributes: { sameSite: "lax", maxAge: 60 * 60 * 24 } // optional
104
+ }
105
+ }
106
+ // 3️⃣ (optional) turn off the automatic __Secure‑ prefix in non‑prod
107
+ // useSecureCookies: false,
108
+ },
109
+ session: {
110
+ modelName: "sessions",
111
+ id: "id",
112
+ additionalFields: {
113
+ activeOrganizationId: { type: "string", nullable: true, input: false },
114
+ activeProjectId: { type: "string", nullable: true, input: false }
115
+ }
116
+ },
117
+ plugins: [
118
+ customSession(async ({ session }) => {
119
+ const typedSession = session;
120
+ let userAPI = null;
121
+ let organizationAPI = null;
122
+ let projectAPI = null;
123
+ if (typedSession.userId) {
124
+ const userData = await getUserById(typedSession.userId);
125
+ if (userData) {
126
+ userAPI = mapUserToAPI(userData);
127
+ }
128
+ }
129
+ if (typedSession.activeOrganizationId) {
130
+ const orgData = await getOrganizationById(
131
+ typedSession.activeOrganizationId
132
+ );
133
+ if (orgData) {
134
+ organizationAPI = mapOrganizationToAPI(orgData);
135
+ }
136
+ }
137
+ if (typedSession.activeProjectId) {
138
+ const projectData = await getProjectById(
139
+ typedSession.activeProjectId
140
+ );
141
+ if (projectData) {
142
+ projectAPI = mapProjectToAPI(projectData);
143
+ }
144
+ }
145
+ const sessionWithNoPermission = {
146
+ session: typedSession,
147
+ user: userAPI,
148
+ organization: organizationAPI ?? null,
149
+ project: projectAPI ?? null,
150
+ authType: "session"
151
+ };
152
+ return formatSession(sessionWithNoPermission);
153
+ })
154
+ ],
155
+ emailAndPassword: {
156
+ enabled: true,
157
+ disableSignUp: false,
158
+ requireEmailVerification: true,
159
+ minPasswordLength: 8,
160
+ maxPasswordLength: 128,
161
+ autoSignIn: true,
162
+ sendResetPassword: async ({ user, url }) => {
163
+ logger.info("sending reset password email", { email: user.email });
164
+ await sendEmail({
165
+ type: "resetPassword",
166
+ to: user.email,
167
+ username: user.name ?? user.email.split("@")[0],
168
+ resetLink: url
169
+ });
170
+ },
171
+ resetPasswordTokenExpiresIn: 3600
172
+ },
173
+ accountLinking: {
174
+ enabled: true,
175
+ // allow linking in general
176
+ trustedProviders: ["google", "github"]
177
+ // optional: auto‑link when Google verifies the e‑mail
178
+ },
179
+ emailVerification: {
180
+ autoSignInAfterVerification: true,
181
+ sendVerificationEmail: async ({ user, url }) => {
182
+ logger.info("sending verification email", { email: user.email });
183
+ await sendEmail({
184
+ type: "validate",
185
+ to: user.email,
186
+ username: user.name ?? user.email.split("@")[0],
187
+ validationLink: url
188
+ });
189
+ }
190
+ },
191
+ crossSubDomainCookies: {
192
+ enabled: true,
193
+ additionalCookies: ["session_token"],
194
+ domain: process.env.CLIENT_URL
195
+ },
196
+ cookiePrefix: "intlayer",
197
+ cookies: {
198
+ session_token: {
199
+ name: "session_token",
200
+ attributes: {
201
+ httpOnly: true,
202
+ secure: true
203
+ }
204
+ }
205
+ },
206
+ trustedOrigins: [process.env.CLIENT_URL],
207
+ socialProviders: {
208
+ google: {
209
+ clientId: process.env.GOOGLE_CLIENT_ID,
210
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET
211
+ },
212
+ github: {
213
+ clientId: process.env.GITHUB_CLIENT_ID,
214
+ clientSecret: process.env.GITHUB_CLIENT_SECRET
215
+ }
216
+ },
217
+ logger: {
218
+ log: (level, message, ...args) => logger[level](message, ...args)
219
+ }
220
+ });
221
+ return auth;
222
+ };
223
+ export {
224
+ formatSession,
225
+ getAuth
226
+ };
227
+ //# sourceMappingURL=getAuth.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/utils/auth/getAuth.ts"],"sourcesContent":["import type { OrganizationAPI } from '@/types/organization.types';\nimport type { ProjectAPI } from '@/types/project.types';\nimport type {\n SessionAPI,\n SessionContext,\n SessionDataApi,\n} from '@/types/session.types';\nimport type { User, UserAPI } from '@/types/user.types';\nimport { sendVerificationUpdate } from '@controllers/user.controller';\nimport { logger } from '@logger';\nimport { sendEmail } from '@services/email.service';\nimport { getOrganizationById } from '@services/organization.service';\nimport { getProjectById } from '@services/project.service';\nimport { getUserById } from '@services/user.service';\nimport { mapOrganizationToAPI } from '@utils/mapper/organization';\nimport { mapProjectToAPI } from '@utils/mapper/project';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport {\n computeEffectivePermission,\n getSessionRoles,\n intersectPermissions,\n} from '@utils/permissions';\nimport { betterAuth, OmitId } from 'better-auth';\nimport { mongodbAdapter } from 'better-auth/adapters/mongodb';\nimport { createAuthMiddleware } from 'better-auth/api';\nimport { customSession } from 'better-auth/plugins';\nimport type { MongoClient } from 'mongodb';\n\nexport type Auth = ReturnType<typeof betterAuth>;\n\nexport const formatSession = (session: SessionContext): OmitId<SessionAPI> => {\n const roles = getSessionRoles(session);\n let permissions = computeEffectivePermission(roles);\n\n // Intersect in the case a Access Token try to override the permissions\n if (session.permissions) {\n permissions = intersectPermissions(permissions, session.permissions);\n }\n\n const resultSession = {\n user: mapUserToAPI(session.user),\n organization: mapOrganizationToAPI(session.organization),\n project: mapProjectToAPI(session.project),\n authType: 'session',\n permissions,\n roles,\n } as OmitId<SessionAPI>;\n\n return resultSession;\n};\n\nexport const getAuth = (dbClient: MongoClient): Auth => {\n if (!dbClient) {\n throw new Error('MongoDB connection not established');\n }\n\n const auth = betterAuth({\n appName: 'Intlayer',\n\n database: mongodbAdapter(dbClient.db()),\n\n /**\n * User model\n */\n user: {\n modelName: 'users',\n },\n\n databaseHooks: {\n user: {\n create: {\n // Runs once, immediately after the INSERT\n after: async (user) => {\n if (!user?.emailVerified) return;\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name ?? user.email.split('@')[0],\n loginLink: `${process.env.CLIENT_URL}/auth/login`,\n locale: (user as any).lang,\n });\n logger.info('Welcome e‑mail delivered', {\n email: user.email,\n });\n },\n },\n },\n },\n\n hooks: {\n after: createAuthMiddleware(async (ctx) => {\n const { path, context } = ctx;\n\n const newUser = context.newSession?.user;\n const existingUser = context.session?.user;\n const user = newUser ?? existingUser;\n\n if (!user) return;\n\n if (['/verify-email'].includes(path)) {\n sendVerificationUpdate(user as unknown as User);\n logger.info('SSE verification update sent', {\n email: user.email,\n userId: user.id,\n });\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name ?? user.email.split('@')[0],\n loginLink: `${process.env.CLIENT_URL}/auth/login`,\n locale: (user as any).lang,\n });\n logger.info('Welcome e‑mail delivered', {\n email: user.email,\n });\n }\n }),\n },\n\n advanced: {\n // 1️⃣ Change or drop the global prefix\n // cookiePrefix: \"intlayer\", // => intlayer.session_token\n cookiePrefix: 'intlayer', // => session_token (no prefix)\n\n // 2️⃣ Override just the session‑token cookie\n cookies: {\n session_token: {\n // name: 'intlayer_session_token', // final name depends on the prefix above\n // attributes: { sameSite: \"lax\", maxAge: 60 * 60 * 24 } // optional\n },\n },\n\n // 3️⃣ (optional) turn off the automatic __Secure‑ prefix in non‑prod\n // useSecureCookies: false,\n },\n\n session: {\n modelName: 'sessions',\n id: 'id',\n\n additionalFields: {\n activeOrganizationId: { type: 'string', nullable: true, input: false },\n activeProjectId: { type: 'string', nullable: true, input: false },\n },\n },\n\n plugins: [\n customSession(async ({ session }) => {\n const typedSession = session as unknown as SessionDataApi;\n\n let userAPI: UserAPI | null = null;\n let organizationAPI: OrganizationAPI | null = null;\n let projectAPI: ProjectAPI | null = null;\n\n if (typedSession.userId) {\n const userData = await getUserById(typedSession.userId);\n\n if (userData) {\n userAPI = mapUserToAPI(userData);\n }\n }\n\n if (typedSession.activeOrganizationId) {\n const orgData = await getOrganizationById(\n typedSession.activeOrganizationId\n );\n\n if (orgData) {\n organizationAPI = mapOrganizationToAPI(orgData);\n }\n }\n if (typedSession.activeProjectId) {\n const projectData = await getProjectById(\n typedSession.activeProjectId\n );\n\n if (projectData) {\n projectAPI = mapProjectToAPI(projectData);\n }\n }\n\n const sessionWithNoPermission: SessionContext = {\n session: typedSession,\n user: userAPI!,\n organization: organizationAPI ?? null,\n project: projectAPI ?? null,\n authType: 'session',\n };\n\n return formatSession(sessionWithNoPermission);\n }),\n ],\n\n emailAndPassword: {\n enabled: true,\n disableSignUp: false,\n requireEmailVerification: true,\n minPasswordLength: 8,\n maxPasswordLength: 128,\n autoSignIn: true,\n sendResetPassword: async ({ user, url }) => {\n logger.info('sending reset password email', { email: user.email });\n await sendEmail({\n type: 'resetPassword',\n to: user.email,\n username: user.name ?? user.email.split('@')[0],\n resetLink: url,\n });\n },\n resetPasswordTokenExpiresIn: 3600,\n },\n accountLinking: {\n enabled: true, // allow linking in general\n trustedProviders: ['google', 'github'], // optional: auto‑link when Google verifies the e‑mail\n },\n emailVerification: {\n autoSignInAfterVerification: true,\n sendVerificationEmail: async ({ user, url }) => {\n logger.info('sending verification email', { email: user.email });\n await sendEmail({\n type: 'validate',\n to: user.email,\n username: user.name ?? user.email.split('@')[0],\n validationLink: url,\n });\n },\n },\n\n crossSubDomainCookies: {\n enabled: true,\n additionalCookies: ['session_token'],\n domain: process.env.CLIENT_URL as string,\n },\n cookiePrefix: 'intlayer',\n cookies: {\n session_token: {\n name: 'session_token',\n attributes: {\n httpOnly: true,\n secure: true,\n },\n },\n },\n\n trustedOrigins: [process.env.CLIENT_URL as string],\n\n socialProviders: {\n google: {\n clientId: process.env.GOOGLE_CLIENT_ID as string,\n clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,\n },\n github: {\n clientId: process.env.GITHUB_CLIENT_ID as string,\n clientSecret: process.env.GITHUB_CLIENT_SECRET as string,\n },\n },\n\n logger: {\n log: (level, message, ...args) => logger[level](message, ...args),\n },\n });\n\n return auth;\n};\n"],"mappings":"AAQA,SAAS,8BAA8B;AACvC,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AACpC,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAKvB,MAAM,gBAAgB,CAAC,YAAgD;AAC5E,QAAM,QAAQ,gBAAgB,OAAO;AACrC,MAAI,cAAc,2BAA2B,KAAK;AAGlD,MAAI,QAAQ,aAAa;AACvB,kBAAc,qBAAqB,aAAa,QAAQ,WAAW;AAAA,EACrE;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM,aAAa,QAAQ,IAAI;AAAA,IAC/B,cAAc,qBAAqB,QAAQ,YAAY;AAAA,IACvD,SAAS,gBAAgB,QAAQ,OAAO;AAAA,IACxC,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;AAEO,MAAM,UAAU,CAAC,aAAgC;AACtD,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,OAAO,WAAW;AAAA,IACtB,SAAS;AAAA,IAET,UAAU,eAAe,SAAS,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,IAKtC,MAAM;AAAA,MACJ,WAAW;AAAA,IACb;AAAA,IAEA,eAAe;AAAA,MACb,MAAM;AAAA,QACJ,QAAQ;AAAA;AAAA,UAEN,OAAO,OAAO,SAAS;AACrB,gBAAI,CAAC,MAAM,cAAe;AAE1B,kBAAM,UAAU;AAAA,cACd,MAAM;AAAA,cACN,IAAI,KAAK;AAAA,cACT,UAAU,KAAK,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,cAC9C,WAAW,GAAG,QAAQ,IAAI,UAAU;AAAA,cACpC,QAAS,KAAa;AAAA,YACxB,CAAC;AACD,mBAAO,KAAK,iCAA4B;AAAA,cACtC,OAAO,KAAK;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,OAAO,qBAAqB,OAAO,QAAQ;AACzC,cAAM,EAAE,MAAM,QAAQ,IAAI;AAE1B,cAAM,UAAU,QAAQ,YAAY;AACpC,cAAM,eAAe,QAAQ,SAAS;AACtC,cAAM,OAAO,WAAW;AAExB,YAAI,CAAC,KAAM;AAEX,YAAI,CAAC,eAAe,EAAE,SAAS,IAAI,GAAG;AACpC,iCAAuB,IAAuB;AAC9C,iBAAO,KAAK,gCAAgC;AAAA,YAC1C,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,UACf,CAAC;AAED,gBAAM,UAAU;AAAA,YACd,MAAM;AAAA,YACN,IAAI,KAAK;AAAA,YACT,UAAU,KAAK,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,YAC9C,WAAW,GAAG,QAAQ,IAAI,UAAU;AAAA,YACpC,QAAS,KAAa;AAAA,UACxB,CAAC;AACD,iBAAO,KAAK,iCAA4B;AAAA,YACtC,OAAO,KAAK;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,UAAU;AAAA;AAAA;AAAA,MAGR,cAAc;AAAA;AAAA;AAAA,MAGd,SAAS;AAAA,QACP,eAAe;AAAA;AAAA;AAAA,QAGf;AAAA,MACF;AAAA;AAAA;AAAA,IAIF;AAAA,IAEA,SAAS;AAAA,MACP,WAAW;AAAA,MACX,IAAI;AAAA,MAEJ,kBAAkB;AAAA,QAChB,sBAAsB,EAAE,MAAM,UAAU,UAAU,MAAM,OAAO,MAAM;AAAA,QACrE,iBAAiB,EAAE,MAAM,UAAU,UAAU,MAAM,OAAO,MAAM;AAAA,MAClE;AAAA,IACF;AAAA,IAEA,SAAS;AAAA,MACP,cAAc,OAAO,EAAE,QAAQ,MAAM;AACnC,cAAM,eAAe;AAErB,YAAI,UAA0B;AAC9B,YAAI,kBAA0C;AAC9C,YAAI,aAAgC;AAEpC,YAAI,aAAa,QAAQ;AACvB,gBAAM,WAAW,MAAM,YAAY,aAAa,MAAM;AAEtD,cAAI,UAAU;AACZ,sBAAU,aAAa,QAAQ;AAAA,UACjC;AAAA,QACF;AAEA,YAAI,aAAa,sBAAsB;AACrC,gBAAM,UAAU,MAAM;AAAA,YACpB,aAAa;AAAA,UACf;AAEA,cAAI,SAAS;AACX,8BAAkB,qBAAqB,OAAO;AAAA,UAChD;AAAA,QACF;AACA,YAAI,aAAa,iBAAiB;AAChC,gBAAM,cAAc,MAAM;AAAA,YACxB,aAAa;AAAA,UACf;AAEA,cAAI,aAAa;AACf,yBAAa,gBAAgB,WAAW;AAAA,UAC1C;AAAA,QACF;AAEA,cAAM,0BAA0C;AAAA,UAC9C,SAAS;AAAA,UACT,MAAM;AAAA,UACN,cAAc,mBAAmB;AAAA,UACjC,SAAS,cAAc;AAAA,UACvB,UAAU;AAAA,QACZ;AAEA,eAAO,cAAc,uBAAuB;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,IAEA,kBAAkB;AAAA,MAChB,SAAS;AAAA,MACT,eAAe;AAAA,MACf,0BAA0B;AAAA,MAC1B,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,YAAY;AAAA,MACZ,mBAAmB,OAAO,EAAE,MAAM,IAAI,MAAM;AAC1C,eAAO,KAAK,gCAAgC,EAAE,OAAO,KAAK,MAAM,CAAC;AACjE,cAAM,UAAU;AAAA,UACd,MAAM;AAAA,UACN,IAAI,KAAK;AAAA,UACT,UAAU,KAAK,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,UAC9C,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,MACA,6BAA6B;AAAA,IAC/B;AAAA,IACA,gBAAgB;AAAA,MACd,SAAS;AAAA;AAAA,MACT,kBAAkB,CAAC,UAAU,QAAQ;AAAA;AAAA,IACvC;AAAA,IACA,mBAAmB;AAAA,MACjB,6BAA6B;AAAA,MAC7B,uBAAuB,OAAO,EAAE,MAAM,IAAI,MAAM;AAC9C,eAAO,KAAK,8BAA8B,EAAE,OAAO,KAAK,MAAM,CAAC;AAC/D,cAAM,UAAU;AAAA,UACd,MAAM;AAAA,UACN,IAAI,KAAK;AAAA,UACT,UAAU,KAAK,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,UAC9C,gBAAgB;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,uBAAuB;AAAA,MACrB,SAAS;AAAA,MACT,mBAAmB,CAAC,eAAe;AAAA,MACnC,QAAQ,QAAQ,IAAI;AAAA,IACtB;AAAA,IACA,cAAc;AAAA,IACd,SAAS;AAAA,MACP,eAAe;AAAA,QACb,MAAM;AAAA,QACN,YAAY;AAAA,UACV,UAAU;AAAA,UACV,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IAEA,gBAAgB,CAAC,QAAQ,IAAI,UAAoB;AAAA,IAEjD,iBAAiB;AAAA,MACf,QAAQ;AAAA,QACN,UAAU,QAAQ,IAAI;AAAA,QACtB,cAAc,QAAQ,IAAI;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,QACN,UAAU,QAAQ,IAAI;AAAA,QACtB,cAAc,QAAQ,IAAI;AAAA,MAC5B;AAAA,IACF;AAAA,IAEA,QAAQ;AAAA,MACN,KAAK,CAAC,OAAO,YAAY,SAAS,OAAO,KAAK,EAAE,SAAS,GAAG,IAAI;AAAA,IAClE;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":[]}
@@ -0,0 +1,31 @@
1
+ import { logger } from "./../logger/index.mjs";
2
+ const whitelist = [process.env.CLIENT_URL];
3
+ const corsOptions = {
4
+ origin: (origin, callback) => {
5
+ if (!origin) return callback(null, true);
6
+ if (whitelist.includes(origin)) {
7
+ logger.info("whitelisted origin", origin);
8
+ return callback(null, true);
9
+ }
10
+ logger.info("non whitelisted origin", origin);
11
+ callback(null, origin);
12
+ },
13
+ allowedHeaders: [
14
+ "authorization",
15
+ "Content-Type",
16
+ "credentials",
17
+ "cache-control",
18
+ "Access-Control-Allow-Origin",
19
+ "private-state-token-redemption",
20
+ "private-state-token-issuance",
21
+ "browsing-topics"
22
+ ],
23
+ exposedHeaders: [""],
24
+ preflightContinue: false,
25
+ methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
26
+ credentials: true
27
+ };
28
+ export {
29
+ corsOptions
30
+ };
31
+ //# sourceMappingURL=cors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/cors.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { CorsOptions } from 'cors';\n\nconst whitelist = [process.env.CLIENT_URL!];\n\nexport const corsOptions: CorsOptions = {\n origin: (origin, callback) => {\n // Allow requests with no origin (like mobile apps or curl requests)\n if (!origin) return callback(null, true);\n\n if (whitelist.includes(origin)) {\n logger.info('whitelisted origin', origin);\n return callback(null, true);\n }\n\n logger.info('non whitelisted origin', origin);\n // Reflect the request's origin (echo back the origin header)\n callback(null, origin);\n },\n allowedHeaders: [\n 'authorization',\n 'Content-Type',\n 'credentials',\n 'cache-control',\n 'Access-Control-Allow-Origin',\n 'private-state-token-redemption',\n 'private-state-token-issuance',\n 'browsing-topics',\n ],\n exposedHeaders: [''],\n preflightContinue: false,\n methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n credentials: true,\n};\n"],"mappings":"AAAA,SAAS,cAAc;AAGvB,MAAM,YAAY,CAAC,QAAQ,IAAI,UAAW;AAEnC,MAAM,cAA2B;AAAA,EACtC,QAAQ,CAAC,QAAQ,aAAa;AAE5B,QAAI,CAAC,OAAQ,QAAO,SAAS,MAAM,IAAI;AAEvC,QAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,aAAO,KAAK,sBAAsB,MAAM;AACxC,aAAO,SAAS,MAAM,IAAI;AAAA,IAC5B;AAEA,WAAO,KAAK,0BAA0B,MAAM;AAE5C,aAAS,MAAM,MAAM;AAAA,EACvB;AAAA,EACA,gBAAgB;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB,CAAC,EAAE;AAAA,EACnB,mBAAmB;AAAA,EACnB,SAAS;AAAA,EACT,aAAa;AACf;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/ensureMongoDocumentToObject.ts"],"sourcesContent":["import type { Document } from 'mongoose';\n\n/**\n * If the dictionary is a mongoose document, convert it to an object\n * @param potentialDocument - The potential document to convert.\n * @returns The potential document converted to an object.\n */\nexport const ensureMongoDocumentToObject = <T extends object | Document>(\n potentialDocument: T\n): T => {\n let potentialObject: T = potentialDocument as T;\n\n // If the user is a mongoose document, convert it to an object\n if (typeof (potentialDocument as Document).toObject === 'function') {\n potentialObject = (potentialDocument as Document).toObject();\n }\n\n return potentialObject as T;\n};\n"],"mappings":"AAOO,MAAM,8BAA8B,CACzC,sBACM;AACN,MAAI,kBAAqB;AAGzB,MAAI,OAAQ,kBAA+B,aAAa,YAAY;AAClE,sBAAmB,kBAA+B,SAAS;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/ensureMongoDocumentToObject.ts"],"sourcesContent":["import type { Document, ObjectIdToString } from 'mongoose';\n\n/**\n * If the dictionary is a mongoose document, convert it to an object\n * @param potentialDocument - The potential document to convert.\n * @returns The potential document converted to an object.\n */\nexport const ensureMongoDocumentToObject = <T extends object | Document>(\n potentialDocument: T\n): ObjectIdToString<T> => {\n let potentialObject: T = potentialDocument as T;\n\n // If the user is a mongoose document, convert it to an object\n if (typeof (potentialDocument as Document).toObject === 'function') {\n potentialObject = (potentialDocument as Document).toObject();\n }\n\n return potentialObject as ObjectIdToString<T>;\n};\n"],"mappings":"AAOO,MAAM,8BAA8B,CACzC,sBACwB;AACxB,MAAI,kBAAqB;AAGzB,MAAI,OAAQ,kBAA+B,aAAa,YAAY;AAClE,sBAAmB,kBAA+B,SAAS;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
@@ -1,9 +1,9 @@
1
1
  import { Locales } from "@intlayer/config";
2
2
  import { logger } from "./../../logger/index.mjs";
3
3
  import { formatPaginatedResponse, formatResponse } from "./../../utils/responseData.mjs";
4
+ import { HttpStatusCodes } from "./../../export.mjs";
4
5
  import { t } from "express-intlayer";
5
6
  import { errorData } from "./errorCodes.mjs";
6
- import { HttpStatusCodes } from "./../../export.mjs";
7
7
  class ErrorHandler {
8
8
  /**
9
9
  * Handles generic error responses by formatting and sending a JSON response.
@@ -49,7 +49,7 @@ class ErrorHandler {
49
49
  res,
50
50
  error.errorKey,
51
51
  isMultilingual ? error.multilingualTitle : error.title,
52
- isMultilingual ? error.multilingualMessage : error.multilingualMessage,
52
+ isMultilingual ? error.multilingualMessage : error.message,
53
53
  error.messageDetails ?? messageDetails,
54
54
  error.httpStatusCode,
55
55
  isPaginatedResponse
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/errors/ErrorHandler.ts"],"sourcesContent":["// Import required modules and types from their respective locations.\nimport { Locales } from '@intlayer/config';\nimport { logger } from '@logger';\nimport { formatPaginatedResponse, formatResponse } from '@utils/responseData';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport type { LanguageContent } from 'express-intlayer';\nimport { t } from 'express-intlayer';\nimport { type ErrorCodes, errorData } from './errorCodes';\nimport type { AppError } from './ErrorsClass';\nimport { type UserAPI, HttpStatusCodes } from '@/export';\n\n// Define a class named 'ErrorHandler' to encapsulate error handling logic.\nexport class ErrorHandler {\n /**\n * Handles generic error responses by formatting and sending a JSON response.\n * @param res - The response object provided by Express.js.\n * @param errorKey - A key representing the specific error.\n * @param statusCode - (Optional) A specific HTTP status code to use for the response.\n * @param isPaginatedResponse - Flag to determine if the response should be paginated.\n */\n static handleGenericErrorResponse(\n res: Response,\n errorKey: ErrorCodes,\n errorDetails?: object,\n statusCode?: HttpStatusCodes,\n isPaginatedResponse: boolean = false\n ) {\n const error = errorData[errorKey];\n const status = statusCode ?? error.statusCode; // Use the provided status code or default to the one in errorData.\n\n // Delegate to a more customizable error response handler.\n this.handleCustomErrorResponse(\n res,\n errorKey,\n error.title,\n error.message,\n errorDetails,\n status,\n isPaginatedResponse\n );\n }\n\n /**\n * Handles application-specific error responses by formatting and sending a JSON response.\n * @param res - The response object provided by Express.js.\n * @param error - The error object.\n * @param messageDetails - (Optional) Additional message details to include in the response.\n * @param isPaginatedResponse - (Optional) Flag to determine if the response should be paginated.\n */\n static handleAppErrorResponse(\n res: Response,\n error: AppError,\n messageDetails?: object,\n isPaginatedResponse: boolean = false\n ) {\n if (!error.isAppError) {\n this.handleCustomErrorResponse(\n res,\n error.errorKey ?? 'UNKNOWN_ERROR',\n 'Error',\n error.message ?? JSON.stringify(error),\n undefined,\n error.httpStatusCode ?? HttpStatusCodes.INTERNAL_SERVER_ERROR_500,\n isPaginatedResponse\n );\n }\n\n const isMultilingual = error.isMultilingual ?? false;\n // Delegate to a more customizable error response handler.\n this.handleCustomErrorResponse(\n res,\n error.errorKey,\n isMultilingual ? error.multilingualTitle : error.title,\n isMultilingual ? error.multilingualMessage : error.multilingualMessage,\n error.messageDetails ?? messageDetails,\n error.httpStatusCode,\n isPaginatedResponse\n );\n }\n\n /**\n * Handles more customizable error responses with detailed error messages and codes.\n * @param res - The response object.\n * @param errorKey - Error code key used to fetch the corresponding message and default status.\n * @param message - The localized error message object.\n * @param messageDetails - (Optional) Additional message details to include in the response.\n * @param statusCode - (Optional) HTTP status code, defaults to 500 if not specified.\n * @param isPaginatedResponse - Determines if the error should be part of a paginated response.\n */\n static handleCustomErrorResponse<T>(\n res: Response,\n errorKey: ErrorCodes | string,\n title: LanguageContent<string> | string,\n message: LanguageContent<string> | string,\n messageDetails?: object,\n statusCode?: HttpStatusCodes,\n isPaginatedResponse: boolean = false\n ) {\n const errorTitle = t(title as LanguageContent<string>, Locales.ENGLISH);\n const errorMessage = t(message as LanguageContent<string>, Locales.ENGLISH);\n logger.error(errorMessage, messageDetails); // Log the English version of the error message.\n const status = statusCode ?? HttpStatusCodes.INTERNAL_SERVER_ERROR_500; // Default to 500 if no status code is provided.\n\n if (isPaginatedResponse) {\n // Format the response as a paginated error response if requested.\n const responseData = formatPaginatedResponse<T>({\n error: {\n code: errorKey,\n title: errorTitle,\n message: errorMessage,\n },\n status,\n });\n res.status(status).json(responseData);\n return;\n }\n\n // Format the response as a standard non-paginated error response.\n const responseData = formatResponse<UserAPI>({\n error: {\n code: errorKey,\n title: errorTitle,\n message: errorMessage,\n ...messageDetails,\n },\n status,\n });\n\n res.status(status).json(responseData);\n }\n}\n"],"mappings":"AACA,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,yBAAyB,sBAAsB;AAIxD,SAAS,SAAS;AAClB,SAA0B,iBAAiB;AAE3C,SAAuB,uBAAuB;AAGvC,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxB,OAAO,2BACL,KACA,UACA,cACA,YACA,sBAA+B,OAC/B;AACA,UAAM,QAAQ,UAAU,QAAQ;AAChC,UAAM,SAAS,cAAc,MAAM;AAGnC,SAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,uBACL,KACA,OACA,gBACA,sBAA+B,OAC/B;AACA,QAAI,CAAC,MAAM,YAAY;AACrB,WAAK;AAAA,QACH;AAAA,QACA,MAAM,YAAY;AAAA,QAClB;AAAA,QACA,MAAM,WAAW,KAAK,UAAU,KAAK;AAAA,QACrC;AAAA,QACA,MAAM,kBAAkB,gBAAgB;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM,kBAAkB;AAE/C,SAAK;AAAA,MACH;AAAA,MACA,MAAM;AAAA,MACN,iBAAiB,MAAM,oBAAoB,MAAM;AAAA,MACjD,iBAAiB,MAAM,sBAAsB,MAAM;AAAA,MACnD,MAAM,kBAAkB;AAAA,MACxB,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,0BACL,KACA,UACA,OACA,SACA,gBACA,YACA,sBAA+B,OAC/B;AACA,UAAM,aAAa,EAAE,OAAkC,QAAQ,OAAO;AACtE,UAAM,eAAe,EAAE,SAAoC,QAAQ,OAAO;AAC1E,WAAO,MAAM,cAAc,cAAc;AACzC,UAAM,SAAS,cAAc,gBAAgB;AAE7C,QAAI,qBAAqB;AAEvB,YAAMA,gBAAe,wBAA2B;AAAA,QAC9C,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,MACF,CAAC;AACD,UAAI,OAAO,MAAM,EAAE,KAAKA,aAAY;AACpC;AAAA,IACF;AAGA,UAAM,eAAe,eAAwB;AAAA,MAC3C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,QACT,GAAG;AAAA,MACL;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,OAAO,MAAM,EAAE,KAAK,YAAY;AAAA,EACtC;AACF;","names":["responseData"]}
1
+ {"version":3,"sources":["../../../../src/utils/errors/ErrorHandler.ts"],"sourcesContent":["// Import required modules and types from their respective locations.\nimport { Locales } from '@intlayer/config';\nimport { logger } from '@logger';\nimport { formatPaginatedResponse, formatResponse } from '@utils/responseData';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport { type UserAPI, HttpStatusCodes } from '@/export';\nimport type { LanguageContent } from 'express-intlayer';\nimport { t } from 'express-intlayer';\nimport { type ErrorCodes, errorData } from './errorCodes';\nimport type { AppError } from './ErrorsClass';\n\n// Define a class named 'ErrorHandler' to encapsulate error handling logic.\nexport class ErrorHandler {\n /**\n * Handles generic error responses by formatting and sending a JSON response.\n * @param res - The response object provided by Express.js.\n * @param errorKey - A key representing the specific error.\n * @param statusCode - (Optional) A specific HTTP status code to use for the response.\n * @param isPaginatedResponse - Flag to determine if the response should be paginated.\n */\n static handleGenericErrorResponse(\n res: Response,\n errorKey: ErrorCodes,\n errorDetails?: object,\n statusCode?: HttpStatusCodes,\n isPaginatedResponse: boolean = false\n ) {\n const error = errorData[errorKey];\n const status = statusCode ?? error.statusCode; // Use the provided status code or default to the one in errorData.\n\n // Delegate to a more customizable error response handler.\n this.handleCustomErrorResponse(\n res,\n errorKey,\n error.title,\n error.message,\n errorDetails,\n status,\n isPaginatedResponse\n );\n }\n\n /**\n * Handles application-specific error responses by formatting and sending a JSON response.\n * @param res - The response object provided by Express.js.\n * @param error - The error object.\n * @param messageDetails - (Optional) Additional message details to include in the response.\n * @param isPaginatedResponse - (Optional) Flag to determine if the response should be paginated.\n */\n static handleAppErrorResponse(\n res: Response,\n error: AppError,\n messageDetails?: object,\n isPaginatedResponse: boolean = false\n ) {\n if (!error.isAppError) {\n this.handleCustomErrorResponse(\n res,\n error.errorKey ?? 'UNKNOWN_ERROR',\n 'Error',\n error.message ?? JSON.stringify(error),\n undefined,\n error.httpStatusCode ?? HttpStatusCodes.INTERNAL_SERVER_ERROR_500,\n isPaginatedResponse\n );\n }\n\n const isMultilingual = error.isMultilingual ?? false;\n // Delegate to a more customizable error response handler.\n this.handleCustomErrorResponse(\n res,\n error.errorKey,\n isMultilingual ? error.multilingualTitle : error.title,\n isMultilingual ? error.multilingualMessage : error.message,\n error.messageDetails ?? messageDetails,\n error.httpStatusCode,\n isPaginatedResponse\n );\n }\n\n /**\n * Handles more customizable error responses with detailed error messages and codes.\n * @param res - The response object.\n * @param errorKey - Error code key used to fetch the corresponding message and default status.\n * @param message - The localized error message object.\n * @param messageDetails - (Optional) Additional message details to include in the response.\n * @param statusCode - (Optional) HTTP status code, defaults to 500 if not specified.\n * @param isPaginatedResponse - Determines if the error should be part of a paginated response.\n */\n static handleCustomErrorResponse<T>(\n res: Response,\n errorKey: ErrorCodes | string,\n title: LanguageContent<string> | string,\n message: LanguageContent<string> | string,\n messageDetails?: object,\n statusCode?: HttpStatusCodes,\n isPaginatedResponse: boolean = false\n ) {\n const errorTitle = t(title as LanguageContent<string>, Locales.ENGLISH);\n const errorMessage = t(message as LanguageContent<string>, Locales.ENGLISH);\n logger.error(errorMessage, messageDetails); // Log the English version of the error message.\n const status = statusCode ?? HttpStatusCodes.INTERNAL_SERVER_ERROR_500; // Default to 500 if no status code is provided.\n\n if (isPaginatedResponse) {\n // Format the response as a paginated error response if requested.\n const responseData = formatPaginatedResponse<T>({\n error: {\n code: errorKey,\n title: errorTitle,\n message: errorMessage,\n },\n status,\n });\n res.status(status).json(responseData);\n return;\n }\n\n // Format the response as a standard non-paginated error response.\n const responseData = formatResponse<UserAPI>({\n error: {\n code: errorKey,\n title: errorTitle,\n message: errorMessage,\n ...messageDetails,\n },\n status,\n });\n\n res.status(status).json(responseData);\n }\n}\n"],"mappings":"AACA,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,yBAAyB,sBAAsB;AAGxD,SAAuB,uBAAuB;AAE9C,SAAS,SAAS;AAClB,SAA0B,iBAAiB;AAIpC,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxB,OAAO,2BACL,KACA,UACA,cACA,YACA,sBAA+B,OAC/B;AACA,UAAM,QAAQ,UAAU,QAAQ;AAChC,UAAM,SAAS,cAAc,MAAM;AAGnC,SAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,uBACL,KACA,OACA,gBACA,sBAA+B,OAC/B;AACA,QAAI,CAAC,MAAM,YAAY;AACrB,WAAK;AAAA,QACH;AAAA,QACA,MAAM,YAAY;AAAA,QAClB;AAAA,QACA,MAAM,WAAW,KAAK,UAAU,KAAK;AAAA,QACrC;AAAA,QACA,MAAM,kBAAkB,gBAAgB;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM,kBAAkB;AAE/C,SAAK;AAAA,MACH;AAAA,MACA,MAAM;AAAA,MACN,iBAAiB,MAAM,oBAAoB,MAAM;AAAA,MACjD,iBAAiB,MAAM,sBAAsB,MAAM;AAAA,MACnD,MAAM,kBAAkB;AAAA,MACxB,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,0BACL,KACA,UACA,OACA,SACA,gBACA,YACA,sBAA+B,OAC/B;AACA,UAAM,aAAa,EAAE,OAAkC,QAAQ,OAAO;AACtE,UAAM,eAAe,EAAE,SAAoC,QAAQ,OAAO;AAC1E,WAAO,MAAM,cAAc,cAAc;AACzC,UAAM,SAAS,cAAc,gBAAgB;AAE7C,QAAI,qBAAqB;AAEvB,YAAMA,gBAAe,wBAA2B;AAAA,QAC9C,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,QACA;AAAA,MACF,CAAC;AACD,UAAI,OAAO,MAAM,EAAE,KAAKA,aAAY;AACpC;AAAA,IACF;AAGA,UAAM,eAAe,eAAwB;AAAA,MAC3C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,QACT,GAAG;AAAA,MACL;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,OAAO,MAAM,EAAE,KAAK,YAAY;AAAA,EACtC;AACF;","names":["responseData"]}