@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
@@ -23,7 +23,6 @@ __export(organization_service_exports, {
23
23
  deleteOrganizationById: () => deleteOrganizationById,
24
24
  findOrganizations: () => findOrganizations,
25
25
  getOrganizationById: () => getOrganizationById,
26
- getOrganizationsByOwner: () => getOrganizationsByOwner,
27
26
  updateOrganizationById: () => updateOrganizationById,
28
27
  updatePlan: () => updatePlan
29
28
  });
@@ -31,9 +30,7 @@ module.exports = __toCommonJS(organization_service_exports);
31
30
  var import_organization = require('./../models/organization.model.cjs');
32
31
  var import_errors = require('./../utils/errors/index.cjs');
33
32
  var import_validateOrganization = require('./../utils/validation/validateOrganization.cjs');
34
- const findOrganizations = async (filters, skip, limit) => {
35
- return await import_organization.OrganizationModel.find(filters).skip(skip).limit(limit);
36
- };
33
+ const findOrganizations = async (filters, skip, limit) => await import_organization.OrganizationModel.find(filters).skip(skip).limit(limit);
37
34
  const getOrganizationById = async (organizationId) => {
38
35
  const organization = await import_organization.OrganizationModel.findById(organizationId);
39
36
  if (!organization) {
@@ -41,12 +38,6 @@ const getOrganizationById = async (organizationId) => {
41
38
  }
42
39
  return organization;
43
40
  };
44
- const getOrganizationsByOwner = async (userId) => {
45
- const organization = await import_organization.OrganizationModel.find({
46
- creatorId: userId
47
- });
48
- return organization;
49
- };
50
41
  const countOrganizations = async (filters) => {
51
42
  const result = await import_organization.OrganizationModel.countDocuments(filters);
52
43
  if (typeof result === "undefined") {
@@ -60,6 +51,14 @@ const createOrganization = async (organization, userId) => {
60
51
  throw new import_errors.GenericError("ORGANIZATION_INVALID_FIELDS", { errors });
61
52
  }
62
53
  try {
54
+ console.log({
55
+ organization: {
56
+ creatorId: userId,
57
+ membersIds: [userId],
58
+ adminsIds: [userId],
59
+ ...organization
60
+ }
61
+ });
63
62
  const result = await import_organization.OrganizationModel.create({
64
63
  creatorId: userId,
65
64
  membersIds: [userId],
@@ -68,7 +67,10 @@ const createOrganization = async (organization, userId) => {
68
67
  });
69
68
  return result;
70
69
  } catch (error) {
71
- throw new import_errors.GenericError("ORGANIZATION_CREATION_FAILED", { error });
70
+ console.error("Organization creation failed:", error);
71
+ throw new import_errors.GenericError("ORGANIZATION_CREATION_FAILED", {
72
+ error: error.message
73
+ });
72
74
  }
73
75
  };
74
76
  const updateOrganizationById = async (organizationId, organization) => {
@@ -102,16 +104,16 @@ const updatePlan = async (organization, plan) => {
102
104
  prevPlan = prevPlan.toObject();
103
105
  }
104
106
  const updateOrganizationResult = await import_organization.OrganizationModel.updateOne(
105
- { _id: organization._id },
107
+ { _id: organization.id },
106
108
  { $set: { plan: { ...prevPlan, ...plan } } },
107
109
  { new: true }
108
110
  );
109
111
  if (updateOrganizationResult.matchedCount === 0) {
110
112
  throw new import_errors.GenericError("ORGANIZATION_UPDATE_FAILED", {
111
- organizationId: organization._id
113
+ organizationId: organization.id
112
114
  });
113
115
  }
114
- const updatedOrganization = await getOrganizationById(organization._id);
116
+ const updatedOrganization = await getOrganizationById(organization.id);
115
117
  return updatedOrganization;
116
118
  };
117
119
  // Annotate the CommonJS export names for ESM import in node:
@@ -121,7 +123,6 @@ const updatePlan = async (organization, plan) => {
121
123
  deleteOrganizationById,
122
124
  findOrganizations,
123
125
  getOrganizationById,
124
- getOrganizationsByOwner,
125
126
  updateOrganizationById,
126
127
  updatePlan
127
128
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/organization.service.ts"],"sourcesContent":["import { OrganizationModel } from '@models/organization.model';\nimport { GenericError } from '@utils/errors';\nimport type { OrganizationFilters } from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport {\n type OrganizationFields,\n validateOrganization,\n} from '@utils/validation/validateOrganization';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Organization,\n OrganizationCreationData,\n OrganizationDocument,\n} from '@/types/organization.types';\nimport type { Plan, PlanDocument } from '@/types/plan.types';\n\n/**\n * Finds organizations based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of organizations matching the filters.\n */\nexport const findOrganizations = async (\n filters: OrganizationFilters,\n skip: number,\n limit: number\n): Promise<OrganizationDocument[]> => {\n return await OrganizationModel.find(filters).skip(skip).limit(limit);\n};\n\n/**\n * Finds an organization by its ID.\n * @param organizationId - The ID of the organization to find.\n * @returns The organization matching the ID.\n */\nexport const getOrganizationById = async (\n organizationId: ObjectId | string\n): Promise<OrganizationDocument> => {\n const organization = await OrganizationModel.findById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', { organizationId });\n }\n\n return organization;\n};\n\n/**\n * Retrieves an organization by its owner.\n * @param userId - The ID of the user to find the organization.\n * @returns The organizations matching the user ID.\n */\nexport const getOrganizationsByOwner = async (\n userId: string | ObjectId\n): Promise<OrganizationDocument[] | null> => {\n const organization = await OrganizationModel.find({\n creatorId: userId,\n });\n\n return organization;\n};\n\n/**\n * Counts the total number of organizations that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of organizations.\n */\nexport const countOrganizations = async (\n filters: OrganizationFilters\n): Promise<number> => {\n const result = await OrganizationModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('ORGANIZATION_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new organization in the database.\n * @param organization - The organization data to create.\n * @returns The created organization.\n */\nexport const createOrganization = async (\n organization: OrganizationCreationData,\n userId: string | ObjectId\n): Promise<OrganizationDocument> => {\n const errors = validateOrganization(organization, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('ORGANIZATION_INVALID_FIELDS', { errors });\n }\n\n try {\n const result = await OrganizationModel.create({\n creatorId: userId,\n membersIds: [userId],\n adminsIds: [userId],\n ...organization,\n });\n\n return result;\n } catch (error) {\n throw new GenericError('ORGANIZATION_CREATION_FAILED', { error });\n }\n};\n\n/**\n * Updates an existing organization in the database by its ID.\n * @param organizationId - The ID of the organization to update.\n * @param organization - The updated organization data.\n * @returns The updated organization.\n */\nexport const updateOrganizationById = async (\n organizationId: ObjectId | string,\n organization: Partial<Organization>\n): Promise<OrganizationDocument> => {\n const updatedKeys = Object.keys(organization) as OrganizationFields;\n const errors = validateOrganization(organization, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('ORGANIZATION_INVALID_FIELDS', {\n organizationId,\n errors,\n });\n }\n\n const result = await OrganizationModel.updateOne(\n { _id: organizationId },\n organization\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', { organizationId });\n }\n\n return await getOrganizationById(organizationId);\n};\n\n/**\n * Deletes an organization from the database by its ID.\n * @param organizationId - The ID of the organization to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteOrganizationById = async (\n organizationId: ObjectId | string\n): Promise<OrganizationDocument> => {\n const organization =\n await OrganizationModel.findByIdAndDelete(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', { organizationId });\n }\n\n return organization;\n};\n\n/**\n * Updates an existing plan in the database by its ID.\n * @param planId - The ID of the plan to update.\n * @param plan - The updated plan data.\n * @returns The updated plan.\n */\nexport const updatePlan = async (\n organization: Organization | OrganizationDocument,\n plan: Partial<Plan>\n): Promise<OrganizationDocument | null> => {\n let prevPlan = organization.plan ?? {};\n\n if (typeof (prevPlan as PlanDocument)?.toObject === 'function') {\n prevPlan = (prevPlan as PlanDocument).toObject();\n }\n\n const updateOrganizationResult = await OrganizationModel.updateOne(\n { _id: organization._id },\n { $set: { plan: { ...prevPlan, ...plan } } },\n { new: true }\n );\n\n if (updateOrganizationResult.matchedCount === 0) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n const updatedOrganization = await getOrganizationById(organization._id);\n\n return updatedOrganization;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/services/organization.service.ts"],"sourcesContent":["import type {\n Organization,\n OrganizationCreationData,\n OrganizationDocument,\n} from '@/types/organization.types';\nimport type { Plan, PlanDocument } from '@/types/plan.types';\nimport { OrganizationModel } from '@models/organization.model';\nimport { GenericError } from '@utils/errors';\nimport type { OrganizationFilters } from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport {\n type OrganizationFields,\n validateOrganization,\n} from '@utils/validation/validateOrganization';\nimport type { Types } from 'mongoose';\n\n/**\n * Finds organizations based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of organizations matching the filters.\n */\nexport const findOrganizations = async (\n filters: OrganizationFilters,\n skip: number,\n limit: number\n): Promise<OrganizationDocument[]> =>\n await OrganizationModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds an organization by its ID.\n * @param organizationId - The ID of the organization to find.\n * @returns The organization matching the ID.\n */\nexport const getOrganizationById = async (\n organizationId: string | Types.ObjectId\n): Promise<OrganizationDocument> => {\n const organization = await OrganizationModel.findById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', { organizationId });\n }\n\n return organization;\n};\n\n/**\n * Counts the total number of organizations that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of organizations.\n */\nexport const countOrganizations = async (\n filters: OrganizationFilters\n): Promise<number> => {\n const result = await OrganizationModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('ORGANIZATION_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new organization in the database.\n * @param organization - The organization data to create.\n * @returns The created organization.\n */\nexport const createOrganization = async (\n organization: OrganizationCreationData,\n userId: string | Types.ObjectId\n): Promise<OrganizationDocument> => {\n const errors = validateOrganization(organization, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('ORGANIZATION_INVALID_FIELDS', { errors });\n }\n\n try {\n console.log({\n organization: {\n creatorId: userId,\n membersIds: [userId],\n adminsIds: [userId],\n ...organization,\n },\n });\n\n const result = await OrganizationModel.create({\n creatorId: userId,\n membersIds: [userId],\n adminsIds: [userId],\n ...organization,\n });\n\n return result;\n } catch (error) {\n console.error('Organization creation failed:', error);\n throw new GenericError('ORGANIZATION_CREATION_FAILED', {\n error: (error as Error).message,\n });\n }\n};\n\n/**\n * Updates an existing organization in the database by its ID.\n * @param organizationId - The ID of the organization to update.\n * @param organization - The updated organization data.\n * @returns The updated organization.\n */\nexport const updateOrganizationById = async (\n organizationId: string | Types.ObjectId,\n organization: Partial<Organization>\n): Promise<OrganizationDocument> => {\n const updatedKeys = Object.keys(organization) as OrganizationFields;\n const errors = validateOrganization(organization, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('ORGANIZATION_INVALID_FIELDS', {\n organizationId,\n errors,\n });\n }\n\n const result = await OrganizationModel.updateOne(\n { _id: organizationId },\n organization\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', { organizationId });\n }\n\n return await getOrganizationById(organizationId);\n};\n\n/**\n * Deletes an organization from the database by its ID.\n * @param organizationId - The ID of the organization to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteOrganizationById = async (\n organizationId: string | Types.ObjectId\n): Promise<OrganizationDocument> => {\n const organization =\n await OrganizationModel.findByIdAndDelete(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', { organizationId });\n }\n\n return organization;\n};\n\n/**\n * Updates an existing plan in the database by its ID.\n * @param planId - The ID of the plan to update.\n * @param plan - The updated plan data.\n * @returns The updated plan.\n */\nexport const updatePlan = async (\n organization: Organization | OrganizationDocument,\n plan: Partial<Plan>\n): Promise<OrganizationDocument | null> => {\n let prevPlan = organization.plan ?? {};\n\n if (typeof (prevPlan as PlanDocument)?.toObject === 'function') {\n prevPlan = (prevPlan as PlanDocument).toObject();\n }\n\n const updateOrganizationResult = await OrganizationModel.updateOne(\n { _id: organization.id },\n { $set: { plan: { ...prevPlan, ...plan } } },\n { new: true }\n );\n\n if (updateOrganizationResult.matchedCount === 0) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization.id,\n });\n }\n\n const updatedOrganization = await getOrganizationById(organization.id);\n\n return updatedOrganization;\n};\n"],"mappings":"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","names":[]}
@@ -59,7 +59,7 @@ const createProject = async (project) => {
59
59
  const updateProjectById = async (projectId, project) => {
60
60
  const projectObject = (0, import_ensureMongoDocumentToObject.ensureMongoDocumentToObject)(project);
61
61
  const projectToUpdate = (0, import_removeObjectKeys.removeObjectKeys)(projectObject, [
62
- "_id",
62
+ "id",
63
63
  "oAuth2Access",
64
64
  "organizationId"
65
65
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/project.service.ts"],"sourcesContent":["import { ProjectModel } from '@models/project.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { ProjectFilters } from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type ProjectFields,\n validateProject,\n} from '@utils/validation/validateProject';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Project,\n ProjectData,\n ProjectDocument,\n} from '@/types/project.types';\n\n/**\n * Finds projects based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of projects matching the filters.\n */\nexport const findProjects = async (\n filters: ProjectFilters,\n skip = 0,\n limit = 100\n): Promise<ProjectDocument[]> =>\n await ProjectModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a project by its ID.\n * @param projectId - The ID of the project to find.\n * @returns The project matching the ID.\n */\nexport const getProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findById(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n\n/**\n * Counts the total number of projects that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of projects.\n */\nexport const countProjects = async (\n filters: ProjectFilters\n): Promise<number> => {\n const result = await ProjectModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('PROJECT_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new project in the database.\n * @param project - The project data to create.\n * @returns The created project.\n */\nexport const createProject = async (\n project: ProjectData\n): Promise<ProjectDocument> => {\n if ((project as Partial<Project>).oAuth2Access) {\n delete (project as Partial<Project>).oAuth2Access;\n }\n\n const errors = await validateProject(project, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', { errors });\n }\n\n return await ProjectModel.create(project);\n};\n\n/**\n * Updates an existing project in the database by its ID.\n * @param projectId - The ID of the project to update.\n * @param project - The updated project data.\n * @returns The updated project.\n */\nexport const updateProjectById = async (\n projectId: string | ObjectId,\n project: Partial<Project>\n): Promise<ProjectDocument> => {\n const projectObject = ensureMongoDocumentToObject(project);\n const projectToUpdate = removeObjectKeys(projectObject, [\n '_id',\n 'oAuth2Access',\n 'organizationId',\n ]);\n\n const updatedKeys = Object.keys(projectToUpdate) as ProjectFields;\n\n const errors = validateProject(project, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', {\n projectId,\n errors,\n });\n }\n\n const result = await ProjectModel.updateOne(\n { _id: projectId },\n projectToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('PROJECT_UPDATE_FAILED', { projectId });\n }\n\n return await getProjectById(projectId);\n};\n\n/**\n * Deletes a project from the database by its ID.\n * @param projectId - The ID of the project to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findByIdAndDelete(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA6B;AAC7B,yCAA4C;AAC5C,oBAA6B;AAE7B,8BAAiC;AACjC,6BAGO;AAeA,MAAM,eAAe,OAC1B,SACA,OAAO,GACP,QAAQ,QAER,MAAM,4BAAa,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAOlD,MAAM,iBAAiB,OAC5B,cAC6B;AAC7B,QAAM,UAAU,MAAM,4BAAa,SAAS,SAAS;AAErD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,2BAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YACoB;AACpB,QAAM,SAAS,MAAM,4BAAa,eAAe,OAAO;AAExD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,2BAAa,wBAAwB,EAAE,QAAQ,CAAC;AAAA,EAC5D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YAC6B;AAC7B,MAAK,QAA6B,cAAc;AAC9C,WAAQ,QAA6B;AAAA,EACvC;AAEA,QAAM,SAAS,UAAM,wCAAgB,SAAS,CAAC,MAAM,CAAC;AAEtD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,0BAA0B,EAAE,OAAO,CAAC;AAAA,EAC7D;AAEA,SAAO,MAAM,4BAAa,OAAO,OAAO;AAC1C;AAQO,MAAM,oBAAoB,OAC/B,WACA,YAC6B;AAC7B,QAAM,oBAAgB,gEAA4B,OAAO;AACzD,QAAM,sBAAkB,0CAAiB,eAAe;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,KAAK,eAAe;AAE/C,QAAM,aAAS,wCAAgB,SAAS,WAAW;AAEnD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,4BAAa;AAAA,IAChC,EAAE,KAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,2BAAa,yBAAyB,EAAE,UAAU,CAAC;AAAA,EAC/D;AAEA,SAAO,MAAM,eAAe,SAAS;AACvC;AAOO,MAAM,oBAAoB,OAC/B,cAC6B;AAC7B,QAAM,UAAU,MAAM,4BAAa,kBAAkB,SAAS;AAE9D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,2BAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/services/project.service.ts"],"sourcesContent":["import type {\n Project,\n ProjectData,\n ProjectDocument,\n} from '@/types/project.types';\nimport { ProjectModel } from '@models/project.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { ProjectFilters } from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type ProjectFields,\n validateProject,\n} from '@utils/validation/validateProject';\nimport type { Types } from 'mongoose';\n\n/**\n * Finds projects based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of projects matching the filters.\n */\nexport const findProjects = async (\n filters: ProjectFilters,\n skip = 0,\n limit = 100\n): Promise<ProjectDocument[]> =>\n await ProjectModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a project by its ID.\n * @param projectId - The ID of the project to find.\n * @returns The project matching the ID.\n */\nexport const getProjectById = async (\n projectId: string | Types.ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findById(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n\n/**\n * Counts the total number of projects that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of projects.\n */\nexport const countProjects = async (\n filters: ProjectFilters\n): Promise<number> => {\n const result = await ProjectModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('PROJECT_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new project in the database.\n * @param project - The project data to create.\n * @returns The created project.\n */\nexport const createProject = async (\n project: ProjectData\n): Promise<ProjectDocument> => {\n if ((project as Partial<Project>).oAuth2Access) {\n delete (project as Partial<Project>).oAuth2Access;\n }\n\n const errors = await validateProject(project, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', { errors });\n }\n\n return await ProjectModel.create(project);\n};\n\n/**\n * Updates an existing project in the database by its ID.\n * @param projectId - The ID of the project to update.\n * @param project - The updated project data.\n * @returns The updated project.\n */\nexport const updateProjectById = async (\n projectId: string | Types.ObjectId,\n project: Partial<Project>\n): Promise<ProjectDocument> => {\n const projectObject = ensureMongoDocumentToObject(project);\n const projectToUpdate = removeObjectKeys(projectObject, [\n 'id',\n 'oAuth2Access',\n 'organizationId',\n ]);\n\n const updatedKeys = Object.keys(projectToUpdate) as ProjectFields;\n\n const errors = validateProject(project, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', {\n projectId,\n errors,\n });\n }\n\n const result = await ProjectModel.updateOne(\n { _id: projectId },\n projectToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('PROJECT_UPDATE_FAILED', { projectId });\n }\n\n return await getProjectById(projectId);\n};\n\n/**\n * Deletes a project from the database by its ID.\n * @param projectId - The ID of the project to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteProjectById = async (\n projectId: string | Types.ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findByIdAndDelete(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,qBAA6B;AAC7B,yCAA4C;AAC5C,oBAA6B;AAE7B,8BAAiC;AACjC,6BAGO;AAUA,MAAM,eAAe,OAC1B,SACA,OAAO,GACP,QAAQ,QAER,MAAM,4BAAa,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAOlD,MAAM,iBAAiB,OAC5B,cAC6B;AAC7B,QAAM,UAAU,MAAM,4BAAa,SAAS,SAAS;AAErD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,2BAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YACoB;AACpB,QAAM,SAAS,MAAM,4BAAa,eAAe,OAAO;AAExD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,2BAAa,wBAAwB,EAAE,QAAQ,CAAC;AAAA,EAC5D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YAC6B;AAC7B,MAAK,QAA6B,cAAc;AAC9C,WAAQ,QAA6B;AAAA,EACvC;AAEA,QAAM,SAAS,UAAM,wCAAgB,SAAS,CAAC,MAAM,CAAC;AAEtD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,0BAA0B,EAAE,OAAO,CAAC;AAAA,EAC7D;AAEA,SAAO,MAAM,4BAAa,OAAO,OAAO;AAC1C;AAQO,MAAM,oBAAoB,OAC/B,WACA,YAC6B;AAC7B,QAAM,oBAAgB,gEAA4B,OAAO;AACzD,QAAM,sBAAkB,0CAAiB,eAAe;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,KAAK,eAAe;AAE/C,QAAM,aAAS,wCAAgB,SAAS,WAAW;AAEnD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,4BAAa;AAAA,IAChC,EAAE,KAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,2BAAa,yBAAyB,EAAE,UAAU,CAAC;AAAA,EAC/D;AAEA,SAAO,MAAM,eAAe,SAAS;AACvC;AAOO,MAAM,oBAAoB,OAC/B,cAC6B;AAC7B,QAAM,UAAU,MAAM,4BAAa,kBAAkB,SAAS;AAE9D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,2BAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
@@ -25,22 +25,23 @@ __export(projectAccessKey_service_exports, {
25
25
  module.exports = __toCommonJS(projectAccessKey_service_exports);
26
26
  var import_project = require('./../models/project.model.cjs');
27
27
  var import_errors = require('./../utils/errors/index.cjs');
28
- var import_oAuth2 = require('./oAuth2.service.cjs');
28
+ var import_crypto = require("crypto");
29
29
  var import_project2 = require('./project.service.cjs');
30
- const addNewAccessKey = async (accessKeyData, projectId, user, organizationRights, projectRights, dictionaryRights) => {
31
- const { clientId, clientSecret } = (0, import_oAuth2.generateClientCredentials)();
30
+ const generateClientCredentials = () => ({
31
+ clientId: (0, import_crypto.randomBytes)(16).toString("hex"),
32
+ // 32 character hexadecimal string
33
+ clientSecret: (0, import_crypto.randomBytes)(32).toString("hex")
34
+ // 64 character hexadecimal string
35
+ });
36
+ const addNewAccessKey = async (accessKeyData, projectId, user) => {
37
+ const { clientId, clientSecret } = generateClientCredentials();
32
38
  const newAccessKey = {
33
39
  ...accessKeyData,
34
40
  clientId,
35
41
  clientSecret,
36
- userId: user._id,
42
+ userId: user.id,
37
43
  accessToken: [],
38
- rights: restrictAccessKeyRights(
39
- accessKeyData,
40
- organizationRights,
41
- projectRights,
42
- dictionaryRights
43
- )
44
+ grants: accessKeyData.grants
44
45
  };
45
46
  const result = await import_project.ProjectModel.updateOne(
46
47
  { _id: projectId },
@@ -50,7 +51,7 @@ const addNewAccessKey = async (accessKeyData, projectId, user, organizationRight
50
51
  throw new import_errors.GenericError("ACCESS_KEY_CREATION_FAILED", {
51
52
  accessKeyData,
52
53
  projectId,
53
- userId: user._id
54
+ userId: user.id
54
55
  });
55
56
  }
56
57
  const updatedProject = await (0, import_project2.getProjectById)(projectId);
@@ -61,7 +62,7 @@ const addNewAccessKey = async (accessKeyData, projectId, user, organizationRight
61
62
  throw new import_errors.GenericError("ACCESS_KEY_CREATION_FAILED", {
62
63
  accessKeyData,
63
64
  projectId,
64
- userId: user._id
65
+ userId: user.id
65
66
  });
66
67
  }
67
68
  return newAccessKeyId;
@@ -73,7 +74,7 @@ const deleteAccessKey = async (clientId, project, userId) => {
73
74
  if (!projectAccess) {
74
75
  throw new import_errors.GenericError("ACCESS_KEY_NOT_FOUND", {
75
76
  clientId,
76
- projectId: project._id
77
+ projectId: project.id
77
78
  });
78
79
  }
79
80
  const result = await import_project.ProjectModel.updateOne(
@@ -86,7 +87,7 @@ const deleteAccessKey = async (clientId, project, userId) => {
86
87
  if (result.modifiedCount === 0) {
87
88
  throw new import_errors.GenericError("ACCESS_KEY_DELETION_FAILED", {
88
89
  clientId,
89
- projectId: project._id
90
+ projectId: project.id
90
91
  });
91
92
  }
92
93
  return projectAccess;
@@ -110,10 +111,10 @@ const refreshAccessKey = async (clientId, projectId, userId) => {
110
111
  if (!projectAccess) {
111
112
  throw new import_errors.GenericError("ACCESS_KEY_NOT_FOUND", {
112
113
  clientId,
113
- projectId: project._id
114
+ projectId: project.id
114
115
  });
115
116
  }
116
- const { clientSecret } = (0, import_oAuth2.generateClientCredentials)();
117
+ const { clientSecret } = generateClientCredentials();
117
118
  const result = await import_project.ProjectModel.updateOne(
118
119
  {
119
120
  "oAuth2Access.clientId": clientId,
@@ -145,23 +146,6 @@ const refreshAccessKey = async (clientId, projectId, userId) => {
145
146
  }
146
147
  return newAccessKeyId;
147
148
  };
148
- const restrictRights = (givenRights, userRights) => {
149
- const restrictedRights = {};
150
- for (const key in givenRights) {
151
- if (Object.prototype.hasOwnProperty.call(givenRights, key)) {
152
- restrictedRights[key] = givenRights[key] && userRights[key];
153
- }
154
- }
155
- return restrictedRights;
156
- };
157
- const restrictAccessKeyRights = (accessKey, organizationsRights, projectRights, dictionaryRights) => ({
158
- dictionary: restrictRights(accessKey.rights.dictionary, dictionaryRights),
159
- project: restrictRights(accessKey.rights.project, projectRights),
160
- organization: restrictRights(
161
- accessKey.rights.organization,
162
- organizationsRights
163
- )
164
- });
165
149
  // Annotate the CommonJS export names for ESM import in node:
166
150
  0 && (module.exports = {
167
151
  addNewAccessKey,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/projectAccessKey.service.ts"],"sourcesContent":["import { ProjectModel } from '@models/project.model';\nimport { GenericError } from '@utils/errors';\nimport type { ObjectId } from 'mongoose';\nimport { generateClientCredentials } from './oAuth2.service';\nimport { getProjectById } from './project.service';\nimport type {\n AccessKeyData,\n OAuth2Access,\n OAuth2AccessData,\n Project,\n Rights,\n TokenRights,\n} from '@/types/project.types';\nimport type { User } from '@/types/user.types';\n\n/**\n * Adds a new access key to a project.\n *\n * @param accessKeyData - The access key data.\n * @param projectId - The ID of the project to add the access key to.\n * @param user - The user adding the access key.\n * @returns The new access key.\n *\n */\nexport const addNewAccessKey = async (\n accessKeyData: AccessKeyData,\n projectId: string | ObjectId,\n user: User,\n organizationRights: Rights,\n projectRights: Rights,\n dictionaryRights: Rights\n): Promise<OAuth2Access> => {\n const { clientId, clientSecret } = generateClientCredentials();\n\n const newAccessKey: OAuth2AccessData = {\n ...accessKeyData,\n clientId,\n clientSecret,\n userId: user._id,\n accessToken: [],\n rights: restrictAccessKeyRights(\n accessKeyData,\n organizationRights,\n projectRights,\n dictionaryRights\n ),\n };\n\n const result = await ProjectModel.updateOne(\n { _id: projectId },\n { $push: { oAuth2Access: newAccessKey } }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData,\n projectId,\n userId: user._id,\n });\n }\n\n const updatedProject = await getProjectById(projectId);\n\n const newAccessKeyId = updatedProject.oAuth2Access.find(\n (access) => access.clientId === clientId\n );\n\n if (!newAccessKeyId) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData,\n projectId,\n userId: user._id,\n });\n }\n\n return newAccessKeyId;\n};\n\nexport const deleteAccessKey = async (\n clientId: string | ObjectId,\n project: Project,\n userId: string | ObjectId\n) => {\n const projectAccess = project.oAuth2Access.find(\n (access) =>\n access.clientId === clientId && String(access.userId) === String(userId)\n );\n\n if (!projectAccess) {\n throw new GenericError('ACCESS_KEY_NOT_FOUND', {\n clientId,\n projectId: project._id,\n });\n }\n\n const result = await ProjectModel.updateOne(\n {\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n },\n { $pull: { oAuth2Access: { clientId } } }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_DELETION_FAILED', {\n clientId,\n projectId: project._id,\n });\n }\n\n return projectAccess;\n};\n\nexport const refreshAccessKey = async (\n clientId: string | ObjectId,\n projectId: string | ObjectId,\n userId: string | ObjectId\n): Promise<OAuth2Access> => {\n const project = await ProjectModel.findOne({\n _id: projectId,\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n });\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_FOUND', {\n clientId,\n projectId,\n userId,\n });\n }\n\n const projectAccess = project.oAuth2Access.find(\n (access) => access.clientId === clientId\n );\n\n if (!projectAccess) {\n throw new GenericError('ACCESS_KEY_NOT_FOUND', {\n clientId,\n projectId: project._id,\n });\n }\n\n const { clientSecret } = generateClientCredentials();\n\n const result = await ProjectModel.updateOne(\n {\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n },\n {\n $set: {\n 'oAuth2Access.$.clientId': projectAccess.clientId,\n 'oAuth2Access.$.clientSecret': clientSecret,\n },\n }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_UPDATE_FAILED', {\n clientId,\n projectId,\n });\n }\n\n const updatedProject = await getProjectById(projectId);\n\n const newAccessKeyId = updatedProject.oAuth2Access.find(\n (access) => access.clientId === projectAccess.clientId\n );\n\n if (!newAccessKeyId) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData: updatedProject.oAuth2Access,\n projectId,\n userId,\n });\n }\n\n return newAccessKeyId;\n};\n\nconst restrictRights = (givenRights: Rights, userRights: Rights): Rights => {\n const restrictedRights: Rights = {} as Rights;\n\n for (const key in givenRights) {\n if (Object.prototype.hasOwnProperty.call(givenRights, key)) {\n restrictedRights[key as keyof Rights] =\n givenRights[key as keyof Rights] && userRights[key as keyof Rights];\n }\n }\n\n return restrictedRights;\n};\n\nconst restrictAccessKeyRights = (\n accessKey: AccessKeyData,\n organizationsRights: Rights,\n projectRights: Rights,\n dictionaryRights: Rights\n): TokenRights => ({\n dictionary: restrictRights(accessKey.rights.dictionary, dictionaryRights),\n project: restrictRights(accessKey.rights.project, projectRights),\n organization: restrictRights(\n accessKey.rights.organization,\n organizationsRights\n ),\n});\n"],"mappings":"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","names":["import_project"]}
1
+ {"version":3,"sources":["../../../src/services/projectAccessKey.service.ts"],"sourcesContent":["import type {\n AccessKeyData,\n OAuth2Access,\n OAuth2AccessData,\n Project,\n} from '@/types/project.types';\nimport type { User } from '@/types/user.types';\nimport { ProjectModel } from '@models/project.model';\nimport { GenericError } from '@utils/errors';\nimport { randomBytes } from 'crypto';\nimport type { Types } from 'mongoose';\nimport { getProjectById } from './project.service';\n\n/**\n * Generates cryptographically secure OAuth2 client credentials\n *\n * @returns Object containing clientId and clientSecret\n *\n * Security improvements:\n * - clientId: 32 characters (128 bits of entropy)\n * - clientSecret: 64 characters (256 bits of entropy)\n * - Uses crypto.randomBytes for cryptographically secure random generation\n * - Follows OAuth2 best practices for credential strength\n */\nconst generateClientCredentials = () => ({\n clientId: randomBytes(16).toString('hex'), // 32 character hexadecimal string\n clientSecret: randomBytes(32).toString('hex'), // 64 character hexadecimal string\n});\n\n/**\n * Adds a new access key to a project.\n *\n * @param accessKeyData - The access key data.\n * @param projectId - The ID of the project to add the access key to.\n * @param user - The user adding the access key.\n * @returns The new access key.\n *\n */\nexport const addNewAccessKey = async (\n accessKeyData: AccessKeyData,\n projectId: string | Types.ObjectId,\n user: User\n): Promise<OAuth2Access> => {\n const { clientId, clientSecret } = generateClientCredentials();\n\n const newAccessKey: OAuth2AccessData = {\n ...accessKeyData,\n clientId,\n clientSecret,\n userId: user.id,\n accessToken: [],\n grants: accessKeyData.grants,\n };\n\n const result = await ProjectModel.updateOne(\n { _id: projectId },\n { $push: { oAuth2Access: newAccessKey } }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData,\n projectId,\n userId: user.id,\n });\n }\n\n const updatedProject = await getProjectById(projectId);\n\n const newAccessKeyId = updatedProject.oAuth2Access.find(\n (access) => access.clientId === clientId\n );\n\n if (!newAccessKeyId) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData,\n projectId,\n userId: user.id,\n });\n }\n\n return newAccessKeyId;\n};\n\nexport const deleteAccessKey = async (\n clientId: string | Types.ObjectId,\n project: Project,\n userId: string | Types.ObjectId\n) => {\n const projectAccess = project.oAuth2Access.find(\n (access) =>\n access.clientId === clientId && String(access.userId) === String(userId)\n );\n\n if (!projectAccess) {\n throw new GenericError('ACCESS_KEY_NOT_FOUND', {\n clientId,\n projectId: project.id,\n });\n }\n\n const result = await ProjectModel.updateOne(\n {\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n },\n { $pull: { oAuth2Access: { clientId } } }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_DELETION_FAILED', {\n clientId,\n projectId: project.id,\n });\n }\n\n return projectAccess;\n};\n\nexport const refreshAccessKey = async (\n clientId: string | Types.ObjectId,\n projectId: string | Types.ObjectId,\n userId: string | Types.ObjectId\n): Promise<OAuth2Access> => {\n const project = await ProjectModel.findOne({\n _id: projectId,\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n });\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_FOUND', {\n clientId,\n projectId,\n userId,\n });\n }\n\n const projectAccess = project.oAuth2Access.find(\n (access) => access.clientId === clientId\n );\n\n if (!projectAccess) {\n throw new GenericError('ACCESS_KEY_NOT_FOUND', {\n clientId,\n projectId: project.id,\n });\n }\n\n const { clientSecret } = generateClientCredentials();\n\n const result = await ProjectModel.updateOne(\n {\n 'oAuth2Access.clientId': clientId,\n 'oAuth2Access.userId': String(userId),\n },\n {\n $set: {\n 'oAuth2Access.$.clientId': projectAccess.clientId,\n 'oAuth2Access.$.clientSecret': clientSecret,\n },\n }\n );\n\n if (result.modifiedCount === 0) {\n throw new GenericError('ACCESS_KEY_UPDATE_FAILED', {\n clientId,\n projectId,\n });\n }\n\n const updatedProject = await getProjectById(projectId);\n\n const newAccessKeyId = updatedProject.oAuth2Access.find(\n (access) => access.clientId === projectAccess.clientId\n );\n\n if (!newAccessKeyId) {\n throw new GenericError('ACCESS_KEY_CREATION_FAILED', {\n accessKeyData: updatedProject.oAuth2Access,\n projectId,\n userId,\n });\n }\n\n return newAccessKeyId;\n};\n"],"mappings":"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","names":["import_project"]}
@@ -50,7 +50,7 @@ const addOrUpdateSubscription = async (subscriptionId, priceId, customerId, user
50
50
  userId
51
51
  });
52
52
  }
53
- if (user.customerId !== customerId) {
53
+ if (String(user.customerId) !== customerId) {
54
54
  user.customerId = customerId;
55
55
  await user.save();
56
56
  }
@@ -69,7 +69,7 @@ const addOrUpdateSubscription = async (subscriptionId, priceId, customerId, user
69
69
  }
70
70
  }
71
71
  const updatedOrganization = await (0, import_organization.updatePlan)(organization, {
72
- creatorId: user._id,
72
+ creatorId: user.id,
73
73
  priceId,
74
74
  customerId,
75
75
  subscriptionId,
@@ -79,11 +79,11 @@ const addOrUpdateSubscription = async (subscriptionId, priceId, customerId, user
79
79
  });
80
80
  if (!updatedOrganization) {
81
81
  throw new import_errors.GenericError("ORGANIZATION_UPDATE_FAILED", {
82
- organizationId: organization._id
82
+ organizationId: organization.id
83
83
  });
84
84
  }
85
85
  import_logger.logger.info(
86
- `Plan updated for organization ${organization._id} - ${planInfo.type} - ${planInfo.period}`
86
+ `Plan updated for organization ${organization.id} - ${planInfo.type} - ${planInfo.period}`
87
87
  );
88
88
  return updatedOrganization.plan ?? null;
89
89
  };
@@ -100,7 +100,7 @@ const cancelSubscription = async (subscriptionId, organizationId) => {
100
100
  if (!organization.plan) {
101
101
  throw new import_errors.GenericError("ORGANIZATION_PLAN_NOT_FOUND", {
102
102
  subscriptionId,
103
- organizationId: organization._id
103
+ organizationId: organization.id
104
104
  });
105
105
  }
106
106
  const updatedOrganization = await (0, import_organization.updatePlan)(organization, {
@@ -108,11 +108,11 @@ const cancelSubscription = async (subscriptionId, organizationId) => {
108
108
  });
109
109
  if (!updatedOrganization) {
110
110
  throw new import_errors.GenericError("ORGANIZATION_UPDATE_FAILED", {
111
- organizationId: organization._id
111
+ organizationId: organization.id
112
112
  });
113
113
  }
114
114
  import_logger.logger.info(
115
- `Cancelled plan for organization ${updatedOrganization._id} - ${updatedOrganization.plan?.type} - ${updatedOrganization.plan?.period}`
115
+ `Cancelled plan for organization ${updatedOrganization.id} - ${updatedOrganization.plan?.type} - ${updatedOrganization.plan?.period}`
116
116
  );
117
117
  return updatedOrganization.plan ?? null;
118
118
  };
@@ -128,7 +128,7 @@ const changeSubscriptionStatus = async (subscriptionId, status, userId, organiza
128
128
  throw new import_errors.GenericError("ORGANIZATION_PLAN_NOT_FOUND", {
129
129
  userId,
130
130
  subscriptionId,
131
- organizationId: organization._id
131
+ organizationId: organization.id
132
132
  });
133
133
  }
134
134
  const updatedOrganization = await (0, import_organization.updatePlan)(organization, {
@@ -137,7 +137,7 @@ const changeSubscriptionStatus = async (subscriptionId, status, userId, organiza
137
137
  });
138
138
  if (!updatedOrganization) {
139
139
  throw new import_errors.GenericError("ORGANIZATION_UPDATE_FAILED", {
140
- organizationId: organization._id
140
+ organizationId: organization.id
141
141
  });
142
142
  }
143
143
  const user = await (0, import_user.getUserById)(userId);
@@ -148,7 +148,7 @@ const changeSubscriptionStatus = async (subscriptionId, status, userId, organiza
148
148
  });
149
149
  }
150
150
  import_logger.logger.info(
151
- `Updated plan status for organization ${organization._id} - Status: ${status}`
151
+ `Updated plan status for organization ${organization.id} - Status: ${status}`
152
152
  );
153
153
  const emailData = {
154
154
  to: user.email,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/subscription.service.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { GenericError } from '@utils/errors';\nimport { retrievePlanInformation } from '@utils/plan';\nimport Stripe from 'stripe';\nimport { sendEmail } from './email.service';\nimport { getOrganizationById, updatePlan } from './organization.service';\nimport { getUserById } from './user.service';\nimport type { Organization } from '@/types/organization.types';\nimport type { Plan } from '@/types/plan.types';\n\nexport const addOrUpdateSubscription = async (\n subscriptionId: string,\n priceId: string,\n customerId: string,\n userId: string,\n organization: Organization,\n status: Plan['status']\n): Promise<Plan | null> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n });\n }\n\n if (user.customerId !== customerId) {\n user.customerId = customerId;\n await user.save();\n }\n\n const planInfo = retrievePlanInformation(priceId);\n\n const subscriptions = await stripe.subscriptions.list({\n customer: customerId,\n status: 'active',\n limit: 1,\n });\n\n if (subscriptions.data.length >= 1) {\n // Active subscription exists; update it to the new plan\n const otherSubscriptionArray = subscriptions.data.filter(\n (subscription) => subscription.id !== subscriptionId\n );\n\n for (const subscription of otherSubscriptionArray) {\n await stripe.subscriptions.cancel(subscription.id);\n }\n }\n\n const updatedOrganization = await updatePlan(organization, {\n creatorId: user._id,\n priceId,\n customerId,\n subscriptionId,\n type: planInfo.type,\n period: planInfo.period,\n status,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n logger.info(\n `Plan updated for organization ${organization._id} - ${planInfo.type} - ${planInfo.period}`\n );\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const cancelSubscription = async (\n subscriptionId: string | Organization['_id'],\n organizationId: Organization['_id'] | string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n subscriptionId,\n });\n }\n\n if (!subscriptionId) {\n throw new GenericError('NO_SUBSCRIPTION_ID_PROVIDED');\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n subscriptionId,\n organizationId: organization._id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status: 'canceled',\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n logger.info(\n `Cancelled plan for organization ${updatedOrganization._id} - ${updatedOrganization.plan?.type} - ${updatedOrganization.plan?.period}`\n );\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const changeSubscriptionStatus = async (\n subscriptionId: string,\n status: Plan['status'],\n userId: string,\n organizationId: string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n userId,\n subscriptionId,\n organizationId: organization._id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status,\n subscriptionId,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization._id,\n });\n }\n\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n logger.info(\n `Updated plan status for organization ${organization._id} - Status: ${status}`\n );\n\n const emailData = {\n to: user.email,\n username: user.name,\n email: user.email,\n planName: organization.plan.type,\n date: new Date().toLocaleDateString(),\n link: `${process.env.CLIENT_URL}/dashboard`,\n };\n\n switch (status) {\n case 'active':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentSuccess',\n organizationName: organization.name,\n subscriptionStartDate: emailData.date,\n manageSubscriptionLink: emailData.link,\n });\n break;\n case 'canceled':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentCancellation',\n organizationName: organization.name,\n cancellationDate: emailData.date,\n reactivateLink: emailData.link,\n });\n break;\n case 'incomplete':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentError',\n organizationName: organization.name,\n errorDate: emailData.date,\n retryPaymentLink: emailData.link,\n });\n break;\n default:\n logger.warn(`Unhandled subscription status: ${status}`);\n }\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const getCouponId = async (\n promoCode: string\n): Promise<string | null> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\n try {\n // Retrieve the coupon details by name\n const coupons = await stripe.coupons.list();\n const matchingCoupon = coupons.data.find(\n (coupon) => coupon.name === promoCode\n );\n\n return matchingCoupon ? matchingCoupon.id : null;\n } catch (error) {\n console.error('Error retrieving coupon:', error);\n return null;\n }\n};\n\nexport type PricingResult = Record<\n string,\n {\n originalTotal: number;\n discountApplied: number;\n discountType: 'amount' | 'percentage' | null;\n finalTotal: number;\n currency: string;\n }\n>;\n\nexport const getPricing = async (\n priceIds: string[],\n promoCode?: string\n): Promise<PricingResult> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\n try {\n // 1. Fetch all price objects\n const pricePromises = priceIds.map((priceId) =>\n stripe.prices.retrieve(priceId)\n );\n const prices = await Promise.all(pricePromises);\n\n // Calculate the total amount before discount (to help with proportional distribution if needed)\n const totalAmount = prices.reduce(\n (sum, price) => sum + (price.unit_amount ?? 0),\n 0\n );\n\n // 2. Retrieve the discount (if promo code is provided)\n let discountAmount = 0;\n let discountType: 'amount' | 'percentage' | null = null;\n\n if (promoCode) {\n const coupons = await stripe.coupons.list();\n const matchingCoupons = coupons.data.find(\n (coupon) => coupon.name === promoCode\n );\n if (matchingCoupons) {\n if (matchingCoupons.amount_off) {\n discountAmount = matchingCoupons.amount_off;\n discountType = 'amount';\n } else if (matchingCoupons.percent_off) {\n // For a percentage discount, we won't store discountAmount as a raw number\n // because each price line is discounted individually by the same percentage.\n discountAmount = matchingCoupons.percent_off;\n discountType = 'percentage';\n }\n }\n }\n\n // 3. Build the result for each priceId\n const results: PricingResult = {};\n\n for (const price of prices) {\n if (!price.id || !price.unit_amount) {\n continue; // Skip any invalid price\n }\n\n const originalTotal = price.unit_amount;\n let appliedDiscount = 0;\n let finalTotal = originalTotal;\n\n // Apply discount based on the discount type\n if (discountType === 'percentage' && discountAmount > 0) {\n // percentage-based discount\n appliedDiscount = (originalTotal * discountAmount) / 100;\n finalTotal = originalTotal - appliedDiscount;\n } else if (\n discountType === 'amount' &&\n totalAmount > 0 &&\n discountAmount > 0\n ) {\n // fixed amount discount - distribute proportionally\n const proportion = originalTotal / totalAmount;\n appliedDiscount = discountAmount * proportion;\n finalTotal = originalTotal - appliedDiscount;\n }\n\n // Prevent final total from going negative due to rounding\n finalTotal = Math.max(finalTotal, 0);\n\n results[price.id] = {\n originalTotal: originalTotal,\n discountApplied: appliedDiscount,\n discountType,\n finalTotal: finalTotal,\n currency: price.currency,\n };\n }\n\n return results;\n } catch (error) {\n console.error('Error calculating pricing per priceId:', error);\n throw new Error('Failed to calculate pricing breakdown.');\n }\n};\n"],"mappings":"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","names":["Stripe"]}
1
+ {"version":3,"sources":["../../../src/services/subscription.service.ts"],"sourcesContent":["import type { Organization } from '@/types/organization.types';\nimport type { Plan } from '@/types/plan.types';\nimport { logger } from '@logger';\nimport { GenericError } from '@utils/errors';\nimport { retrievePlanInformation } from '@utils/plan';\nimport Stripe from 'stripe';\nimport { sendEmail } from './email.service';\nimport { getOrganizationById, updatePlan } from './organization.service';\nimport { getUserById } from './user.service';\n\nexport const addOrUpdateSubscription = async (\n subscriptionId: string,\n priceId: string,\n customerId: string,\n userId: string,\n organization: Organization,\n status: Plan['status']\n): Promise<Plan | null> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n });\n }\n\n if (String(user.customerId) !== customerId) {\n (user.customerId as unknown as string) = customerId;\n await user.save();\n }\n\n const planInfo = retrievePlanInformation(priceId);\n\n const subscriptions = await stripe.subscriptions.list({\n customer: customerId,\n status: 'active',\n limit: 1,\n });\n\n if (subscriptions.data.length >= 1) {\n // Active subscription exists; update it to the new plan\n const otherSubscriptionArray = subscriptions.data.filter(\n (subscription) => subscription.id !== subscriptionId\n );\n\n for (const subscription of otherSubscriptionArray) {\n await stripe.subscriptions.cancel(subscription.id);\n }\n }\n\n const updatedOrganization = await updatePlan(organization, {\n creatorId: user.id,\n priceId,\n customerId,\n subscriptionId,\n type: planInfo.type,\n period: planInfo.period,\n status,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization.id,\n });\n }\n\n logger.info(\n `Plan updated for organization ${organization.id} - ${planInfo.type} - ${planInfo.period}`\n );\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const cancelSubscription = async (\n subscriptionId: string | Organization['id'],\n organizationId: Organization['id'] | string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n subscriptionId,\n });\n }\n\n if (!subscriptionId) {\n throw new GenericError('NO_SUBSCRIPTION_ID_PROVIDED');\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n subscriptionId,\n organizationId: organization.id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status: 'canceled',\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization.id,\n });\n }\n\n logger.info(\n `Cancelled plan for organization ${updatedOrganization.id} - ${updatedOrganization.plan?.type} - ${updatedOrganization.plan?.period}`\n );\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const changeSubscriptionStatus = async (\n subscriptionId: string,\n status: Plan['status'],\n userId: string,\n organizationId: string\n): Promise<Plan | null> => {\n const organization = await getOrganizationById(organizationId);\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n if (!organization.plan) {\n throw new GenericError('ORGANIZATION_PLAN_NOT_FOUND', {\n userId,\n subscriptionId,\n organizationId: organization.id,\n });\n }\n\n const updatedOrganization = await updatePlan(organization, {\n status,\n subscriptionId,\n });\n\n if (!updatedOrganization) {\n throw new GenericError('ORGANIZATION_UPDATE_FAILED', {\n organizationId: organization.id,\n });\n }\n\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n userId,\n subscriptionId,\n });\n }\n\n logger.info(\n `Updated plan status for organization ${organization.id} - Status: ${status}`\n );\n\n const emailData = {\n to: user.email,\n username: user.name,\n email: user.email,\n planName: organization.plan.type,\n date: new Date().toLocaleDateString(),\n link: `${process.env.CLIENT_URL}/dashboard`,\n };\n\n switch (status) {\n case 'active':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentSuccess',\n organizationName: organization.name,\n subscriptionStartDate: emailData.date,\n manageSubscriptionLink: emailData.link,\n });\n break;\n case 'canceled':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentCancellation',\n organizationName: organization.name,\n cancellationDate: emailData.date,\n reactivateLink: emailData.link,\n });\n break;\n case 'incomplete':\n await sendEmail({\n ...emailData,\n type: 'subscriptionPaymentError',\n organizationName: organization.name,\n errorDate: emailData.date,\n retryPaymentLink: emailData.link,\n });\n break;\n default:\n logger.warn(`Unhandled subscription status: ${status}`);\n }\n\n return updatedOrganization.plan ?? null;\n};\n\nexport const getCouponId = async (\n promoCode: string\n): Promise<string | null> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\n try {\n // Retrieve the coupon details by name\n const coupons = await stripe.coupons.list();\n const matchingCoupon = coupons.data.find(\n (coupon) => coupon.name === promoCode\n );\n\n return matchingCoupon ? matchingCoupon.id : null;\n } catch (error) {\n console.error('Error retrieving coupon:', error);\n return null;\n }\n};\n\nexport type PricingResult = Record<\n string,\n {\n originalTotal: number;\n discountApplied: number;\n discountType: 'amount' | 'percentage' | null;\n finalTotal: number;\n currency: string;\n }\n>;\n\nexport const getPricing = async (\n priceIds: string[],\n promoCode?: string\n): Promise<PricingResult> => {\n const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);\n\n try {\n // 1. Fetch all price objects\n const pricePromises = priceIds.map((priceId) =>\n stripe.prices.retrieve(priceId)\n );\n const prices = await Promise.all(pricePromises);\n\n // Calculate the total amount before discount (to help with proportional distribution if needed)\n const totalAmount = prices.reduce(\n (sum, price) => sum + (price.unit_amount ?? 0),\n 0\n );\n\n // 2. Retrieve the discount (if promo code is provided)\n let discountAmount = 0;\n let discountType: 'amount' | 'percentage' | null = null;\n\n if (promoCode) {\n const coupons = await stripe.coupons.list();\n const matchingCoupons = coupons.data.find(\n (coupon) => coupon.name === promoCode\n );\n if (matchingCoupons) {\n if (matchingCoupons.amount_off) {\n discountAmount = matchingCoupons.amount_off;\n discountType = 'amount';\n } else if (matchingCoupons.percent_off) {\n // For a percentage discount, we won't store discountAmount as a raw number\n // because each price line is discounted individually by the same percentage.\n discountAmount = matchingCoupons.percent_off;\n discountType = 'percentage';\n }\n }\n }\n\n // 3. Build the result for each priceId\n const results: PricingResult = {};\n\n for (const price of prices) {\n if (!price.id || !price.unit_amount) {\n continue; // Skip any invalid price\n }\n\n const originalTotal = price.unit_amount;\n let appliedDiscount = 0;\n let finalTotal = originalTotal;\n\n // Apply discount based on the discount type\n if (discountType === 'percentage' && discountAmount > 0) {\n // percentage-based discount\n appliedDiscount = (originalTotal * discountAmount) / 100;\n finalTotal = originalTotal - appliedDiscount;\n } else if (\n discountType === 'amount' &&\n totalAmount > 0 &&\n discountAmount > 0\n ) {\n // fixed amount discount - distribute proportionally\n const proportion = originalTotal / totalAmount;\n appliedDiscount = discountAmount * proportion;\n finalTotal = originalTotal - appliedDiscount;\n }\n\n // Prevent final total from going negative due to rounding\n finalTotal = Math.max(finalTotal, 0);\n\n results[price.id] = {\n originalTotal: originalTotal,\n discountApplied: appliedDiscount,\n discountType,\n finalTotal: finalTotal,\n currency: price.currency,\n };\n }\n\n return results;\n } catch (error) {\n console.error('Error calculating pricing per priceId:', error);\n throw new Error('Failed to calculate pricing breakdown.');\n }\n};\n"],"mappings":"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","names":["Stripe"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/tag.service.ts"],"sourcesContent":["import { TagModel } from '@models/tag.model';\nimport { GenericError } from '@utils/errors';\nimport type { TagFilters } from '@utils/filtersAndPagination/getTagFiltersAndPagination';\nimport { type TagFields, validateTag } from '@utils/validation/validateTag';\nimport type { ObjectId } from 'mongoose';\nimport type { Organization } from '@/export';\nimport type { Tag, TagData, TagDocument } from '@/types/tag.types';\n\n/**\n * Finds tags based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of tags matching the filters.\n */\nexport const findTags = async (\n filters: TagFilters,\n skip = 0,\n limit = 100\n): Promise<TagDocument[]> =>\n await TagModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a tag by its ID.\n * @param tagId - The ID of the tag to find.\n * @returns The tag matching the ID.\n */\nexport const getTagById = async (\n tagId: string | ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findById(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n\nexport const getTagsByKeys = async (\n keys: string[],\n organizationId: string | Organization['_id']\n): Promise<TagDocument[]> => {\n const tags = await TagModel.find({ key: { $in: keys }, organizationId });\n\n return tags;\n};\n\n/**\n * Counts the total number of tags that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of tags.\n */\nexport const countTags = async (filters: TagFilters): Promise<number> => {\n const result = await TagModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('TAG_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new tag in the database.\n * @param tag - The tag data to create.\n * @returns The created tag.\n */\nexport const createTag = async (tag: TagData): Promise<TagDocument> => {\n const errors = await validateTag(tag, ['key']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', { errors });\n }\n\n return await TagModel.create(tag);\n};\n\n/**\n * Updates an existing tag in the database by its ID.\n * @param tagId - The ID of the tag to update.\n * @param tag - The updated tag data.\n * @returns The updated tag.\n */\nexport const updateTagById = async (\n tagId: string | ObjectId,\n tag: Partial<Tag>\n): Promise<TagDocument> => {\n const updatedKeys = Object.keys(tag) as TagFields;\n\n const errors = validateTag(tag, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', {\n tagId,\n errors,\n });\n }\n\n const result = await TagModel.updateOne({ _id: tagId }, tag);\n\n if (result.matchedCount === 0) {\n throw new GenericError('TAG_UPDATE_FAILED', { tagId });\n }\n\n return await getTagById(tagId);\n};\n\n/**\n * Deletes a tag from the database by its ID.\n * @param tagId - The ID of the tag to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteTagById = async (\n tagId: string | ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findByIdAndDelete(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAyB;AACzB,oBAA6B;AAE7B,yBAA4C;AAYrC,MAAM,WAAW,OACtB,SACA,OAAO,GACP,QAAQ,QAER,MAAM,oBAAS,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAO9C,MAAM,aAAa,OACxB,UACyB;AACzB,QAAM,MAAM,MAAM,oBAAS,SAAS,KAAK;AAEzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,2BAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;AAEO,MAAM,gBAAgB,OAC3B,MACA,mBAC2B;AAC3B,QAAM,OAAO,MAAM,oBAAS,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,GAAG,eAAe,CAAC;AAEvE,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,YAAyC;AACvE,QAAM,SAAS,MAAM,oBAAS,eAAe,OAAO;AAEpD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,2BAAa,oBAAoB,EAAE,QAAQ,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,QAAuC;AACrE,QAAM,SAAS,UAAM,gCAAY,KAAK,CAAC,KAAK,CAAC;AAE7C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,sBAAsB,EAAE,OAAO,CAAC;AAAA,EACzD;AAEA,SAAO,MAAM,oBAAS,OAAO,GAAG;AAClC;AAQO,MAAM,gBAAgB,OAC3B,OACA,QACyB;AACzB,QAAM,cAAc,OAAO,KAAK,GAAG;AAEnC,QAAM,aAAS,gCAAY,KAAK,WAAW;AAE3C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,sBAAsB;AAAA,MAC3C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,oBAAS,UAAU,EAAE,KAAK,MAAM,GAAG,GAAG;AAE3D,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,2BAAa,qBAAqB,EAAE,MAAM,CAAC;AAAA,EACvD;AAEA,SAAO,MAAM,WAAW,KAAK;AAC/B;AAOO,MAAM,gBAAgB,OAC3B,UACyB;AACzB,QAAM,MAAM,MAAM,oBAAS,kBAAkB,KAAK;AAElD,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,2BAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/services/tag.service.ts"],"sourcesContent":["import type { Organization } from '@/export';\nimport type { Tag, TagData, TagDocument } from '@/types/tag.types';\nimport { TagModel } from '@models/tag.model';\nimport { GenericError } from '@utils/errors';\nimport type { TagFilters } from '@utils/filtersAndPagination/getTagFiltersAndPagination';\nimport { type TagFields, validateTag } from '@utils/validation/validateTag';\nimport type { Types } from 'mongoose';\n\n/**\n * Finds tags based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of tags matching the filters.\n */\nexport const findTags = async (\n filters: TagFilters,\n skip = 0,\n limit = 100\n): Promise<TagDocument[]> =>\n await TagModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a tag by its ID.\n * @param tagId - The ID of the tag to find.\n * @returns The tag matching the ID.\n */\nexport const getTagById = async (\n tagId: string | Types.ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findById(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n\nexport const getTagsByKeys = async (\n keys: string[],\n organizationId: string | Organization['id']\n): Promise<TagDocument[]> => {\n const tags = await TagModel.find({ key: { $in: keys }, organizationId });\n\n return tags;\n};\n\n/**\n * Counts the total number of tags that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of tags.\n */\nexport const countTags = async (filters: TagFilters): Promise<number> => {\n const result = await TagModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('TAG_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new tag in the database.\n * @param tag - The tag data to create.\n * @returns The created tag.\n */\nexport const createTag = async (tag: TagData): Promise<TagDocument> => {\n const errors = await validateTag(tag, ['key']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', { errors });\n }\n\n return await TagModel.create(tag);\n};\n\n/**\n * Updates an existing tag in the database by its ID.\n * @param tagId - The ID of the tag to update.\n * @param tag - The updated tag data.\n * @returns The updated tag.\n */\nexport const updateTagById = async (\n tagId: string | Types.ObjectId,\n tag: Partial<Tag>\n): Promise<TagDocument> => {\n const updatedKeys = Object.keys(tag) as TagFields;\n\n const errors = validateTag(tag, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', {\n tagId,\n errors,\n });\n }\n\n const result = await TagModel.updateOne({ _id: tagId }, tag);\n\n if (result.matchedCount === 0) {\n throw new GenericError('TAG_UPDATE_FAILED', { tagId });\n }\n\n return await getTagById(tagId);\n};\n\n/**\n * Deletes a tag from the database by its ID.\n * @param tagId - The ID of the tag to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteTagById = async (\n tagId: string | Types.ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findByIdAndDelete(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAyB;AACzB,oBAA6B;AAE7B,yBAA4C;AAUrC,MAAM,WAAW,OACtB,SACA,OAAO,GACP,QAAQ,QAER,MAAM,oBAAS,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAO9C,MAAM,aAAa,OACxB,UACyB;AACzB,QAAM,MAAM,MAAM,oBAAS,SAAS,KAAK;AAEzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,2BAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;AAEO,MAAM,gBAAgB,OAC3B,MACA,mBAC2B;AAC3B,QAAM,OAAO,MAAM,oBAAS,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,GAAG,eAAe,CAAC;AAEvE,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,YAAyC;AACvE,QAAM,SAAS,MAAM,oBAAS,eAAe,OAAO;AAEpD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,2BAAa,oBAAoB,EAAE,QAAQ,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,QAAuC;AACrE,QAAM,SAAS,UAAM,gCAAY,KAAK,CAAC,KAAK,CAAC;AAE7C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,sBAAsB,EAAE,OAAO,CAAC;AAAA,EACzD;AAEA,SAAO,MAAM,oBAAS,OAAO,GAAG;AAClC;AAQO,MAAM,gBAAgB,OAC3B,OACA,QACyB;AACzB,QAAM,cAAc,OAAO,KAAK,GAAG;AAEnC,QAAM,aAAS,gCAAY,KAAK,WAAW;AAE3C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,sBAAsB;AAAA,MAC3C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,oBAAS,UAAU,EAAE,KAAK,MAAM,GAAG,GAAG;AAE3D,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,2BAAa,qBAAqB,EAAE,MAAM,CAAC;AAAA,EACvD;AAEA,SAAO,MAAM,WAAW,KAAK;AAC/B;AAOO,MAAM,gBAAgB,OAC3B,UACyB;AACzB,QAAM,MAAM,MAAM,oBAAS,kBAAkB,KAAK;AAElD,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,2BAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;","names":[]}
@@ -23,10 +23,8 @@ __export(user_service_exports, {
23
23
  createUser: () => createUser,
24
24
  deleteUser: () => deleteUser,
25
25
  findUsers: () => findUsers,
26
- getUserByAccount: () => getUserByAccount,
27
26
  getUserByEmail: () => getUserByEmail,
28
27
  getUserById: () => getUserById,
29
- getUserBySession: () => getUserBySession,
30
28
  getUsersByEmails: () => getUsersByEmails,
31
29
  getUsersByIds: () => getUsersByIds,
32
30
  updateUserById: () => updateUserById
@@ -35,7 +33,6 @@ module.exports = __toCommonJS(user_service_exports);
35
33
  var import_user = require('./../models/user.model.cjs');
36
34
  var import_errors = require('./../utils/errors/index.cjs');
37
35
  var import_validateUser = require('./../utils/validation/validateUser.cjs');
38
- var import_sessionAuth = require('./sessionAuth.service.cjs');
39
36
  const createUser = async (user) => {
40
37
  const fieldsToCheck = ["email"];
41
38
  const errors = (0, import_validateUser.validateUser)(user, fieldsToCheck);
@@ -45,13 +42,7 @@ const createUser = async (user) => {
45
42
  errors
46
43
  });
47
44
  }
48
- let newUser;
49
- if (user.password) {
50
- const userWithHashedPassword = await (0, import_sessionAuth.hashUserPassword)(user);
51
- newUser = await import_user.UserModel.create(userWithHashedPassword);
52
- } else {
53
- newUser = await import_user.UserModel.create(user);
54
- }
45
+ const newUser = await import_user.UserModel.create(user);
55
46
  if (!newUser) {
56
47
  throw new import_errors.GenericError("USER_CREATION_FAILED", { userEmail: user.email });
57
48
  }
@@ -68,36 +59,7 @@ const checkUserExists = async (email) => {
68
59
  return user !== null;
69
60
  };
70
61
  const getUserById = async (userId) => await import_user.UserModel.findById(userId);
71
- const getUsersByIds = async (userIds) => {
72
- return await import_user.UserModel.find({ _id: { $in: userIds } });
73
- };
74
- const getUserBySession = async (sessionToken) => {
75
- const user = await import_user.UserModel.findOne({
76
- "session.sessionToken": sessionToken
77
- });
78
- if (!user) {
79
- throw new import_errors.GenericError("USER_NOT_FOUND", { sessionToken });
80
- }
81
- if (user.session?.expires && user.session.expires < /* @__PURE__ */ new Date()) {
82
- throw new import_errors.GenericError("USER_SESSION_EXPIRED", {
83
- sessionToken,
84
- userId: user.id
85
- });
86
- }
87
- return user;
88
- };
89
- const getUserByAccount = async (provider, providerAccountId) => {
90
- const user = await import_user.UserModel.findOne({
91
- provider: [{ provider, providerAccountId }]
92
- });
93
- if (!user) {
94
- throw new import_errors.GenericError("USER_NOT_FOUND", {
95
- provider,
96
- providerAccountId
97
- });
98
- }
99
- return user;
100
- };
62
+ const getUsersByIds = async (userIds) => await import_user.UserModel.find({ _id: { $in: userIds } });
101
63
  const findUsers = async (filters, skip, limit) => {
102
64
  return await import_user.UserModel.find(filters).skip(skip).limit(limit);
103
65
  };
@@ -142,10 +104,8 @@ const deleteUser = async (userId) => {
142
104
  createUser,
143
105
  deleteUser,
144
106
  findUsers,
145
- getUserByAccount,
146
107
  getUserByEmail,
147
108
  getUserById,
148
- getUserBySession,
149
109
  getUsersByEmails,
150
110
  getUsersByIds,
151
111
  updateUserById
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/user.service.ts"],"sourcesContent":["import { UserModel } from '@models/user.model';\nimport { GenericError } from '@utils/errors';\nimport type { UserFilters } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport {\n type FieldsToCheck,\n type UserFields,\n validateUser,\n} from '@utils/validation/validateUser';\nimport type { ObjectId } from 'mongoose';\nimport { hashUserPassword } from './sessionAuth.service';\nimport type { SessionProviders } from '@/types/session.types';\nimport type {\n User,\n UserDocument,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\n\n/**\n * Creates a new user with password in the database and hashes the password.\n * @param user - User object with password not hashed.\n * @returns Created user object.\n */\nexport const createUser = async (\n user: UserWithPasswordNotHashed\n): Promise<UserDocument> => {\n const fieldsToCheck: FieldsToCheck[] = ['email'];\n\n const errors = validateUser(user, fieldsToCheck);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userEmail: user.email,\n errors,\n });\n }\n\n let newUser: UserDocument;\n\n if (user.password) {\n const userWithHashedPassword = await hashUserPassword(user);\n\n newUser = await UserModel.create(userWithHashedPassword);\n } else {\n newUser = await UserModel.create(user);\n }\n\n if (!newUser) {\n throw new GenericError('USER_CREATION_FAILED', { userEmail: user.email });\n }\n\n return newUser;\n};\n\n/**\n * Retrieves a user by email.\n * @param email - User's email.\n * @returns User object or null if no user was found.\n */\nexport const getUserByEmail = async (\n email: string\n): Promise<UserDocument | null> => {\n return await UserModel.findOne({ email });\n};\n\n/**\n * Retrieves users list by email.\n * @param emails - Users email.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByEmails = async (\n emails: string[]\n): Promise<UserDocument[] | null> => {\n return await UserModel.find({ email: { $in: emails } });\n};\n\n/**\n * Checks if a user exists by email.\n * @param email - User's email.\n * @returns True if the user exists, false otherwise.\n */\nexport const checkUserExists = async (email: string): Promise<boolean> => {\n const user = await UserModel.exists({ email });\n return user !== null;\n};\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUserById = async (\n userId: string | ObjectId\n): Promise<UserDocument | null> => await UserModel.findById(userId);\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByIds = async (\n userIds: (string | ObjectId)[]\n): Promise<UserDocument[] | null> => {\n return await UserModel.find({ _id: { $in: userIds } });\n};\n\n/**\n * Retrieves a user by session token.\n * @param sessionToken - The session token.\n * @returns User object or null if no user was found.\n */\nexport const getUserBySession = async (\n sessionToken: string\n): Promise<UserDocument> => {\n // Get an user by session token and check if it expired\n const user = await UserModel.findOne({\n 'session.sessionToken': sessionToken,\n });\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { sessionToken });\n }\n\n if (user.session?.expires && user.session.expires < new Date()) {\n throw new GenericError('USER_SESSION_EXPIRED', {\n sessionToken,\n userId: user.id,\n });\n }\n\n return user;\n};\n\n/**\n * Retrieves a user by account.\n * @param provider - The provider of the account.\n * @param providerAccountId - The provider account ID.\n * @returns User object or null if no user was found.\n */\nexport const getUserByAccount = async (\n provider: SessionProviders['provider'],\n providerAccountId: string\n): Promise<UserDocument> => {\n const user = await UserModel.findOne({\n provider: [{ provider, providerAccountId }],\n });\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', {\n provider,\n providerAccountId,\n });\n }\n\n return user;\n};\n\n/**\n * Finds users based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of users matching the filters.\n */\nexport const findUsers = async (\n filters: UserFilters,\n skip: number,\n limit: number\n): Promise<UserDocument[]> => {\n return await UserModel.find(filters).skip(skip).limit(limit);\n};\n\n/**\n * Counts the total number of users that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of users.\n */\nexport const countUsers = async (filters: UserFilters): Promise<number> => {\n const count = await UserModel.countDocuments(filters);\n\n if (typeof count === 'undefined') {\n throw new GenericError('USER_COUNT_FAILED');\n }\n\n return count;\n};\n\n/**\n * Updates a user's information.\n * @param user - The user object.\n * @param updates - The updates to apply to the user.\n * @returns The updated user.\n */\nexport const updateUserById = async (\n userId: string | ObjectId,\n updates: Partial<User>\n): Promise<UserDocument> => {\n const keyToValidate = Object.keys(updates) as UserFields;\n const errors = validateUser(updates, keyToValidate);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userId,\n errors,\n });\n }\n\n const result = await UserModel.updateOne({ _id: userId }, { $set: updates });\n\n if (result.matchedCount === 0) {\n throw new GenericError('USER_UPDATE_FAILED', { userId });\n }\n\n const updatedUser = await UserModel.findById(userId);\n\n if (!updatedUser) {\n throw new GenericError('USER_UPDATED_USER_NOT_FOUND', { userId });\n }\n\n return updatedUser;\n};\n\n/**\n * Deletes a user from the database.\n * @param userId - The user object.\n * @returns\n */\nexport const deleteUser = async (\n userId: string | ObjectId\n): Promise<UserDocument> => {\n await getUserById(userId);\n\n const user = await UserModel.findByIdAndDelete(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n return user;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/services/user.service.ts"],"sourcesContent":["import type { User, UserDocument } from '@/types/user.types';\nimport { UserModel } from '@models/user.model';\nimport { GenericError } from '@utils/errors';\nimport type { UserFilters } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport {\n type FieldsToCheck,\n type UserFields,\n validateUser,\n} from '@utils/validation/validateUser';\nimport type { Types } from 'mongoose';\n\n/**\n * Creates a new user with password in the database and hashes the password.\n * @param user - User object with password not hashed.\n * @returns Created user object.\n */\nexport const createUser = async (\n user: Partial<User>\n): Promise<UserDocument> => {\n const fieldsToCheck: FieldsToCheck[] = ['email'];\n\n const errors = validateUser(user, fieldsToCheck);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userEmail: user.email,\n errors,\n });\n }\n\n const newUser: UserDocument = await UserModel.create(user);\n\n if (!newUser) {\n throw new GenericError('USER_CREATION_FAILED', { userEmail: user.email });\n }\n\n return newUser;\n};\n\n/**\n * Retrieves a user by email.\n * @param email - User's email.\n * @returns User object or null if no user was found.\n */\nexport const getUserByEmail = async (\n email: string\n): Promise<UserDocument | null> => {\n return await UserModel.findOne({ email });\n};\n\n/**\n * Retrieves users list by email.\n * @param emails - Users email.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByEmails = async (\n emails: string[]\n): Promise<UserDocument[] | null> => {\n return await UserModel.find({ email: { $in: emails } });\n};\n\n/**\n * Checks if a user exists by email.\n * @param email - User's email.\n * @returns True if the user exists, false otherwise.\n */\nexport const checkUserExists = async (email: string): Promise<boolean> => {\n const user = await UserModel.exists({ email });\n return user !== null;\n};\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUserById = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument | null> => await UserModel.findById(userId);\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByIds = async (\n userIds: (string | Types.ObjectId)[]\n): Promise<UserDocument[] | null> =>\n await UserModel.find({ _id: { $in: userIds } });\n\n/**\n * Finds users based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of users matching the filters.\n */\nexport const findUsers = async (\n filters: UserFilters,\n skip: number,\n limit: number\n): Promise<UserDocument[]> => {\n return await UserModel.find(filters).skip(skip).limit(limit);\n};\n\n/**\n * Counts the total number of users that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of users.\n */\nexport const countUsers = async (filters: UserFilters): Promise<number> => {\n const count = await UserModel.countDocuments(filters);\n\n if (typeof count === 'undefined') {\n throw new GenericError('USER_COUNT_FAILED');\n }\n\n return count;\n};\n\n/**\n * Updates a user's information.\n * @param user - The user object.\n * @param updates - The updates to apply to the user.\n * @returns The updated user.\n */\nexport const updateUserById = async (\n userId: string | Types.ObjectId,\n updates: Partial<User>\n): Promise<UserDocument> => {\n const keyToValidate = Object.keys(updates) as UserFields;\n const errors = validateUser(updates, keyToValidate);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userId,\n errors,\n });\n }\n\n const result = await UserModel.updateOne({ _id: userId }, { $set: updates });\n\n if (result.matchedCount === 0) {\n throw new GenericError('USER_UPDATE_FAILED', { userId });\n }\n\n const updatedUser = await UserModel.findById(userId);\n\n if (!updatedUser) {\n throw new GenericError('USER_UPDATED_USER_NOT_FOUND', { userId });\n }\n\n return updatedUser;\n};\n\n/**\n * Deletes a user from the database.\n * @param userId - The user object.\n * @returns\n */\nexport const deleteUser = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument> => {\n await getUserById(userId);\n\n const user = await UserModel.findByIdAndDelete(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n return user;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAA0B;AAC1B,oBAA6B;AAE7B,0BAIO;AAQA,MAAM,aAAa,OACxB,SAC0B;AAC1B,QAAM,gBAAiC,CAAC,OAAO;AAE/C,QAAM,aAAS,kCAAa,MAAM,aAAa;AAE/C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,uBAAuB;AAAA,MAC5C,WAAW,KAAK;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,UAAwB,MAAM,sBAAU,OAAO,IAAI;AAEzD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,2BAAa,wBAAwB,EAAE,WAAW,KAAK,MAAM,CAAC;AAAA,EAC1E;AAEA,SAAO;AACT;AAOO,MAAM,iBAAiB,OAC5B,UACiC;AACjC,SAAO,MAAM,sBAAU,QAAQ,EAAE,MAAM,CAAC;AAC1C;AAOO,MAAM,mBAAmB,OAC9B,WACmC;AACnC,SAAO,MAAM,sBAAU,KAAK,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC;AACxD;AAOO,MAAM,kBAAkB,OAAO,UAAoC;AACxE,QAAM,OAAO,MAAM,sBAAU,OAAO,EAAE,MAAM,CAAC;AAC7C,SAAO,SAAS;AAClB;AAOO,MAAM,cAAc,OACzB,WACiC,MAAM,sBAAU,SAAS,MAAM;AAO3D,MAAM,gBAAgB,OAC3B,YAEA,MAAM,sBAAU,KAAK,EAAE,KAAK,EAAE,KAAK,QAAQ,EAAE,CAAC;AASzC,MAAM,YAAY,OACvB,SACA,MACA,UAC4B;AAC5B,SAAO,MAAM,sBAAU,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAC7D;AAOO,MAAM,aAAa,OAAO,YAA0C;AACzE,QAAM,QAAQ,MAAM,sBAAU,eAAe,OAAO;AAEpD,MAAI,OAAO,UAAU,aAAa;AAChC,UAAM,IAAI,2BAAa,mBAAmB;AAAA,EAC5C;AAEA,SAAO;AACT;AAQO,MAAM,iBAAiB,OAC5B,QACA,YAC0B;AAC1B,QAAM,gBAAgB,OAAO,KAAK,OAAO;AACzC,QAAM,aAAS,kCAAa,SAAS,aAAa;AAElD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,2BAAa,uBAAuB;AAAA,MAC5C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,sBAAU,UAAU,EAAE,KAAK,OAAO,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE3E,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,2BAAa,sBAAsB,EAAE,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,cAAc,MAAM,sBAAU,SAAS,MAAM;AAEnD,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,2BAAa,+BAA+B,EAAE,OAAO,CAAC;AAAA,EAClE;AAEA,SAAO;AACT;AAOO,MAAM,aAAa,OACxB,WAC0B;AAC1B,QAAM,YAAY,MAAM;AAExB,QAAM,OAAO,MAAM,sBAAU,kBAAkB,MAAM;AAErD,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,SAAO;AACT;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport type { Model, ObjectId, Document } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['_id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['_id'] | string)[];\n creatorId: User['_id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n};\n\nexport type Dictionary = DictionaryData & {\n _id: ObjectId;\n createdAt: number;\n updatedAt: number;\n};\n\nexport type DictionaryAPI = DictionaryCore & {\n projectIds: (Project['_id'] | string)[];\n};\n\nexport type DictionaryDocument = Document<unknown, {}, Dictionary> & Dictionary;\nexport type DictionaryModelType = Model<Dictionary>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport { RenameId } from '@utils/mongoDB/types';\nimport type { Document, Model, ObjectIdToString, Types } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['id'] | string)[];\n creatorId: User['id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n};\n\nexport type Dictionary = DictionaryData & {\n id: Types.ObjectId;\n createdAt: number;\n updatedAt: number;\n};\n\nexport type DictionaryAPI = ObjectIdToString<\n DictionaryCore & {\n projectIds: (Project['id'] | string)[];\n }\n>;\n\nexport type DictionarySchema = RenameId<Dictionary>;\nexport type DictionaryModelType = Model<Dictionary>;\nexport type DictionaryDocument = Document<unknown, {}, Dictionary> & Dictionary;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}