@intlayer/backend 3.1.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/dist/cjs/controllers/dictionary.controller.cjs +41 -0
  2. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  3. package/dist/cjs/controllers/organization.controller.cjs +73 -4
  4. package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
  5. package/dist/cjs/controllers/project.controller.cjs +71 -7
  6. package/dist/cjs/controllers/project.controller.cjs.map +1 -1
  7. package/dist/cjs/controllers/projectAccessKey.controller.cjs +31 -0
  8. package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
  9. package/dist/cjs/controllers/sessionAuth.controller.cjs +277 -57
  10. package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
  11. package/dist/cjs/controllers/stripe.controller.cjs +84 -0
  12. package/dist/cjs/controllers/stripe.controller.cjs.map +1 -0
  13. package/dist/cjs/controllers/user.controller.cjs +40 -3
  14. package/dist/cjs/controllers/user.controller.cjs.map +1 -1
  15. package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs +182 -0
  16. package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs.map +1 -0
  17. package/dist/cjs/emails/SubscriptionPaymentError.cjs +182 -0
  18. package/dist/cjs/emails/SubscriptionPaymentError.cjs.map +1 -0
  19. package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs +188 -0
  20. package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs.map +1 -0
  21. package/dist/cjs/export.cjs.map +1 -1
  22. package/dist/cjs/index.cjs +15 -5
  23. package/dist/cjs/index.cjs.map +1 -1
  24. package/dist/cjs/middlewares/sessionAuth.middleware.cjs +4 -6
  25. package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
  26. package/dist/cjs/routes/dictionary.routes.cjs +2 -62
  27. package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
  28. package/dist/cjs/routes/organization.routes.cjs +1 -25
  29. package/dist/cjs/routes/organization.routes.cjs.map +1 -1
  30. package/dist/cjs/routes/project.routes.cjs +10 -85
  31. package/dist/cjs/routes/project.routes.cjs.map +1 -1
  32. package/dist/cjs/routes/sessionAuth.routes.cjs +26 -25
  33. package/dist/cjs/routes/sessionAuth.routes.cjs.map +1 -1
  34. package/dist/cjs/{models/plan.moddel.cjs → routes/stripe.routes.cjs} +20 -9
  35. package/dist/cjs/routes/stripe.routes.cjs.map +1 -0
  36. package/dist/cjs/routes/user.routes.cjs +6 -27
  37. package/dist/cjs/routes/user.routes.cjs.map +1 -1
  38. package/dist/cjs/schemas/organization.schema.cjs +5 -0
  39. package/dist/cjs/schemas/organization.schema.cjs.map +1 -1
  40. package/dist/cjs/schemas/plans.schema.cjs +2 -8
  41. package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
  42. package/dist/cjs/schemas/user.schema.cjs +1 -1
  43. package/dist/cjs/schemas/user.schema.cjs.map +1 -1
  44. package/dist/cjs/services/email.service.cjs +113 -43
  45. package/dist/cjs/services/email.service.cjs.map +1 -1
  46. package/dist/cjs/services/organization.service.cjs +55 -8
  47. package/dist/cjs/services/organization.service.cjs.map +1 -1
  48. package/dist/cjs/services/project.service.cjs +1 -3
  49. package/dist/cjs/services/project.service.cjs.map +1 -1
  50. package/dist/cjs/services/sessionAuth.service.cjs +9 -11
  51. package/dist/cjs/services/sessionAuth.service.cjs.map +1 -1
  52. package/dist/cjs/services/subscription.service.cjs +134 -51
  53. package/dist/cjs/services/subscription.service.cjs.map +1 -1
  54. package/dist/cjs/services/user.service.cjs +1 -3
  55. package/dist/cjs/services/user.service.cjs.map +1 -1
  56. package/dist/cjs/types/organization.types.cjs.map +1 -1
  57. package/dist/cjs/types/plan.types.cjs.map +1 -1
  58. package/dist/cjs/types/session.types.cjs.map +1 -1
  59. package/dist/cjs/utils/errors/ErrorHandler.cjs +29 -9
  60. package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
  61. package/dist/cjs/utils/errors/ErrorsClass.cjs +17 -3
  62. package/dist/cjs/utils/errors/ErrorsClass.cjs.map +1 -1
  63. package/dist/cjs/utils/errors/errorCodes.cjs +99 -8
  64. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  65. package/dist/cjs/utils/mapper/project.cjs +1 -1
  66. package/dist/cjs/utils/mapper/project.cjs.map +1 -1
  67. package/dist/cjs/utils/plan.cjs +7 -2
  68. package/dist/cjs/utils/plan.cjs.map +1 -1
  69. package/dist/cjs/utils/responseData.cjs +8 -0
  70. package/dist/cjs/utils/responseData.cjs.map +1 -1
  71. package/dist/cjs/webhooks/stripe.webhook.cjs +133 -0
  72. package/dist/cjs/webhooks/stripe.webhook.cjs.map +1 -0
  73. package/dist/esm/controllers/dictionary.controller.mjs +41 -0
  74. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  75. package/dist/esm/controllers/organization.controller.mjs +73 -4
  76. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  77. package/dist/esm/controllers/project.controller.mjs +71 -7
  78. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  79. package/dist/esm/controllers/projectAccessKey.controller.mjs +31 -0
  80. package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
  81. package/dist/esm/controllers/sessionAuth.controller.mjs +273 -56
  82. package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
  83. package/dist/esm/controllers/stripe.controller.mjs +60 -0
  84. package/dist/esm/controllers/stripe.controller.mjs.map +1 -0
  85. package/dist/esm/controllers/user.controller.mjs +40 -3
  86. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  87. package/dist/esm/emails/SubscriptionPaymentCancellation.mjs +168 -0
  88. package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -0
  89. package/dist/esm/emails/SubscriptionPaymentError.mjs +168 -0
  90. package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -0
  91. package/dist/esm/emails/SubscriptionPaymentSuccess.mjs +174 -0
  92. package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -0
  93. package/dist/esm/export.mjs.map +1 -1
  94. package/dist/esm/index.mjs +15 -5
  95. package/dist/esm/index.mjs.map +1 -1
  96. package/dist/esm/middlewares/sessionAuth.middleware.mjs +4 -6
  97. package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
  98. package/dist/esm/routes/dictionary.routes.mjs +2 -62
  99. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  100. package/dist/esm/routes/organization.routes.mjs +1 -25
  101. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  102. package/dist/esm/routes/project.routes.mjs +10 -85
  103. package/dist/esm/routes/project.routes.mjs.map +1 -1
  104. package/dist/esm/routes/sessionAuth.routes.mjs +29 -26
  105. package/dist/esm/routes/sessionAuth.routes.mjs.map +1 -1
  106. package/dist/esm/routes/stripe.routes.mjs +17 -0
  107. package/dist/esm/routes/stripe.routes.mjs.map +1 -0
  108. package/dist/esm/routes/user.routes.mjs +6 -27
  109. package/dist/esm/routes/user.routes.mjs.map +1 -1
  110. package/dist/esm/schemas/organization.schema.mjs +5 -0
  111. package/dist/esm/schemas/organization.schema.mjs.map +1 -1
  112. package/dist/esm/schemas/plans.schema.mjs +2 -8
  113. package/dist/esm/schemas/plans.schema.mjs.map +1 -1
  114. package/dist/esm/schemas/user.schema.mjs +1 -1
  115. package/dist/esm/schemas/user.schema.mjs.map +1 -1
  116. package/dist/esm/services/email.service.mjs +125 -43
  117. package/dist/esm/services/email.service.mjs.map +1 -1
  118. package/dist/esm/services/organization.service.mjs +51 -7
  119. package/dist/esm/services/organization.service.mjs.map +1 -1
  120. package/dist/esm/services/project.service.mjs +1 -3
  121. package/dist/esm/services/project.service.mjs.map +1 -1
  122. package/dist/esm/services/sessionAuth.service.mjs +9 -10
  123. package/dist/esm/services/sessionAuth.service.mjs.map +1 -1
  124. package/dist/esm/services/subscription.service.mjs +136 -53
  125. package/dist/esm/services/subscription.service.mjs.map +1 -1
  126. package/dist/esm/services/user.service.mjs +1 -3
  127. package/dist/esm/services/user.service.mjs.map +1 -1
  128. package/dist/esm/utils/errors/ErrorHandler.mjs +29 -9
  129. package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
  130. package/dist/esm/utils/errors/ErrorsClass.mjs +17 -3
  131. package/dist/esm/utils/errors/ErrorsClass.mjs.map +1 -1
  132. package/dist/esm/utils/errors/errorCodes.mjs +99 -8
  133. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  134. package/dist/esm/utils/mapper/project.mjs +1 -1
  135. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  136. package/dist/esm/utils/plan.mjs +7 -2
  137. package/dist/esm/utils/plan.mjs.map +1 -1
  138. package/dist/esm/utils/responseData.mjs +8 -0
  139. package/dist/esm/utils/responseData.mjs.map +1 -1
  140. package/dist/esm/webhooks/stripe.webhook.mjs +113 -0
  141. package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -0
  142. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  143. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  144. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  145. package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
  146. package/dist/types/controllers/sessionAuth.controller.d.ts +24 -5
  147. package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
  148. package/dist/types/controllers/stripe.controller.d.ts +17 -0
  149. package/dist/types/controllers/stripe.controller.d.ts.map +1 -0
  150. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  151. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +20 -0
  152. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts.map +1 -0
  153. package/dist/types/emails/SubscriptionPaymentError.d.ts +20 -0
  154. package/dist/types/emails/SubscriptionPaymentError.d.ts.map +1 -0
  155. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +20 -0
  156. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts.map +1 -0
  157. package/dist/types/export.d.ts +1 -0
  158. package/dist/types/export.d.ts.map +1 -1
  159. package/dist/types/index.d.ts.map +1 -1
  160. package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
  161. package/dist/types/models/organization.model.d.ts +1 -0
  162. package/dist/types/models/organization.model.d.ts.map +1 -1
  163. package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
  164. package/dist/types/routes/organization.routes.d.ts.map +1 -1
  165. package/dist/types/routes/project.routes.d.ts.map +1 -1
  166. package/dist/types/routes/sessionAuth.routes.d.ts +15 -2
  167. package/dist/types/routes/sessionAuth.routes.d.ts.map +1 -1
  168. package/dist/types/routes/stripe.routes.d.ts +10 -0
  169. package/dist/types/routes/stripe.routes.d.ts.map +1 -0
  170. package/dist/types/routes/user.routes.d.ts.map +1 -1
  171. package/dist/types/schemas/organization.schema.d.ts +1 -0
  172. package/dist/types/schemas/organization.schema.d.ts.map +1 -1
  173. package/dist/types/schemas/plans.schema.d.ts.map +1 -1
  174. package/dist/types/services/email.service.d.ts +33 -4
  175. package/dist/types/services/email.service.d.ts.map +1 -1
  176. package/dist/types/services/organization.service.d.ts +15 -0
  177. package/dist/types/services/organization.service.d.ts.map +1 -1
  178. package/dist/types/services/project.service.d.ts.map +1 -1
  179. package/dist/types/services/sessionAuth.service.d.ts +1 -8
  180. package/dist/types/services/sessionAuth.service.d.ts.map +1 -1
  181. package/dist/types/services/subscription.service.d.ts +20 -5
  182. package/dist/types/services/subscription.service.d.ts.map +1 -1
  183. package/dist/types/services/user.service.d.ts.map +1 -1
  184. package/dist/types/types/organization.types.d.ts +2 -0
  185. package/dist/types/types/organization.types.d.ts.map +1 -1
  186. package/dist/types/types/plan.types.d.ts +2 -3
  187. package/dist/types/types/plan.types.d.ts.map +1 -1
  188. package/dist/types/types/session.types.d.ts +6 -6
  189. package/dist/types/types/session.types.d.ts.map +1 -1
  190. package/dist/types/utils/errors/ErrorHandler.d.ts +5 -3
  191. package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
  192. package/dist/types/utils/errors/ErrorsClass.d.ts +4 -1
  193. package/dist/types/utils/errors/ErrorsClass.d.ts.map +1 -1
  194. package/dist/types/utils/errors/errorCodes.d.ts +92 -1
  195. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  196. package/dist/types/utils/mapper/project.d.ts +1 -1
  197. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  198. package/dist/types/utils/plan.d.ts +1 -1
  199. package/dist/types/utils/plan.d.ts.map +1 -1
  200. package/dist/types/utils/responseData.d.ts +13 -2
  201. package/dist/types/utils/responseData.d.ts.map +1 -1
  202. package/dist/types/webhooks/stripe.d.ts.map +1 -1
  203. package/dist/types/webhooks/stripe.webhook.d.ts +3 -0
  204. package/dist/types/webhooks/stripe.webhook.d.ts.map +1 -0
  205. package/package.json +6 -5
  206. package/dist/cjs/models/plan.moddel.cjs.map +0 -1
  207. package/dist/cjs/services/plans.service.cjs +0 -72
  208. package/dist/cjs/services/plans.service.cjs.map +0 -1
  209. package/dist/cjs/webhooks/stripe.cjs +0 -94
  210. package/dist/cjs/webhooks/stripe.cjs.map +0 -1
  211. package/dist/esm/models/plan.moddel.mjs +0 -7
  212. package/dist/esm/models/plan.moddel.mjs.map +0 -1
  213. package/dist/esm/services/plans.service.mjs +0 -44
  214. package/dist/esm/services/plans.service.mjs.map +0 -1
  215. package/dist/esm/webhooks/stripe.mjs +0 -70
  216. package/dist/esm/webhooks/stripe.mjs.map +0 -1
@@ -1,3 +1,4 @@
1
+ import crypto from "crypto";
1
2
  import { logger } from './../logger/index.mjs';
2
3
  import { sessionAuthRoutes } from './../routes/sessionAuth.routes.mjs';
3
4
  import { sendEmail } from './../services/email.service.mjs';
@@ -10,6 +11,7 @@ import { mapOrganizationToAPI } from './../utils/mapper/organization.mjs';
10
11
  import { mapProjectToAPI } from './../utils/mapper/project.mjs';
11
12
  import { mapUserToAPI } from './../utils/mapper/user.mjs';
12
13
  import { formatResponse } from './../utils/responseData.mjs';
14
+ import { t } from "express-intlayer";
13
15
  import { Types } from "mongoose";
14
16
  import { v4 as uuidv4 } from "uuid";
15
17
  const setCSRFToken = (req, res, _next) => {
@@ -22,10 +24,15 @@ const setCSRFToken = (req, res, _next) => {
22
24
  };
23
25
  const registerEmailPassword = async (req, res, _next) => {
24
26
  const { user } = res.locals;
27
+ const { callBack_url } = req.query;
25
28
  if (user) {
26
29
  ErrorHandler.handleGenericErrorResponse(res, "USER_ALREADY_LOGGED_IN");
27
30
  return;
28
31
  }
32
+ if (callBack_url && !callBack_url.startsWith(process.env.CLIENT_URL ?? "")) {
33
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
34
+ return;
35
+ }
29
36
  const userData = req.body;
30
37
  try {
31
38
  let user2 = await userService.getUserByEmail(userData.email);
@@ -33,22 +40,18 @@ const registerEmailPassword = async (req, res, _next) => {
33
40
  const emailProvider = user2.provider?.find(
34
41
  (provider) => provider.provider === "email"
35
42
  );
36
- if (emailProvider) {
37
- if (emailProvider.emailValidated) {
38
- ErrorHandler.handleGenericErrorResponse(
39
- res,
40
- "EMAIL_ALREADY_VALIDATED"
41
- );
42
- return;
43
- } else {
44
- user2 = await sessionAuthService.updateUserProvider(
45
- user2._id,
46
- "email",
47
- {
48
- secret: uuidv4()
49
- }
50
- );
51
- }
43
+ if (emailProvider?.emailValidated) {
44
+ ErrorHandler.handleGenericErrorResponse(
45
+ res,
46
+ "EMAIL_ALREADY_REGISTERED"
47
+ );
48
+ return;
49
+ } else if (emailProvider) {
50
+ user2 = await sessionAuthService.updateUserProvider(user2._id, "email", {
51
+ provider: "email",
52
+ emailValidated: void 0,
53
+ secret: uuidv4()
54
+ });
52
55
  } else {
53
56
  user2 = await sessionAuthService.addUserProvider(user2._id, {
54
57
  provider: "email",
@@ -57,7 +60,16 @@ const registerEmailPassword = async (req, res, _next) => {
57
60
  });
58
61
  }
59
62
  } else {
60
- user2 = await userService.createUser(userData);
63
+ user2 = await userService.createUser({
64
+ ...userData,
65
+ provider: [
66
+ {
67
+ provider: "email",
68
+ emailValidated: void 0,
69
+ secret: uuidv4()
70
+ }
71
+ ]
72
+ });
61
73
  logger.info(`New registration: ${user2.name} - ${user2.email}`);
62
74
  }
63
75
  if (!user2) {
@@ -66,9 +78,30 @@ const registerEmailPassword = async (req, res, _next) => {
66
78
  });
67
79
  return;
68
80
  }
69
- await sessionAuthService.setUserAuth(res, user2);
81
+ await sendEmail({
82
+ type: "validate",
83
+ to: user2.email,
84
+ username: user2.name ?? user2.email.split("@")[0],
85
+ validationLink: sessionAuthRoutes.validEmail.url({
86
+ userId: String(user2._id),
87
+ secret: user2.provider?.find((provider) => provider.provider === "email")?.secret ?? "",
88
+ callBack_url
89
+ })
90
+ });
70
91
  const formattedUser = mapUserToAPI(user2);
71
- const responseData = formatResponse({ data: formattedUser });
92
+ const responseData = formatResponse({
93
+ message: t({
94
+ en: "User registered successfully",
95
+ fr: "Utilisateur enregistr\xE9 avec succ\xE8s",
96
+ es: "Usuario registrado con \xE9xito"
97
+ }),
98
+ description: t({
99
+ en: "Your user has been registered successfully. Please check your email to validate your account.",
100
+ fr: "Votre utilisateur a \xE9t\xE9 enregistr\xE9 avec succ\xE8s. Veuillez v\xE9rifier votre e-mail pour valider votre compte.",
101
+ es: "Su usuario ha sido registrado con \xE9xito. Por favor, revise su correo electr\xF3nico para validar su cuenta."
102
+ }),
103
+ data: formattedUser
104
+ });
72
105
  res.json(responseData);
73
106
  return;
74
107
  } catch (error) {
@@ -97,7 +130,19 @@ const loginEmailPassword = async (req, res, _next) => {
97
130
  }
98
131
  await sessionAuthService.setUserAuth(res, loggedInUser);
99
132
  const formattedUser = mapUserToAPI(loggedInUser);
100
- const responseData = formatResponse({ data: formattedUser });
133
+ const responseData = formatResponse({
134
+ message: t({
135
+ en: "User logged in successfully",
136
+ fr: "Utilisateur connect\xE9 avec succ\xE8s",
137
+ es: "Usuario conectado con \xE9xito"
138
+ }),
139
+ description: t({
140
+ en: "Your user has been logged in successfully",
141
+ fr: "Votre utilisateur a \xE9t\xE9 connect\xE9 avec succ\xE8s",
142
+ es: "Su usuario ha sido conectado con \xE9xito"
143
+ }),
144
+ data: formattedUser
145
+ });
101
146
  logger.info(`Login: ${loggedInUser.email}`);
102
147
  res.json(responseData);
103
148
  return;
@@ -116,7 +161,19 @@ const logOut = async (_req, res, _next) => {
116
161
  sessionAuthService.clearOrganizationAuth(res);
117
162
  sessionAuthService.clearProjectAuth(res);
118
163
  logger.info(`Logout: ${user.name} - ${user.email}`);
119
- const responseData = formatResponse({ data: void 0 });
164
+ const responseData = formatResponse({
165
+ message: t({
166
+ en: "User logged out successfully",
167
+ fr: "Utilisateur d\xE9connect\xE9 avec succ\xE8s",
168
+ es: "Usuario desconectado con \xE9xito"
169
+ }),
170
+ description: t({
171
+ en: "Your user has been logged out successfully",
172
+ fr: "Votre utilisateur a \xE9t\xE9 d\xE9connect\xE9 avec succ\xE8s",
173
+ es: "Su usuario ha sido desconectado con \xE9xito"
174
+ }),
175
+ data: void 0
176
+ });
120
177
  res.json(responseData);
121
178
  };
122
179
  const updatePassword = async (req, res, _next) => {
@@ -126,20 +183,34 @@ const updatePassword = async (req, res, _next) => {
126
183
  ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
127
184
  return;
128
185
  }
129
- try {
130
- const { error } = await sessionAuthService.testUserPassword(
131
- user.email,
132
- oldPassword
186
+ const userEmailProvider = user.provider?.find(
187
+ (provider) => provider.provider === "email"
188
+ );
189
+ if (!userEmailProvider) {
190
+ ErrorHandler.handleGenericErrorResponse(res, "USER_PROVIDER_NOT_FOUND", {
191
+ provider: "email"
192
+ });
193
+ return;
194
+ }
195
+ if (userEmailProvider.passwordHash && !oldPassword) {
196
+ ErrorHandler.handleGenericErrorResponse(
197
+ res,
198
+ "USER_PREVIOUS_PASSWORD_NOT_PROVIDED"
133
199
  );
134
- if (error) {
135
- ErrorHandler.handleGenericErrorResponse(res, "LOGIN_FAILED");
136
- return;
200
+ return;
201
+ }
202
+ try {
203
+ if (oldPassword) {
204
+ const { error } = await sessionAuthService.testUserPassword(
205
+ user.email,
206
+ oldPassword
207
+ );
208
+ if (error) {
209
+ ErrorHandler.handleGenericErrorResponse(res, "LOGIN_FAILED");
210
+ return;
211
+ }
137
212
  }
138
- user = await sessionAuthService.changeUserPassword(
139
- user._id,
140
- oldPassword,
141
- newPassword
142
- );
213
+ user = await sessionAuthService.changeUserPassword(user._id, newPassword);
143
214
  if (!user || typeof user !== "object") {
144
215
  ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
145
216
  return;
@@ -148,7 +219,65 @@ const updatePassword = async (req, res, _next) => {
148
219
  `Password changed - User : Name : ${user.name}, id : ${String(user._id)}`
149
220
  );
150
221
  const formattedUser = mapUserToAPI(user);
151
- const responseData = formatResponse({ data: formattedUser });
222
+ const responseData = formatResponse({
223
+ message: t({
224
+ en: "Password changed successfully",
225
+ fr: "Mot de passe modifi\xE9 avec succ\xE8s",
226
+ es: "Contrase\xF1a cambiada con \xE9xito"
227
+ }),
228
+ description: t({
229
+ en: "Your password has been changed successfully",
230
+ fr: "Votre mot de passe a \xE9t\xE9 modifi\xE9 avec succ\xE8s",
231
+ es: "Su contrase\xF1a ha sido cambiada con \xE9xito"
232
+ }),
233
+ data: formattedUser
234
+ });
235
+ res.json(responseData);
236
+ return;
237
+ } catch (error) {
238
+ ErrorHandler.handleAppErrorResponse(res, error);
239
+ return;
240
+ }
241
+ };
242
+ let clients = [];
243
+ const sendVerificationUpdate = (user) => {
244
+ const filteredClients = clients.filter(
245
+ (client) => String(client.userId) === String(user._id)
246
+ );
247
+ for (const client of filteredClients) {
248
+ const provider = user.provider?.find(
249
+ (provider2) => provider2.provider === "email"
250
+ );
251
+ if (provider?.emailValidated) {
252
+ client.res.write(
253
+ `data: ${JSON.stringify({ userId: user._id, status: "verified" })}
254
+
255
+ `
256
+ );
257
+ continue;
258
+ }
259
+ client.res.write(
260
+ `data: ${JSON.stringify({ userId: user._id, status: "waiting" })}
261
+
262
+ `
263
+ );
264
+ }
265
+ };
266
+ const checkIfUserHasPassword = async (_req, res, _next) => {
267
+ const { user } = res.locals;
268
+ if (!user) {
269
+ ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
270
+ return;
271
+ }
272
+ try {
273
+ const userProvider = user.provider?.find(
274
+ (provider) => provider.provider === "email"
275
+ );
276
+ const responseData = formatResponse({
277
+ data: {
278
+ hasPassword: Boolean(userProvider?.passwordHash)
279
+ }
280
+ });
152
281
  res.json(responseData);
153
282
  return;
154
283
  } catch (error) {
@@ -158,15 +287,11 @@ const updatePassword = async (req, res, _next) => {
158
287
  };
159
288
  const validEmail = async (req, res, _next) => {
160
289
  const { userId, secret } = req.params;
161
- const { organization } = res.locals;
290
+ const callBack_url = `${req.query.callBack_url ?? `${process.env.CLIENT_URL}/auth/login`}?userId=${userId}`;
162
291
  if (!Types.ObjectId.isValid(userId.toString())) {
163
292
  ErrorHandler.handleGenericErrorResponse(res, "INVALID_USER_ID");
164
293
  return;
165
294
  }
166
- if (!organization) {
167
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
168
- return;
169
- }
170
295
  const user = await userService.getUserById(userId);
171
296
  if (!user) {
172
297
  ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED", {
@@ -174,19 +299,63 @@ const validEmail = async (req, res, _next) => {
174
299
  });
175
300
  return;
176
301
  }
177
- await sessionAuthService.activateUser(user._id, secret);
302
+ if (callBack_url && !callBack_url.startsWith(process.env.CLIENT_URL ?? "")) {
303
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
304
+ return;
305
+ }
306
+ const provider = user.provider?.find(
307
+ (provider2) => provider2.provider === "email"
308
+ );
309
+ if (provider?.emailValidated) {
310
+ res.redirect(callBack_url);
311
+ }
312
+ if (!provider?.secret) {
313
+ throw new GenericError("USER_PROVIDER_SECRET_NOT_DEFINED", { userId });
314
+ }
315
+ if (!crypto.timingSafeEqual(Buffer.from(provider.secret), Buffer.from(secret))) {
316
+ throw new GenericError("USER_PROVIDER_SECRET_NOT_VALID", { userId });
317
+ }
318
+ await sessionAuthService.updateUserProvider(userId, "email", {
319
+ secret: void 0,
320
+ emailValidated: /* @__PURE__ */ new Date()
321
+ });
178
322
  logger.info(
179
323
  `User activated - User: Name: ${user.name}, id: ${String(user._id)}`
180
324
  );
325
+ sendVerificationUpdate(user);
326
+ await sessionAuthService.setUserAuth(res, user);
181
327
  await sendEmail({
182
328
  type: "welcome",
183
329
  to: user.email,
184
330
  username: user.name,
185
- loginLink: sessionAuthRoutes.loginEmailPassword.url
331
+ loginLink: callBack_url
332
+ });
333
+ res.redirect(callBack_url);
334
+ };
335
+ const verifyEmailStatusSSE = async (req, res) => {
336
+ res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
337
+ res.setHeader("Cache-Control", "no-cache, no-transform");
338
+ res.setHeader("Connection", "keep-alive");
339
+ res.setHeader("X-Accel-Buffering", "no");
340
+ res.write(":\n\n");
341
+ res.flushHeaders();
342
+ const { userId } = req.params;
343
+ const clientId = Date.now();
344
+ const user = await userService.getUserById(userId);
345
+ if (!user) {
346
+ logger.error(`User not found - User ID: ${userId}`);
347
+ res.write(`data: ${JSON.stringify({ userId, status: "error" })}
348
+
349
+ `);
350
+ res.end();
351
+ return;
352
+ }
353
+ const newClient = { id: clientId, userId, res };
354
+ clients.push(newClient);
355
+ sendVerificationUpdate(user);
356
+ req.on("close", () => {
357
+ clients = clients.filter((client) => client.id !== clientId);
186
358
  });
187
- const formattedUser = mapUserToAPI(user);
188
- const responseData = formatResponse({ data: formattedUser });
189
- res.json(responseData);
190
359
  };
191
360
  const askResetPassword = async (req, res, _next) => {
192
361
  const { email } = req.body;
@@ -214,7 +383,19 @@ const askResetPassword = async (req, res, _next) => {
214
383
  )?.secret ?? ""
215
384
  })
216
385
  });
217
- const responseData = formatResponse({ data: void 0 });
386
+ const responseData = formatResponse({
387
+ message: t({
388
+ en: "Password reset request sent successfully",
389
+ fr: "Demande de r\xE9initialisation de mot de passe envoy\xE9e avec succ\xE8s",
390
+ es: "Solicitud de restablecimiento de contrase\xF1a enviada con \xE9xito"
391
+ }),
392
+ description: t({
393
+ en: "Your password reset request has been sent successfully. Please check your email to reset your password.",
394
+ fr: "Votre demande de r\xE9initialisation de mot de passe a \xE9t\xE9 envoy\xE9e avec succ\xE8s. Veuillez v\xE9rifier votre e-mail pour r\xE9initialiser votre mot de passe.",
395
+ es: "Su solicitud de restablecimiento de contrase\xF1a ha sido enviada con \xE9xito. Por favor, revise su correo electr\xF3nico para restablecer su contrase\xF1a."
396
+ }),
397
+ data: void 0
398
+ });
218
399
  res.json(responseData);
219
400
  return;
220
401
  } catch (error) {
@@ -249,7 +430,19 @@ const resetPassword = async (req, res, _next) => {
249
430
  username: updatedUser.name
250
431
  });
251
432
  const formattedUser = mapUserToAPI(updatedUser);
252
- const responseData = formatResponse({ data: formattedUser });
433
+ const responseData = formatResponse({
434
+ message: t({
435
+ en: "Password reset successfully",
436
+ fr: "R\xE9initialisation du mot de passe r\xE9ussie",
437
+ es: "Restablecimiento de contrase\xF1a exitoso"
438
+ }),
439
+ description: t({
440
+ en: "Your password has been reset successfully. You can now log in with your new password",
441
+ fr: "Votre mot de passe a \xE9t\xE9 r\xE9initialis\xE9 avec succ\xE8s. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe",
442
+ es: "Su contrase\xF1a ha sido restablecida con \xE9xito. Ahora puede iniciar sesi\xF3n con su nueva contrase\xF1a"
443
+ }),
444
+ data: formattedUser
445
+ });
253
446
  res.json(responseData);
254
447
  return;
255
448
  } catch (error) {
@@ -265,15 +458,19 @@ const getSessionInformation = async (req, res, _next) => {
265
458
  if (sessionToken) {
266
459
  user = await userService.getUserBySession(sessionToken);
267
460
  }
268
- if (!user) {
269
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
461
+ if (!user || !user?.session) {
462
+ const responseData2 = formatResponse({
463
+ data: {
464
+ session: null,
465
+ user: null,
466
+ organization: organization?._id ? mapOrganizationToAPI(organization, isOrganizationAdmin) : null,
467
+ project: project?._id ? mapProjectToAPI(project, user, isProjectAdmin) : null
468
+ }
469
+ });
470
+ res.json(responseData2);
270
471
  return;
271
472
  }
272
473
  const session = user.session;
273
- if (!session) {
274
- ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_FOUND");
275
- return;
276
- }
277
474
  const formattedUser = {
278
475
  ...mapUserToAPI(user),
279
476
  role: "user"
@@ -300,11 +497,15 @@ const githubLoginQuery = (req, res, _next) => {
300
497
  ErrorHandler.handleGenericErrorResponse(res, "USER_ALREADY_LOGGED_IN");
301
498
  return;
302
499
  }
500
+ if (origin && !origin.startsWith(process.env.CLIENT_URL ?? "")) {
501
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
502
+ return;
503
+ }
303
504
  const encodedOrigin = encodeURIComponent(origin);
304
505
  const redirectURI = `${process.env.BACKEND_URL}/api/auth/callback/github?redirect_uri=${encodedOrigin}`;
305
506
  const encodedRedirectURI = encodeURIComponent(redirectURI);
306
507
  res.redirect(
307
- `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodedRedirectURI}`
508
+ `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodedRedirectURI}&scope=user:email`
308
509
  );
309
510
  };
310
511
  const githubCallback = async (req, res, _next) => {
@@ -321,6 +522,10 @@ const githubCallback = async (req, res, _next) => {
321
522
  res.redirect(redirect_uri);
322
523
  return;
323
524
  }
525
+ if (redirect_uri && !redirect_uri.startsWith(process.env.CLIENT_URL ?? "")) {
526
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
527
+ return;
528
+ }
324
529
  try {
325
530
  const tokenResponse = await fetch(
326
531
  "https://github.com/login/oauth/access_token",
@@ -418,7 +623,7 @@ const githubCallback = async (req, res, _next) => {
418
623
  type: "welcome",
419
624
  to: user.email,
420
625
  username: user.name,
421
- loginLink: sessionAuthRoutes.loginEmailPassword.url
626
+ loginLink: `${process.env.CLIENT_URL}/auth/login`
422
627
  });
423
628
  res.redirect(redirect_uri);
424
629
  } catch (error) {
@@ -435,6 +640,10 @@ const googleLoginQuery = (req, res, _next) => {
435
640
  res.redirect(origin);
436
641
  return;
437
642
  }
643
+ if (origin && !origin.startsWith(process.env.CLIENT_URL ?? "")) {
644
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
645
+ return;
646
+ }
438
647
  const responseType = "code";
439
648
  const scope = [
440
649
  "https%3A//www.googleapis.com/auth/userinfo.email",
@@ -466,6 +675,10 @@ const googleCallback = async (req, res, _next) => {
466
675
  res.redirect(responseCode, redirect_uri);
467
676
  return;
468
677
  }
678
+ if (redirect_uri && !redirect_uri.startsWith(process.env.CLIENT_URL ?? "")) {
679
+ ErrorHandler.handleGenericErrorResponse(res, "CALLBACK_URL_NOT_VALID");
680
+ return;
681
+ }
469
682
  try {
470
683
  const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
471
684
  method: "POST",
@@ -554,8 +767,9 @@ const googleCallback = async (req, res, _next) => {
554
767
  type: "welcome",
555
768
  to: user.email,
556
769
  username: user.name,
557
- loginLink: sessionAuthRoutes.loginEmailPassword.url
770
+ loginLink: `${process.env.CLIENT_URL}/auth/login`
558
771
  });
772
+ res.redirect(redirect_uri);
559
773
  } catch (error) {
560
774
  ErrorHandler.handleAppErrorResponse(res, error);
561
775
  return;
@@ -563,6 +777,7 @@ const googleCallback = async (req, res, _next) => {
563
777
  };
564
778
  export {
565
779
  askResetPassword,
780
+ checkIfUserHasPassword,
566
781
  getSessionInformation,
567
782
  githubCallback,
568
783
  githubLoginQuery,
@@ -572,8 +787,10 @@ export {
572
787
  loginEmailPassword,
573
788
  registerEmailPassword,
574
789
  resetPassword,
790
+ sendVerificationUpdate,
575
791
  setCSRFToken,
576
792
  updatePassword,
577
- validEmail
793
+ validEmail,
794
+ verifyEmailStatusSSE
578
795
  };
579
796
  //# sourceMappingURL=sessionAuth.controller.mjs.map