@intlayer/backend 3.1.0 → 3.2.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.
- package/dist/cjs/controllers/dictionary.controller.cjs +41 -0
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/controllers/organization.controller.cjs +73 -4
- package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
- package/dist/cjs/controllers/project.controller.cjs +71 -7
- package/dist/cjs/controllers/project.controller.cjs.map +1 -1
- package/dist/cjs/controllers/projectAccessKey.controller.cjs +31 -0
- package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
- package/dist/cjs/controllers/sessionAuth.controller.cjs +277 -57
- package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
- package/dist/cjs/controllers/stripe.controller.cjs +84 -0
- package/dist/cjs/controllers/stripe.controller.cjs.map +1 -0
- package/dist/cjs/controllers/user.controller.cjs +40 -3
- package/dist/cjs/controllers/user.controller.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs +182 -0
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs.map +1 -0
- package/dist/cjs/emails/SubscriptionPaymentError.cjs +182 -0
- package/dist/cjs/emails/SubscriptionPaymentError.cjs.map +1 -0
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs +188 -0
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs.map +1 -0
- package/dist/cjs/export.cjs.map +1 -1
- package/dist/cjs/index.cjs +15 -5
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs +4 -6
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
- package/dist/cjs/routes/dictionary.routes.cjs +2 -62
- package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
- package/dist/cjs/routes/organization.routes.cjs +1 -25
- package/dist/cjs/routes/organization.routes.cjs.map +1 -1
- package/dist/cjs/routes/project.routes.cjs +10 -85
- package/dist/cjs/routes/project.routes.cjs.map +1 -1
- package/dist/cjs/routes/sessionAuth.routes.cjs +26 -25
- package/dist/cjs/routes/sessionAuth.routes.cjs.map +1 -1
- package/dist/cjs/{models/plan.moddel.cjs → routes/stripe.routes.cjs} +20 -9
- package/dist/cjs/routes/stripe.routes.cjs.map +1 -0
- package/dist/cjs/routes/user.routes.cjs +6 -27
- package/dist/cjs/routes/user.routes.cjs.map +1 -1
- package/dist/cjs/schemas/organization.schema.cjs +5 -0
- package/dist/cjs/schemas/organization.schema.cjs.map +1 -1
- package/dist/cjs/schemas/plans.schema.cjs +2 -8
- package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
- package/dist/cjs/schemas/user.schema.cjs +1 -1
- package/dist/cjs/schemas/user.schema.cjs.map +1 -1
- package/dist/cjs/services/email.service.cjs +113 -43
- package/dist/cjs/services/email.service.cjs.map +1 -1
- package/dist/cjs/services/organization.service.cjs +55 -8
- package/dist/cjs/services/organization.service.cjs.map +1 -1
- package/dist/cjs/services/project.service.cjs +1 -3
- package/dist/cjs/services/project.service.cjs.map +1 -1
- package/dist/cjs/services/sessionAuth.service.cjs +9 -11
- package/dist/cjs/services/sessionAuth.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +134 -51
- package/dist/cjs/services/subscription.service.cjs.map +1 -1
- package/dist/cjs/services/user.service.cjs +1 -3
- package/dist/cjs/services/user.service.cjs.map +1 -1
- package/dist/cjs/types/organization.types.cjs.map +1 -1
- package/dist/cjs/types/plan.types.cjs.map +1 -1
- package/dist/cjs/types/session.types.cjs.map +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs +29 -9
- package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
- package/dist/cjs/utils/errors/ErrorsClass.cjs +17 -3
- package/dist/cjs/utils/errors/ErrorsClass.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +99 -8
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/mapper/project.cjs +1 -1
- package/dist/cjs/utils/mapper/project.cjs.map +1 -1
- package/dist/cjs/utils/plan.cjs +7 -2
- package/dist/cjs/utils/plan.cjs.map +1 -1
- package/dist/cjs/utils/responseData.cjs +8 -0
- package/dist/cjs/utils/responseData.cjs.map +1 -1
- package/dist/cjs/webhooks/stripe.webhook.cjs +133 -0
- package/dist/cjs/webhooks/stripe.webhook.cjs.map +1 -0
- package/dist/esm/controllers/dictionary.controller.mjs +41 -0
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/controllers/organization.controller.mjs +73 -4
- package/dist/esm/controllers/organization.controller.mjs.map +1 -1
- package/dist/esm/controllers/project.controller.mjs +71 -7
- package/dist/esm/controllers/project.controller.mjs.map +1 -1
- package/dist/esm/controllers/projectAccessKey.controller.mjs +31 -0
- package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
- package/dist/esm/controllers/sessionAuth.controller.mjs +273 -56
- package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
- package/dist/esm/controllers/stripe.controller.mjs +60 -0
- package/dist/esm/controllers/stripe.controller.mjs.map +1 -0
- package/dist/esm/controllers/user.controller.mjs +40 -3
- package/dist/esm/controllers/user.controller.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs +168 -0
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -0
- package/dist/esm/emails/SubscriptionPaymentError.mjs +168 -0
- package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -0
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs +174 -0
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -0
- package/dist/esm/export.mjs.map +1 -1
- package/dist/esm/index.mjs +15 -5
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares/sessionAuth.middleware.mjs +4 -6
- package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
- package/dist/esm/routes/dictionary.routes.mjs +2 -62
- package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
- package/dist/esm/routes/organization.routes.mjs +1 -25
- package/dist/esm/routes/organization.routes.mjs.map +1 -1
- package/dist/esm/routes/project.routes.mjs +10 -85
- package/dist/esm/routes/project.routes.mjs.map +1 -1
- package/dist/esm/routes/sessionAuth.routes.mjs +29 -26
- package/dist/esm/routes/sessionAuth.routes.mjs.map +1 -1
- package/dist/esm/routes/stripe.routes.mjs +17 -0
- package/dist/esm/routes/stripe.routes.mjs.map +1 -0
- package/dist/esm/routes/user.routes.mjs +6 -27
- package/dist/esm/routes/user.routes.mjs.map +1 -1
- package/dist/esm/schemas/organization.schema.mjs +5 -0
- package/dist/esm/schemas/organization.schema.mjs.map +1 -1
- package/dist/esm/schemas/plans.schema.mjs +2 -8
- package/dist/esm/schemas/plans.schema.mjs.map +1 -1
- package/dist/esm/schemas/user.schema.mjs +1 -1
- package/dist/esm/schemas/user.schema.mjs.map +1 -1
- package/dist/esm/services/email.service.mjs +125 -43
- package/dist/esm/services/email.service.mjs.map +1 -1
- package/dist/esm/services/organization.service.mjs +51 -7
- package/dist/esm/services/organization.service.mjs.map +1 -1
- package/dist/esm/services/project.service.mjs +1 -3
- package/dist/esm/services/project.service.mjs.map +1 -1
- package/dist/esm/services/sessionAuth.service.mjs +9 -10
- package/dist/esm/services/sessionAuth.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +136 -53
- package/dist/esm/services/subscription.service.mjs.map +1 -1
- package/dist/esm/services/user.service.mjs +1 -3
- package/dist/esm/services/user.service.mjs.map +1 -1
- package/dist/esm/utils/errors/ErrorHandler.mjs +29 -9
- package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
- package/dist/esm/utils/errors/ErrorsClass.mjs +17 -3
- package/dist/esm/utils/errors/ErrorsClass.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +99 -8
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/mapper/project.mjs +1 -1
- package/dist/esm/utils/mapper/project.mjs.map +1 -1
- package/dist/esm/utils/plan.mjs +7 -2
- package/dist/esm/utils/plan.mjs.map +1 -1
- package/dist/esm/utils/responseData.mjs +8 -0
- package/dist/esm/utils/responseData.mjs.map +1 -1
- package/dist/esm/webhooks/stripe.webhook.mjs +113 -0
- package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -0
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/controllers/organization.controller.d.ts.map +1 -1
- package/dist/types/controllers/project.controller.d.ts.map +1 -1
- package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
- package/dist/types/controllers/sessionAuth.controller.d.ts +24 -5
- package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
- package/dist/types/controllers/stripe.controller.d.ts +17 -0
- package/dist/types/controllers/stripe.controller.d.ts.map +1 -0
- package/dist/types/controllers/user.controller.d.ts.map +1 -1
- package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +20 -0
- package/dist/types/emails/SubscriptionPaymentCancellation.d.ts.map +1 -0
- package/dist/types/emails/SubscriptionPaymentError.d.ts +20 -0
- package/dist/types/emails/SubscriptionPaymentError.d.ts.map +1 -0
- package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +20 -0
- package/dist/types/emails/SubscriptionPaymentSuccess.d.ts.map +1 -0
- package/dist/types/export.d.ts +1 -0
- package/dist/types/export.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
- package/dist/types/models/organization.model.d.ts +1 -0
- package/dist/types/models/organization.model.d.ts.map +1 -1
- package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
- package/dist/types/routes/organization.routes.d.ts.map +1 -1
- package/dist/types/routes/project.routes.d.ts.map +1 -1
- package/dist/types/routes/sessionAuth.routes.d.ts +15 -2
- package/dist/types/routes/sessionAuth.routes.d.ts.map +1 -1
- package/dist/types/routes/stripe.routes.d.ts +10 -0
- package/dist/types/routes/stripe.routes.d.ts.map +1 -0
- package/dist/types/routes/user.routes.d.ts.map +1 -1
- package/dist/types/schemas/organization.schema.d.ts +1 -0
- package/dist/types/schemas/organization.schema.d.ts.map +1 -1
- package/dist/types/schemas/plans.schema.d.ts.map +1 -1
- package/dist/types/services/email.service.d.ts +33 -4
- package/dist/types/services/email.service.d.ts.map +1 -1
- package/dist/types/services/organization.service.d.ts +15 -0
- package/dist/types/services/organization.service.d.ts.map +1 -1
- package/dist/types/services/project.service.d.ts.map +1 -1
- package/dist/types/services/sessionAuth.service.d.ts +1 -8
- package/dist/types/services/sessionAuth.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +20 -5
- package/dist/types/services/subscription.service.d.ts.map +1 -1
- package/dist/types/services/user.service.d.ts.map +1 -1
- package/dist/types/types/organization.types.d.ts +2 -0
- package/dist/types/types/organization.types.d.ts.map +1 -1
- package/dist/types/types/plan.types.d.ts +2 -3
- package/dist/types/types/plan.types.d.ts.map +1 -1
- package/dist/types/types/session.types.d.ts +6 -6
- package/dist/types/types/session.types.d.ts.map +1 -1
- package/dist/types/utils/errors/ErrorHandler.d.ts +5 -3
- package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
- package/dist/types/utils/errors/ErrorsClass.d.ts +4 -1
- package/dist/types/utils/errors/ErrorsClass.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +92 -1
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/utils/mapper/project.d.ts +1 -1
- package/dist/types/utils/mapper/project.d.ts.map +1 -1
- package/dist/types/utils/plan.d.ts +1 -1
- package/dist/types/utils/plan.d.ts.map +1 -1
- package/dist/types/utils/responseData.d.ts +13 -2
- package/dist/types/utils/responseData.d.ts.map +1 -1
- package/dist/types/webhooks/stripe.d.ts.map +1 -1
- package/dist/types/webhooks/stripe.webhook.d.ts +3 -0
- package/dist/types/webhooks/stripe.webhook.d.ts.map +1 -0
- package/package.json +6 -5
- package/dist/cjs/models/plan.moddel.cjs.map +0 -1
- package/dist/cjs/services/plans.service.cjs +0 -72
- package/dist/cjs/services/plans.service.cjs.map +0 -1
- package/dist/cjs/webhooks/stripe.cjs +0 -94
- package/dist/cjs/webhooks/stripe.cjs.map +0 -1
- package/dist/esm/models/plan.moddel.mjs +0 -7
- package/dist/esm/models/plan.moddel.mjs.map +0 -1
- package/dist/esm/services/plans.service.mjs +0 -44
- package/dist/esm/services/plans.service.mjs.map +0 -1
- package/dist/esm/webhooks/stripe.mjs +0 -70
- 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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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(
|
|
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
|
|
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({
|
|
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({
|
|
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({
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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({
|
|
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
|
|
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
|
-
|
|
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:
|
|
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({
|
|
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({
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|