@intlayer/backend 3.0.2 → 3.1.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 +50 -18
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/controllers/organization.controller.cjs +71 -12
- package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
- package/dist/cjs/controllers/project.controller.cjs +117 -31
- package/dist/cjs/controllers/project.controller.cjs.map +1 -1
- package/dist/cjs/controllers/projectAccessKey.controller.cjs +30 -10
- package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
- package/dist/cjs/controllers/sessionAuth.controller.cjs +16 -7
- package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
- package/dist/cjs/controllers/user.controller.cjs +9 -17
- package/dist/cjs/controllers/user.controller.cjs.map +1 -1
- package/dist/cjs/export.cjs.map +1 -1
- package/dist/cjs/index.cjs +3 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/oAuth2.middleware.cjs +10 -0
- package/dist/cjs/middlewares/oAuth2.middleware.cjs.map +1 -1
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs +49 -7
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
- package/dist/cjs/{middlewares/admin.middleware.cjs → models/plan.moddel.cjs} +9 -22
- package/dist/cjs/models/plan.moddel.cjs.map +1 -0
- package/dist/cjs/schemas/plans.schema.cjs +62 -0
- package/dist/cjs/schemas/plans.schema.cjs.map +1 -0
- package/dist/cjs/schemas/project.schema.cjs +14 -1
- package/dist/cjs/schemas/project.schema.cjs.map +1 -1
- package/dist/cjs/schemas/user.schema.cjs +4 -0
- package/dist/cjs/schemas/user.schema.cjs.map +1 -1
- package/dist/cjs/services/dictionary.service.cjs.map +1 -1
- package/dist/cjs/services/oAuth2.service.cjs +16 -8
- package/dist/cjs/services/oAuth2.service.cjs.map +1 -1
- package/dist/cjs/services/organization.service.cjs +8 -0
- package/dist/cjs/services/organization.service.cjs.map +1 -1
- package/dist/cjs/services/plans.service.cjs +72 -0
- package/dist/cjs/services/plans.service.cjs.map +1 -0
- package/dist/cjs/services/project.service.cjs +8 -2
- package/dist/cjs/services/project.service.cjs.map +1 -1
- package/dist/cjs/services/projectAccessKey.service.cjs +42 -10
- package/dist/cjs/services/projectAccessKey.service.cjs.map +1 -1
- package/dist/cjs/services/sessionAuth.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +118 -0
- package/dist/cjs/services/subscription.service.cjs.map +1 -0
- package/dist/cjs/services/user.service.cjs.map +1 -1
- package/dist/cjs/types/dictionary.types.cjs.map +1 -1
- package/dist/cjs/types/organization.types.cjs.map +1 -1
- package/dist/cjs/types/plan.types.cjs +17 -0
- package/dist/cjs/types/plan.types.cjs.map +1 -0
- package/dist/cjs/types/project.types.cjs.map +1 -1
- package/dist/cjs/types/user.types.cjs.map +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +222 -1
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
- package/dist/cjs/utils/mapper/project.cjs +19 -3
- package/dist/cjs/utils/mapper/project.cjs.map +1 -1
- package/dist/cjs/utils/mapper/user.cjs.map +1 -1
- package/dist/cjs/utils/plan.cjs +70 -0
- package/dist/cjs/utils/plan.cjs.map +1 -0
- package/dist/cjs/webhooks/stripe.cjs +94 -0
- package/dist/cjs/webhooks/stripe.cjs.map +1 -0
- package/dist/esm/controllers/dictionary.controller.mjs +50 -18
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/controllers/organization.controller.mjs +71 -12
- package/dist/esm/controllers/organization.controller.mjs.map +1 -1
- package/dist/esm/controllers/project.controller.mjs +117 -31
- package/dist/esm/controllers/project.controller.mjs.map +1 -1
- package/dist/esm/controllers/projectAccessKey.controller.mjs +30 -10
- package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
- package/dist/esm/controllers/sessionAuth.controller.mjs +16 -7
- package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
- package/dist/esm/controllers/user.controller.mjs +9 -17
- package/dist/esm/controllers/user.controller.mjs.map +1 -1
- package/dist/esm/export.mjs.map +1 -1
- package/dist/esm/index.mjs +6 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares/oAuth2.middleware.mjs +10 -0
- package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
- package/dist/esm/middlewares/sessionAuth.middleware.mjs +48 -6
- package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
- package/dist/esm/models/plan.moddel.mjs +7 -0
- package/dist/esm/models/plan.moddel.mjs.map +1 -0
- package/dist/esm/schemas/plans.schema.mjs +38 -0
- package/dist/esm/schemas/plans.schema.mjs.map +1 -0
- package/dist/esm/schemas/project.schema.mjs +13 -1
- package/dist/esm/schemas/project.schema.mjs.map +1 -1
- package/dist/esm/schemas/user.schema.mjs +4 -0
- package/dist/esm/schemas/user.schema.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/services/oAuth2.service.mjs +16 -8
- package/dist/esm/services/oAuth2.service.mjs.map +1 -1
- package/dist/esm/services/organization.service.mjs +7 -0
- package/dist/esm/services/organization.service.mjs.map +1 -1
- package/dist/esm/services/plans.service.mjs +44 -0
- package/dist/esm/services/plans.service.mjs.map +1 -0
- package/dist/esm/services/project.service.mjs +8 -2
- package/dist/esm/services/project.service.mjs.map +1 -1
- package/dist/esm/services/projectAccessKey.service.mjs +42 -10
- package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
- package/dist/esm/services/sessionAuth.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +95 -0
- package/dist/esm/services/subscription.service.mjs.map +1 -0
- package/dist/esm/services/user.service.mjs.map +1 -1
- package/dist/esm/types/plan.types.mjs +1 -0
- package/dist/esm/types/plan.types.mjs.map +1 -0
- package/dist/esm/utils/errors/ErrorHandler.mjs +1 -1
- package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +222 -1
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/mapper/organization.mjs.map +1 -1
- package/dist/esm/utils/mapper/project.mjs +17 -2
- package/dist/esm/utils/mapper/project.mjs.map +1 -1
- package/dist/esm/utils/mapper/user.mjs.map +1 -1
- package/dist/esm/utils/plan.mjs +45 -0
- package/dist/esm/utils/plan.mjs.map +1 -0
- package/dist/esm/webhooks/stripe.mjs +70 -0
- package/dist/esm/webhooks/stripe.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 +9 -7
- 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 +4 -4
- package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
- package/dist/types/controllers/user.controller.d.ts.map +1 -1
- 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/oAuth2.middleware.d.ts.map +1 -1
- package/dist/types/middlewares/sessionAuth.middleware.d.ts +13 -7
- package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
- package/dist/types/models/dictionary.model.d.ts +1 -1
- package/dist/types/models/oAuth2.model.d.ts +1 -1
- package/dist/types/models/organization.model.d.ts +1 -1
- package/dist/types/models/plan.moddel.d.ts +11 -0
- package/dist/types/models/plan.moddel.d.ts.map +1 -0
- package/dist/types/models/project.model.d.ts +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts +2 -2
- package/dist/types/schemas/oAuth2.schema.d.ts +2 -2
- package/dist/types/schemas/organization.schema.d.ts +2 -2
- package/dist/types/schemas/plans.schema.d.ts +16 -0
- package/dist/types/schemas/plans.schema.d.ts.map +1 -0
- package/dist/types/schemas/project.schema.d.ts +12 -3
- package/dist/types/schemas/project.schema.d.ts.map +1 -1
- package/dist/types/schemas/user.schema.d.ts +2 -2
- package/dist/types/schemas/user.schema.d.ts.map +1 -1
- package/dist/types/services/dictionary.service.d.ts +9 -9
- package/dist/types/services/dictionary.service.d.ts.map +1 -1
- package/dist/types/services/oAuth2.service.d.ts +7 -5
- package/dist/types/services/oAuth2.service.d.ts.map +1 -1
- package/dist/types/services/organization.service.d.ts +12 -6
- package/dist/types/services/organization.service.d.ts.map +1 -1
- package/dist/types/services/plans.service.d.ts +35 -0
- package/dist/types/services/plans.service.d.ts.map +1 -0
- package/dist/types/services/project.service.d.ts +6 -6
- package/dist/types/services/project.service.d.ts.map +1 -1
- package/dist/types/services/projectAccessKey.service.d.ts +4 -4
- package/dist/types/services/projectAccessKey.service.d.ts.map +1 -1
- package/dist/types/services/sessionAuth.service.d.ts +9 -9
- package/dist/types/services/sessionAuth.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +7 -0
- package/dist/types/services/subscription.service.d.ts.map +1 -0
- package/dist/types/services/user.service.d.ts +11 -19
- package/dist/types/services/user.service.d.ts.map +1 -1
- package/dist/types/types/dictionary.types.d.ts +2 -2
- package/dist/types/types/dictionary.types.d.ts.map +1 -1
- package/dist/types/types/organization.types.d.ts +2 -2
- package/dist/types/types/organization.types.d.ts.map +1 -1
- package/dist/types/types/plan.types.d.ts +19 -0
- package/dist/types/types/plan.types.d.ts.map +1 -0
- package/dist/types/types/project.types.d.ts +13 -2
- package/dist/types/types/project.types.d.ts.map +1 -1
- package/dist/types/types/user.types.d.ts +2 -1
- package/dist/types/types/user.types.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +221 -0
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/utils/mapper/organization.d.ts +1 -1
- package/dist/types/utils/mapper/organization.d.ts.map +1 -1
- package/dist/types/utils/mapper/project.d.ts +10 -1
- package/dist/types/utils/mapper/project.d.ts.map +1 -1
- package/dist/types/utils/mapper/user.d.ts +1 -1
- package/dist/types/utils/mapper/user.d.ts.map +1 -1
- package/dist/types/utils/plan.d.ts +17 -0
- package/dist/types/utils/plan.d.ts.map +1 -0
- package/dist/types/webhooks/stripe.d.ts +3 -0
- package/dist/types/webhooks/stripe.d.ts.map +1 -0
- package/package.json +25 -23
- package/dist/cjs/middlewares/admin.middleware.cjs.map +0 -1
- package/dist/esm/middlewares/admin.middleware.mjs +0 -20
- package/dist/esm/middlewares/admin.middleware.mjs.map +0 -1
|
@@ -6,6 +6,8 @@ import * as userService from './../services/user.service.mjs';
|
|
|
6
6
|
import { generateToken } from './../utils/CSRF.mjs';
|
|
7
7
|
import { ErrorHandler, GenericError } from './../utils/errors/index.mjs';
|
|
8
8
|
import { HttpStatusCodes } from './../utils/httpStatusCodes.mjs';
|
|
9
|
+
import { mapOrganizationToAPI } from './../utils/mapper/organization.mjs';
|
|
10
|
+
import { mapProjectToAPI } from './../utils/mapper/project.mjs';
|
|
9
11
|
import { mapUserToAPI } from './../utils/mapper/user.mjs';
|
|
10
12
|
import { formatResponse } from './../utils/responseData.mjs';
|
|
11
13
|
import { Types } from "mongoose";
|
|
@@ -107,7 +109,7 @@ const loginEmailPassword = async (req, res, _next) => {
|
|
|
107
109
|
const logOut = async (_req, res, _next) => {
|
|
108
110
|
const { user } = res.locals;
|
|
109
111
|
if (!user) {
|
|
110
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
112
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
111
113
|
return;
|
|
112
114
|
}
|
|
113
115
|
await sessionAuthService.clearUserAuth(res);
|
|
@@ -121,7 +123,7 @@ const updatePassword = async (req, res, _next) => {
|
|
|
121
123
|
const { oldPassword, newPassword } = req.body;
|
|
122
124
|
let { user } = res.locals;
|
|
123
125
|
if (!user) {
|
|
124
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
126
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
125
127
|
return;
|
|
126
128
|
}
|
|
127
129
|
try {
|
|
@@ -162,12 +164,14 @@ const validEmail = async (req, res, _next) => {
|
|
|
162
164
|
return;
|
|
163
165
|
}
|
|
164
166
|
if (!organization) {
|
|
165
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
167
|
+
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
166
168
|
return;
|
|
167
169
|
}
|
|
168
170
|
const user = await userService.getUserById(userId);
|
|
169
171
|
if (!user) {
|
|
170
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
172
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED", {
|
|
173
|
+
userId
|
|
174
|
+
});
|
|
171
175
|
return;
|
|
172
176
|
}
|
|
173
177
|
await sessionAuthService.activateUser(user._id, secret);
|
|
@@ -256,13 +260,13 @@ const resetPassword = async (req, res, _next) => {
|
|
|
256
260
|
const getSessionInformation = async (req, res, _next) => {
|
|
257
261
|
const { session_token: sessionToken } = req.query;
|
|
258
262
|
let { user } = res.locals;
|
|
259
|
-
const { organization, project } = res.locals;
|
|
263
|
+
const { organization, project, isOrganizationAdmin, isProjectAdmin } = res.locals;
|
|
260
264
|
try {
|
|
261
265
|
if (sessionToken) {
|
|
262
266
|
user = await userService.getUserBySession(sessionToken);
|
|
263
267
|
}
|
|
264
268
|
if (!user) {
|
|
265
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
269
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
266
270
|
return;
|
|
267
271
|
}
|
|
268
272
|
const session = user.session;
|
|
@@ -275,7 +279,12 @@ const getSessionInformation = async (req, res, _next) => {
|
|
|
275
279
|
role: "user"
|
|
276
280
|
};
|
|
277
281
|
const responseData = formatResponse({
|
|
278
|
-
data: {
|
|
282
|
+
data: {
|
|
283
|
+
session,
|
|
284
|
+
user: formattedUser,
|
|
285
|
+
organization: organization?._id ? mapOrganizationToAPI(organization, isOrganizationAdmin) : null,
|
|
286
|
+
project: project?._id ? mapProjectToAPI(project, user, isProjectAdmin) : null
|
|
287
|
+
}
|
|
279
288
|
});
|
|
280
289
|
res.json(responseData);
|
|
281
290
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/sessionAuth.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport * as sessionAuthService from '@services/sessionAuth.service';\nimport * as userService from '@services/user.service';\nimport { generateToken } from '@utils/CSRF';\nimport { ErrorHandler, AppError, GenericError } from '@utils/errors';\nimport { HttpStatusCodes } from '@utils/httpStatusCodes';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\nimport { Types } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Organization } from '@/types/organization.types';\nimport { Project } from '@/types/project.types';\nimport type {\n Session,\n GithubSessionProvider,\n GoogleSessionProvider,\n} from '@/types/session.types';\nimport type { UserAPI, UserData } from '@/types/user.types';\n\nexport type CSRFTokenData = { csrf_token: string };\nexport type SetCSRFTokenResult = ResponseData<CSRFTokenData>;\n\nexport const setCSRFToken = (\n req: Request,\n res: Response<SetCSRFTokenResult>,\n _next: NextFunction\n) => {\n const csrf_token = generateToken(req, res);\n\n const responseData = formatResponse<CSRFTokenData>({\n data: { csrf_token },\n });\n\n res.locals.csrf_token = csrf_token;\n res.json(responseData);\n};\n\nexport type RegisterBody = { email: string; password: string };\nexport type RegisterResult = ResponseData<UserAPI>;\n\n/**\n * Handles user registration.\n */\nexport const registerEmailPassword = async (\n req: Request<any, any, RegisterBody>,\n res: ResponseWithInformation<RegisterResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const userData = req.body;\n\n try {\n let user = await userService.getUserByEmail(userData.email);\n\n if (user) {\n const emailProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (emailProvider) {\n if (emailProvider.emailValidated) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'EMAIL_ALREADY_VALIDATED'\n );\n return;\n } else {\n user = await sessionAuthService.updateUserProvider(\n user._id,\n 'email',\n {\n secret: uuidv4(),\n }\n );\n }\n } else {\n user = await sessionAuthService.addUserProvider(user._id, {\n provider: 'email',\n emailValidated: undefined,\n secret: uuidv4(),\n });\n }\n } else {\n user = await userService.createUser(userData);\n logger.info(`New registration: ${user.name} - ${user.email}`);\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_CREATION_FAILED', {\n email: userData.email,\n });\n return;\n }\n\n await sessionAuthService.setUserAuth(res, user);\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type LoginBody = {\n email: string;\n password: string;\n};\nexport type LoginResult = ResponseData<UserAPI>;\n\n/**\n * Handles user login.\n */\nexport const loginEmailPassword = async (\n req: Request<any, any, LoginBody>,\n res: ResponseWithInformation<LoginResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const { email, password } = req.body;\n\n try {\n const { user: loggedInUser, error } =\n await sessionAuthService.testUserPassword(email, password);\n\n if (error) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'LOGIN_FAILED');\n return;\n }\n }\n\n if (!loggedInUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n await sessionAuthService.setUserAuth(res, loggedInUser);\n\n const formattedUser = mapUserToAPI(loggedInUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n logger.info(`Login: ${loggedInUser.email}`);\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type LogoutResult = ResponseData<undefined>;\n\n/**\n * Handles user logout and clears cookies.\n */\nexport const logOut = async (\n _req: Request,\n res: ResponseWithInformation<LogoutResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n await sessionAuthService.clearUserAuth(res);\n sessionAuthService.clearOrganizationAuth(res);\n sessionAuthService.clearProjectAuth(res);\n\n logger.info(`Logout: ${user.name} - ${user.email}`);\n\n const responseData = formatResponse<undefined>({ data: undefined });\n\n res.json(responseData);\n};\n\nexport type UpdatePasswordBody = {\n oldPassword: string;\n newPassword: string;\n};\nexport type UpdatePasswordResult = ResponseData<UserAPI>;\n\n/**\n * Updates the user's password.\n */\nexport const updatePassword = async (\n req: Request<undefined, any, UpdatePasswordBody>,\n res: ResponseWithInformation<UpdatePasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { oldPassword, newPassword } = req.body;\n let { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const { error } = await sessionAuthService.testUserPassword(\n user.email,\n oldPassword\n );\n\n if (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'LOGIN_FAILED');\n return;\n }\n\n user = await sessionAuthService.changeUserPassword(\n user._id,\n oldPassword,\n newPassword\n );\n\n if (!user || typeof user !== 'object') {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND');\n return;\n }\n\n logger.info(\n `Password changed - User : Name : ${user.name}, id : ${String(user._id)}`\n );\n\n const formattedUser = mapUserToAPI(user);\n\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type ValidEmailParams = { secret: string; userId: string };\nexport type ValidEmailResult = ResponseData<UserAPI>;\n\n/**\n * Validates a user's email based on the provided secret and user ID.\n */\nexport const validEmail = async (\n req: Request<ValidEmailParams, any, any>,\n res: ResponseWithInformation<ValidEmailResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId, secret } = req.params;\n const { organization } = res.locals;\n\n if (!Types.ObjectId.isValid(userId.toString())) {\n ErrorHandler.handleGenericErrorResponse(res, 'INVALID_USER_ID');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_FOUND');\n return;\n }\n\n const user = await userService.getUserById(userId);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND', { userId });\n return;\n }\n\n await sessionAuthService.activateUser(user._id, secret);\n\n logger.info(\n `User activated - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n};\n\nexport type AskResetPasswordBody = {\n email: string;\n};\nexport type AskResetPasswordResult = ResponseData<undefined>;\n\n/**\n * Requests a password reset for a user.\n */\nexport const askResetPassword = async (\n req: Request<undefined, any, AskResetPasswordBody>,\n res: ResponseWithInformation<AskResetPasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { email } = req.body as Partial<AskResetPasswordBody>;\n\n if (!email) {\n ErrorHandler.handleGenericErrorResponse(res, 'EMAIL_NOT_PROVIDED');\n return;\n }\n\n try {\n const updatedUser = await sessionAuthService.requestPasswordReset(email);\n\n if (!updatedUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND', { email });\n return;\n }\n\n logger.info(\n `Ask changing password - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n await sendEmail({\n type: 'resetPassword',\n to: updatedUser.email,\n username: updatedUser.name,\n resetLink: sessionAuthRoutes.resetPassword.url({\n userId: String(updatedUser._id),\n secret:\n updatedUser.provider?.find(\n (provider) => provider.provider === 'email'\n )?.secret ?? '',\n }),\n });\n\n const responseData = formatResponse<undefined>({ data: undefined });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type ResetPasswordParams = { secret: string; userId: string };\nexport type ResetPasswordResult = ResponseData<UserAPI>;\n\n/**\n * Resets a user's password based on the provided secret and user ID.\n */\nexport const resetPassword = async (\n req: Request<ResetPasswordParams, any, any>,\n res: Response<ResetPasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { secret, userId } = req.params as Partial<ResetPasswordParams>;\n const password: string = req.body.password;\n\n const userIdString = String(userId);\n\n if (!userId || !userIdString || !Types.ObjectId.isValid(userIdString)) {\n ErrorHandler.handleGenericErrorResponse(res, 'INVALID_USER_ID', { userId });\n return;\n }\n\n if (!secret) {\n ErrorHandler.handleGenericErrorResponse(res, 'SECRET_NOT_PROVIDED');\n return;\n }\n\n try {\n const updatedUser = await sessionAuthService.resetUserPassword(\n userId,\n secret,\n password\n );\n\n logger.info(\n `Password changed - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n await sendEmail({\n type: 'passwordChangeConfirmation',\n to: updatedUser.email,\n username: updatedUser.name,\n });\n\n const formattedUser = mapUserToAPI(updatedUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type CreateSessionBody = {\n sessionToken: string;\n userId: string;\n expires: Date;\n};\nexport type CreateSessionResult = ResponseData<Session>;\n\nexport type GetSessionInformationQuery = {\n session_token?: string;\n};\ntype SessionInformation = {\n user: UserAPI | null;\n organization: Organization | null;\n project: Project | null;\n session: Session | null;\n};\nexport type GetSessionInformationResult = ResponseData<SessionInformation>;\n\n/**\n * Gets information about a session for a user.\n */\nexport const getSessionInformation = async (\n req: Request<undefined, undefined, undefined, GetSessionInformationQuery>,\n res: ResponseWithInformation<GetSessionInformationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { session_token: sessionToken } = req.query;\n\n let { user } = res.locals;\n const { organization, project } = res.locals;\n\n try {\n if (sessionToken) {\n user = await userService.getUserBySession(sessionToken);\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n const session = user.session;\n\n if (!session) {\n ErrorHandler.handleGenericErrorResponse(res, 'SESSION_NOT_FOUND');\n return;\n }\n\n const formattedUser: SessionInformation['user'] = {\n ...mapUserToAPI(user),\n role: 'user',\n };\n\n const responseData = formatResponse<SessionInformation>({\n data: { session, user: formattedUser, organization, project },\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GithubLoginQueryParams = {\n origin: string;\n};\nexport type GithubLoginQueryResult = ResponseData<undefined>;\n\nexport const githubLoginQuery = (\n req: Request<undefined, undefined, undefined, GithubLoginQueryParams>,\n res: ResponseWithInformation<GithubLoginQueryResult>,\n _next: NextFunction\n): void => {\n const { origin } = req.query;\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const encodedOrigin = encodeURIComponent(origin);\n\n const redirectURI = `${process.env.BACKEND_URL}/api/auth/callback/github?redirect_uri=${encodedOrigin}`;\n const encodedRedirectURI = encodeURIComponent(redirectURI);\n\n res.redirect(\n `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodedRedirectURI}`\n );\n};\n\nexport type GithubCallbackQuery = {\n code: string;\n redirect_uri: string;\n};\n\nexport type GithubCallbackResult = ResponseData<UserAPI>;\n\n/**\n * Handles GitHub OAuth callback.\n */\nexport const githubCallback = async (\n req: Request<undefined, undefined, undefined, GithubCallbackQuery>,\n res: ResponseWithInformation<GithubCallbackResult>,\n _next: NextFunction\n): Promise<void> => {\n const { code, redirect_uri } = req.query;\n\n if (!code) {\n const errorMessage = 'Code not provided';\n\n logger.error(errorMessage);\n\n res.redirect(redirect_uri);\n return;\n }\n\n if (!redirect_uri) {\n const errorMessage = 'Redirect URI not provided';\n\n logger.error(errorMessage);\n\n res.redirect(redirect_uri);\n return;\n }\n\n try {\n const tokenResponse = await fetch(\n 'https://github.com/login/oauth/access_token',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({\n client_id: process.env.GITHUB_CLIENT_ID,\n client_secret: process.env.GITHUB_CLIENT_SECRET,\n code,\n }),\n }\n );\n\n const tokenData = await tokenResponse.json();\n\n const userResponse = await fetch('https://api.github.com/user', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenData.access_token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!userResponse.ok) {\n throw new GenericError('GITHUB_FETCH_USER_DATA_FAILED', { userResponse });\n }\n\n const userData = await userResponse.json();\n\n const emailResponse = await fetch('https://api.github.com/user/emails', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenData.access_token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!emailResponse.ok) {\n throw new GenericError('GIT_HUB_FETCH_USER_EMAIL_FAILED', {\n emailResponse,\n });\n }\n\n const emails: { primary: boolean; email: string }[] =\n await emailResponse.json();\n\n const primaryEmail = emails.find((email) => email.primary)?.email;\n\n if (!primaryEmail) {\n const errorMessage = 'Primary email not found';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.NOT_FOUND_404;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n let existingUser = await userService.getUserByEmail(primaryEmail);\n\n if (existingUser) {\n const existingProvider = await sessionAuthService.getUserProvider(\n existingUser._id,\n 'github'\n );\n\n if (existingProvider?.providerAccountId !== userData.id) {\n const updatedUser = await sessionAuthService.updateUserProvider(\n existingUser._id,\n 'github',\n {\n providerAccountId: userData.id,\n }\n );\n\n logger.info(\n `GitHub login provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n if (updatedUser) {\n existingUser = updatedUser;\n }\n }\n\n const updatedUser = await userService.updateUserById(existingUser._id, {\n name: existingUser.name ?? userData.name,\n });\n\n await sessionAuthService.setUserAuth(res, updatedUser);\n\n res.redirect(redirect_uri);\n return;\n }\n\n const userInformation: UserData = {\n name: userData.name,\n email: primaryEmail,\n };\n\n const userProvider: GithubSessionProvider = {\n provider: 'github',\n providerAccountId: userData.id,\n };\n\n const user = await userService.createUser({\n ...userInformation,\n provider: [userProvider],\n });\n\n await sessionAuthService.setUserAuth(res, user);\n\n logger.info(\n `GitHub login - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n res.redirect(redirect_uri);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GoogleLoginQueryParams = {\n origin: string;\n};\n\nexport type GoogleLoginResult = ResponseData<undefined>;\n\nexport const googleLoginQuery = (\n req: Request<undefined, undefined, undefined, GoogleLoginQueryParams>,\n res: ResponseWithInformation<GoogleLoginResult>,\n _next: NextFunction\n): void => {\n const { origin } = req.query;\n const { user } = res.locals;\n\n if (user) {\n const errorMessage = `User already logged in - ${user?.email}`;\n\n logger.error(errorMessage);\n\n res.redirect(origin);\n return;\n }\n\n const responseType = 'code';\n const scope = [\n 'https%3A//www.googleapis.com/auth/userinfo.email',\n 'https%3A//www.googleapis.com/auth/userinfo.profile',\n ].join(' ');\n const includeGrantedScopes = 'false';\n\n const encodedOrigin = encodeURIComponent(origin);\n const state = JSON.stringify({ redirect_uri: encodedOrigin });\n\n const redirectURI = `${process.env.BACKEND_URL}/api/auth/callback/google`;\n\n res.redirect(\n `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.GOOGLE_CLIENT_ID}&redirect_uri=${redirectURI}&response_type=${responseType}&scope=${scope}&include_granted_scopes=${includeGrantedScopes}&state=${state}`\n );\n};\n\nexport type GoogleCallbackQuery = {\n code: string;\n state: string;\n};\n\nexport type GoogleCallbackResult = ResponseData<UserAPI>;\n\n/**\n * Handles Google OAuth 2 callback.\n */\nexport const googleCallback = async (\n req: Request<undefined, undefined, undefined, GoogleCallbackQuery>,\n res: ResponseWithInformation<GoogleCallbackResult>,\n _next: NextFunction\n): Promise<void> => {\n const { code, state } = req.query;\n\n const decodedState = decodeURIComponent(state);\n const { redirect_uri } = JSON.parse(decodedState);\n\n if (!code) {\n const errorMessage = 'code not provided';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.BAD_REQUEST_400;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n if (!redirect_uri) {\n const errorMessage = 'Redirect URI not provided';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.BAD_REQUEST_400;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n try {\n // Exchange the authorization code for an access token\n const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n code,\n redirect_uri: `${process.env.BACKEND_URL}/api/auth/callback/google`,\n client_id: process.env.GOOGLE_CLIENT_ID!,\n client_secret: process.env.GOOGLE_CLIENT_SECRET!,\n grant_type: 'authorization_code',\n }),\n });\n\n const responseData = await tokenResponse.json();\n\n const { access_token: accessToken } = responseData;\n\n if (!accessToken) {\n const errorMessage = 'Failed to fetch access_token';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.INTERNAL_SERVER_ERROR_500;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n const userResponse = await fetch(\n 'https://www.googleapis.com/oauth2/v3/userinfo',\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n const userData = await userResponse.json();\n\n if (!userData.email) {\n const errorMessage = 'Failed to fetch user data from Google';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.INTERNAL_SERVER_ERROR_500;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n let existingUser = await userService.getUserByEmail(userData.email);\n\n if (existingUser) {\n const existingProvider = await sessionAuthService.getUserProvider(\n existingUser._id,\n 'google'\n );\n\n if (existingProvider?.providerAccountId !== userData.sub) {\n const updatedUser = await sessionAuthService.updateUserProvider(\n existingUser._id,\n 'google',\n {\n providerAccountId: userData.id,\n }\n );\n\n logger.info(\n `Google login provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n if (updatedUser) {\n existingUser = updatedUser;\n }\n }\n\n const updatedUser = await userService.updateUserById(existingUser._id, {\n name: existingUser.name ?? userData.name,\n });\n\n await sessionAuthService.setUserAuth(res, updatedUser);\n\n res.redirect(redirect_uri);\n return;\n }\n\n const userInformation: UserData = {\n name: userData.name,\n email: userData.email,\n };\n\n const userProvider: GoogleSessionProvider = {\n provider: 'google',\n providerAccountId: userData.id,\n };\n\n const user = await userService.createUser({\n ...userInformation,\n provider: [userProvider],\n });\n\n await sessionAuthService.setUserAuth(res, user);\n\n logger.info(\n `Google login - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n // res.redirect(redirect_uri);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":["user","updatedUser"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/sessionAuth.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport * as sessionAuthService from '@services/sessionAuth.service';\nimport * as userService from '@services/user.service';\nimport { generateToken } from '@utils/CSRF';\nimport { ErrorHandler, AppError, GenericError } from '@utils/errors';\nimport { HttpStatusCodes } from '@utils/httpStatusCodes';\nimport { mapOrganizationToAPI } from '@utils/mapper/organization';\nimport { mapProjectToAPI } from '@utils/mapper/project';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\nimport { Types } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Organization, OrganizationAPI } from '@/types/organization.types';\nimport { Project, ProjectAPI } from '@/types/project.types';\nimport type {\n Session,\n GithubSessionProvider,\n GoogleSessionProvider,\n} from '@/types/session.types';\nimport type { UserAPI, UserData } from '@/types/user.types';\n\nexport type CSRFTokenData = { csrf_token: string };\nexport type SetCSRFTokenResult = ResponseData<CSRFTokenData>;\n\nexport const setCSRFToken = (\n req: Request,\n res: Response<SetCSRFTokenResult>,\n _next: NextFunction\n) => {\n const csrf_token = generateToken(req, res);\n\n const responseData = formatResponse<CSRFTokenData>({\n data: { csrf_token },\n });\n\n res.locals.csrf_token = csrf_token;\n res.json(responseData);\n};\n\nexport type RegisterBody = { email: string; password: string };\nexport type RegisterResult = ResponseData<UserAPI>;\n\n/**\n * Handles user registration.\n */\nexport const registerEmailPassword = async (\n req: Request<any, any, RegisterBody>,\n res: ResponseWithInformation<RegisterResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const userData = req.body;\n\n try {\n let user = await userService.getUserByEmail(userData.email);\n\n if (user) {\n const emailProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (emailProvider) {\n if (emailProvider.emailValidated) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'EMAIL_ALREADY_VALIDATED'\n );\n return;\n } else {\n user = await sessionAuthService.updateUserProvider(\n user._id,\n 'email',\n {\n secret: uuidv4(),\n }\n );\n }\n } else {\n user = await sessionAuthService.addUserProvider(user._id, {\n provider: 'email',\n emailValidated: undefined,\n secret: uuidv4(),\n });\n }\n } else {\n user = await userService.createUser(userData);\n logger.info(`New registration: ${user.name} - ${user.email}`);\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_CREATION_FAILED', {\n email: userData.email,\n });\n return;\n }\n\n await sessionAuthService.setUserAuth(res, user);\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type LoginBody = {\n email: string;\n password: string;\n};\nexport type LoginResult = ResponseData<UserAPI>;\n\n/**\n * Handles user login.\n */\nexport const loginEmailPassword = async (\n req: Request<any, any, LoginBody>,\n res: ResponseWithInformation<LoginResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const { email, password } = req.body;\n\n try {\n const { user: loggedInUser, error } =\n await sessionAuthService.testUserPassword(email, password);\n\n if (error) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'LOGIN_FAILED');\n return;\n }\n }\n\n if (!loggedInUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n await sessionAuthService.setUserAuth(res, loggedInUser);\n\n const formattedUser = mapUserToAPI(loggedInUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n logger.info(`Login: ${loggedInUser.email}`);\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type LogoutResult = ResponseData<undefined>;\n\n/**\n * Handles user logout and clears cookies.\n */\nexport const logOut = async (\n _req: Request,\n res: ResponseWithInformation<LogoutResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n await sessionAuthService.clearUserAuth(res);\n sessionAuthService.clearOrganizationAuth(res);\n sessionAuthService.clearProjectAuth(res);\n\n logger.info(`Logout: ${user.name} - ${user.email}`);\n\n const responseData = formatResponse<undefined>({ data: undefined });\n\n res.json(responseData);\n};\n\nexport type UpdatePasswordBody = {\n oldPassword: string;\n newPassword: string;\n};\nexport type UpdatePasswordResult = ResponseData<UserAPI>;\n\n/**\n * Updates the user's password.\n */\nexport const updatePassword = async (\n req: Request<undefined, any, UpdatePasswordBody>,\n res: ResponseWithInformation<UpdatePasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { oldPassword, newPassword } = req.body;\n let { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n try {\n const { error } = await sessionAuthService.testUserPassword(\n user.email,\n oldPassword\n );\n\n if (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'LOGIN_FAILED');\n return;\n }\n\n user = await sessionAuthService.changeUserPassword(\n user._id,\n oldPassword,\n newPassword\n );\n\n if (!user || typeof user !== 'object') {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND');\n return;\n }\n\n logger.info(\n `Password changed - User : Name : ${user.name}, id : ${String(user._id)}`\n );\n\n const formattedUser = mapUserToAPI(user);\n\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type ValidEmailParams = { secret: string; userId: string };\nexport type ValidEmailResult = ResponseData<UserAPI>;\n\n/**\n * Validates a user's email based on the provided secret and user ID.\n */\nexport const validEmail = async (\n req: Request<ValidEmailParams, any, any>,\n res: ResponseWithInformation<ValidEmailResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId, secret } = req.params;\n const { organization } = res.locals;\n\n if (!Types.ObjectId.isValid(userId.toString())) {\n ErrorHandler.handleGenericErrorResponse(res, 'INVALID_USER_ID');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n const user = await userService.getUserById(userId);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED', {\n userId,\n });\n return;\n }\n\n await sessionAuthService.activateUser(user._id, secret);\n\n logger.info(\n `User activated - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n};\n\nexport type AskResetPasswordBody = {\n email: string;\n};\nexport type AskResetPasswordResult = ResponseData<undefined>;\n\n/**\n * Requests a password reset for a user.\n */\nexport const askResetPassword = async (\n req: Request<undefined, any, AskResetPasswordBody>,\n res: ResponseWithInformation<AskResetPasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { email } = req.body as Partial<AskResetPasswordBody>;\n\n if (!email) {\n ErrorHandler.handleGenericErrorResponse(res, 'EMAIL_NOT_PROVIDED');\n return;\n }\n\n try {\n const updatedUser = await sessionAuthService.requestPasswordReset(email);\n\n if (!updatedUser) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND', { email });\n return;\n }\n\n logger.info(\n `Ask changing password - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n await sendEmail({\n type: 'resetPassword',\n to: updatedUser.email,\n username: updatedUser.name,\n resetLink: sessionAuthRoutes.resetPassword.url({\n userId: String(updatedUser._id),\n secret:\n updatedUser.provider?.find(\n (provider) => provider.provider === 'email'\n )?.secret ?? '',\n }),\n });\n\n const responseData = formatResponse<undefined>({ data: undefined });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type ResetPasswordParams = { secret: string; userId: string };\nexport type ResetPasswordResult = ResponseData<UserAPI>;\n\n/**\n * Resets a user's password based on the provided secret and user ID.\n */\nexport const resetPassword = async (\n req: Request<ResetPasswordParams, any, any>,\n res: Response<ResetPasswordResult>,\n _next: NextFunction\n): Promise<void> => {\n const { secret, userId } = req.params as Partial<ResetPasswordParams>;\n const password: string = req.body.password;\n\n const userIdString = String(userId);\n\n if (!userId || !userIdString || !Types.ObjectId.isValid(userIdString)) {\n ErrorHandler.handleGenericErrorResponse(res, 'INVALID_USER_ID', { userId });\n return;\n }\n\n if (!secret) {\n ErrorHandler.handleGenericErrorResponse(res, 'SECRET_NOT_PROVIDED');\n return;\n }\n\n try {\n const updatedUser = await sessionAuthService.resetUserPassword(\n userId,\n secret,\n password\n );\n\n logger.info(\n `Password changed - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n await sendEmail({\n type: 'passwordChangeConfirmation',\n to: updatedUser.email,\n username: updatedUser.name,\n });\n\n const formattedUser = mapUserToAPI(updatedUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type CreateSessionBody = {\n sessionToken: string;\n userId: string;\n expires: Date;\n};\nexport type CreateSessionResult = ResponseData<Session>;\n\nexport type GetSessionInformationQuery = {\n session_token?: string;\n};\ntype SessionInformation = {\n user: UserAPI | null;\n organization: OrganizationAPI | null;\n project: ProjectAPI | null;\n session: Session | null;\n};\nexport type GetSessionInformationResult = ResponseData<SessionInformation>;\n\n/**\n * Gets information about a session for a user.\n */\nexport const getSessionInformation = async (\n req: Request<undefined, undefined, undefined, GetSessionInformationQuery>,\n res: ResponseWithInformation<GetSessionInformationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { session_token: sessionToken } = req.query;\n\n let { user } = res.locals;\n const { organization, project, isOrganizationAdmin, isProjectAdmin } =\n res.locals;\n\n try {\n if (sessionToken) {\n user = await userService.getUserBySession(sessionToken);\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n const session = user.session;\n\n if (!session) {\n ErrorHandler.handleGenericErrorResponse(res, 'SESSION_NOT_FOUND');\n return;\n }\n\n const formattedUser: SessionInformation['user'] = {\n ...mapUserToAPI(user),\n role: 'user',\n };\n\n const responseData = formatResponse<SessionInformation>({\n data: {\n session,\n user: formattedUser,\n organization: organization?._id\n ? mapOrganizationToAPI(organization, isOrganizationAdmin)\n : null,\n project: project?._id\n ? mapProjectToAPI(project, user, isProjectAdmin)\n : null,\n },\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GithubLoginQueryParams = {\n origin: string;\n};\nexport type GithubLoginQueryResult = ResponseData<undefined>;\n\nexport const githubLoginQuery = (\n req: Request<undefined, undefined, undefined, GithubLoginQueryParams>,\n res: ResponseWithInformation<GithubLoginQueryResult>,\n _next: NextFunction\n): void => {\n const { origin } = req.query;\n const { user } = res.locals;\n\n if (user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_ALREADY_LOGGED_IN');\n return;\n }\n\n const encodedOrigin = encodeURIComponent(origin);\n\n const redirectURI = `${process.env.BACKEND_URL}/api/auth/callback/github?redirect_uri=${encodedOrigin}`;\n const encodedRedirectURI = encodeURIComponent(redirectURI);\n\n res.redirect(\n `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodedRedirectURI}`\n );\n};\n\nexport type GithubCallbackQuery = {\n code: string;\n redirect_uri: string;\n};\n\nexport type GithubCallbackResult = ResponseData<UserAPI>;\n\n/**\n * Handles GitHub OAuth callback.\n */\nexport const githubCallback = async (\n req: Request<undefined, undefined, undefined, GithubCallbackQuery>,\n res: ResponseWithInformation<GithubCallbackResult>,\n _next: NextFunction\n): Promise<void> => {\n const { code, redirect_uri } = req.query;\n\n if (!code) {\n const errorMessage = 'Code not provided';\n\n logger.error(errorMessage);\n\n res.redirect(redirect_uri);\n return;\n }\n\n if (!redirect_uri) {\n const errorMessage = 'Redirect URI not provided';\n\n logger.error(errorMessage);\n\n res.redirect(redirect_uri);\n return;\n }\n\n try {\n const tokenResponse = await fetch(\n 'https://github.com/login/oauth/access_token',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify({\n client_id: process.env.GITHUB_CLIENT_ID,\n client_secret: process.env.GITHUB_CLIENT_SECRET,\n code,\n }),\n }\n );\n\n const tokenData = await tokenResponse.json();\n\n const userResponse = await fetch('https://api.github.com/user', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenData.access_token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!userResponse.ok) {\n throw new GenericError('GITHUB_FETCH_USER_DATA_FAILED', { userResponse });\n }\n\n const userData = await userResponse.json();\n\n const emailResponse = await fetch('https://api.github.com/user/emails', {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${tokenData.access_token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!emailResponse.ok) {\n throw new GenericError('GIT_HUB_FETCH_USER_EMAIL_FAILED', {\n emailResponse,\n });\n }\n\n const emails: { primary: boolean; email: string }[] =\n await emailResponse.json();\n\n const primaryEmail = emails.find((email) => email.primary)?.email;\n\n if (!primaryEmail) {\n const errorMessage = 'Primary email not found';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.NOT_FOUND_404;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n let existingUser = await userService.getUserByEmail(primaryEmail);\n\n if (existingUser) {\n const existingProvider = await sessionAuthService.getUserProvider(\n existingUser._id,\n 'github'\n );\n\n if (existingProvider?.providerAccountId !== userData.id) {\n const updatedUser = await sessionAuthService.updateUserProvider(\n existingUser._id,\n 'github',\n {\n providerAccountId: userData.id,\n }\n );\n\n logger.info(\n `GitHub login provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n if (updatedUser) {\n existingUser = updatedUser;\n }\n }\n\n const updatedUser = await userService.updateUserById(existingUser._id, {\n name: existingUser.name ?? userData.name,\n });\n\n await sessionAuthService.setUserAuth(res, updatedUser);\n\n res.redirect(redirect_uri);\n return;\n }\n\n const userInformation: UserData = {\n name: userData.name,\n email: primaryEmail,\n };\n\n const userProvider: GithubSessionProvider = {\n provider: 'github',\n providerAccountId: userData.id,\n };\n\n const user = await userService.createUser({\n ...userInformation,\n provider: [userProvider],\n });\n\n await sessionAuthService.setUserAuth(res, user);\n\n logger.info(\n `GitHub login - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n res.redirect(redirect_uri);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GoogleLoginQueryParams = {\n origin: string;\n};\n\nexport type GoogleLoginResult = ResponseData<undefined>;\n\nexport const googleLoginQuery = (\n req: Request<undefined, undefined, undefined, GoogleLoginQueryParams>,\n res: ResponseWithInformation<GoogleLoginResult>,\n _next: NextFunction\n): void => {\n const { origin } = req.query;\n const { user } = res.locals;\n\n if (user) {\n const errorMessage = `User already logged in - ${user?.email}`;\n\n logger.error(errorMessage);\n\n res.redirect(origin);\n return;\n }\n\n const responseType = 'code';\n const scope = [\n 'https%3A//www.googleapis.com/auth/userinfo.email',\n 'https%3A//www.googleapis.com/auth/userinfo.profile',\n ].join(' ');\n const includeGrantedScopes = 'false';\n\n const encodedOrigin = encodeURIComponent(origin);\n const state = JSON.stringify({ redirect_uri: encodedOrigin });\n\n const redirectURI = `${process.env.BACKEND_URL}/api/auth/callback/google`;\n\n res.redirect(\n `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.GOOGLE_CLIENT_ID}&redirect_uri=${redirectURI}&response_type=${responseType}&scope=${scope}&include_granted_scopes=${includeGrantedScopes}&state=${state}`\n );\n};\n\nexport type GoogleCallbackQuery = {\n code: string;\n state: string;\n};\n\nexport type GoogleCallbackResult = ResponseData<UserAPI>;\n\n/**\n * Handles Google OAuth 2 callback.\n */\nexport const googleCallback = async (\n req: Request<undefined, undefined, undefined, GoogleCallbackQuery>,\n res: ResponseWithInformation<GoogleCallbackResult>,\n _next: NextFunction\n): Promise<void> => {\n const { code, state } = req.query;\n\n const decodedState = decodeURIComponent(state);\n const { redirect_uri } = JSON.parse(decodedState);\n\n if (!code) {\n const errorMessage = 'code not provided';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.BAD_REQUEST_400;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n if (!redirect_uri) {\n const errorMessage = 'Redirect URI not provided';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.BAD_REQUEST_400;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n try {\n // Exchange the authorization code for an access token\n const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n code,\n redirect_uri: `${process.env.BACKEND_URL}/api/auth/callback/google`,\n client_id: process.env.GOOGLE_CLIENT_ID!,\n client_secret: process.env.GOOGLE_CLIENT_SECRET!,\n grant_type: 'authorization_code',\n }),\n });\n\n const responseData = await tokenResponse.json();\n\n const { access_token: accessToken } = responseData;\n\n if (!accessToken) {\n const errorMessage = 'Failed to fetch access_token';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.INTERNAL_SERVER_ERROR_500;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n const userResponse = await fetch(\n 'https://www.googleapis.com/oauth2/v3/userinfo',\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n const userData = await userResponse.json();\n\n if (!userData.email) {\n const errorMessage = 'Failed to fetch user data from Google';\n\n logger.error(errorMessage);\n\n const responseCode = HttpStatusCodes.INTERNAL_SERVER_ERROR_500;\n\n res.redirect(responseCode, redirect_uri);\n return;\n }\n\n let existingUser = await userService.getUserByEmail(userData.email);\n\n if (existingUser) {\n const existingProvider = await sessionAuthService.getUserProvider(\n existingUser._id,\n 'google'\n );\n\n if (existingProvider?.providerAccountId !== userData.sub) {\n const updatedUser = await sessionAuthService.updateUserProvider(\n existingUser._id,\n 'google',\n {\n providerAccountId: userData.id,\n }\n );\n\n logger.info(\n `Google login provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n if (updatedUser) {\n existingUser = updatedUser;\n }\n }\n\n const updatedUser = await userService.updateUserById(existingUser._id, {\n name: existingUser.name ?? userData.name,\n });\n\n await sessionAuthService.setUserAuth(res, updatedUser);\n\n res.redirect(redirect_uri);\n return;\n }\n\n const userInformation: UserData = {\n name: userData.name,\n email: userData.email,\n };\n\n const userProvider: GoogleSessionProvider = {\n provider: 'google',\n providerAccountId: userData.id,\n };\n\n const user = await userService.createUser({\n ...userInformation,\n provider: [userProvider],\n });\n\n await sessionAuthService.setUserAuth(res, user);\n\n logger.info(\n `Google login - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n\n await sendEmail({\n type: 'welcome',\n to: user.email,\n username: user.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n // res.redirect(redirect_uri);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":["user","updatedUser"]}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
const createUser = async (req, res, _next) => {
|
|
13
13
|
const user = req.body;
|
|
14
14
|
if (!user) {
|
|
15
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
15
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
try {
|
|
@@ -35,10 +35,8 @@ const createUser = async (req, res, _next) => {
|
|
|
35
35
|
const getUsers = async (req, res, _next) => {
|
|
36
36
|
const { user } = res.locals;
|
|
37
37
|
if (!user) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
38
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
39
|
+
return;
|
|
42
40
|
}
|
|
43
41
|
const { filters, pageSize, skip, page, getNumberOfPages } = getOrganizationFiltersAndPagination(req);
|
|
44
42
|
try {
|
|
@@ -64,10 +62,8 @@ const getUserById = async (req, res, _next) => {
|
|
|
64
62
|
try {
|
|
65
63
|
const user = await userService.getUserById(userId);
|
|
66
64
|
if (!user) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
65
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
66
|
+
return;
|
|
71
67
|
}
|
|
72
68
|
const formattedUser = mapUserToAPI(user);
|
|
73
69
|
const responseData = formatResponse({ data: formattedUser });
|
|
@@ -83,10 +79,8 @@ const getUserByEmail = async (req, res, _next) => {
|
|
|
83
79
|
try {
|
|
84
80
|
const user = await userService.getUserByEmail(email);
|
|
85
81
|
if (!user) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
82
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
83
|
+
return;
|
|
90
84
|
}
|
|
91
85
|
const formattedUser = mapUserToAPI(user);
|
|
92
86
|
const responseData = formatResponse({ data: formattedUser });
|
|
@@ -113,10 +107,8 @@ const updateUser = async (req, res, _next) => {
|
|
|
113
107
|
const userData = req.body;
|
|
114
108
|
const { user } = res.locals;
|
|
115
109
|
if (!user) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
110
|
+
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
111
|
+
return;
|
|
120
112
|
}
|
|
121
113
|
if (typeof userData !== "object") {
|
|
122
114
|
ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/user.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport * as userService from '@services/user.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { getOrganizationFiltersAndPagination } from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport type { UserFiltersParam } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport { mapUsersToAPI, mapUserToAPI } from '@utils/mapper/user';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { SessionProviders } from '@/types/session.types';\nimport type {\n User,\n UserAPI,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\n\nexport type CreateUserBody = { email: string; password?: string };\nexport type CreateUserResult = ResponseData<UserAPI>;\n\n/**\n * Creates a new user.\n */\nexport const createUser = async (\n req: Request<any, any, UserWithPasswordNotHashed>,\n res: ResponseWithInformation<CreateUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const user: UserWithPasswordNotHashed | undefined = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n\n try {\n const newUser = await userService.createUser(user);\n\n await sendEmail({\n type: 'welcome',\n to: newUser.email,\n username: newUser.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n const formattedUser = mapUserToAPI(newUser);\n\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUsersParams = FiltersAndPagination<UserFiltersParam>;\nexport type GetUsersResult = PaginatedResponse<UserAPI>;\n\n/**\n * Retrieves a list of users based on filters and pagination.\n */\nexport const getUsers = async (\n req: Request<GetUsersParams>,\n res: ResponseWithInformation<GetUsersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (!user) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n }\n\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getOrganizationFiltersAndPagination(req);\n\n try {\n const users = await userService.findUsers(filters, skip, pageSize);\n const totalItems = await userService.countUsers(filters);\n\n const formattedUsers = mapUsersToAPI(users);\n\n const responseData = formatPaginatedResponse<UserAPI>({\n data: formattedUsers,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUserByIdParams = { userId: string };\nexport type GetUserByIdResult = ResponseData<UserAPI>;\n\nexport const getUserById = async (\n req: Request<GetUserByIdParams>,\n res: ResponseWithInformation<GetUserByIdResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId } = req.params;\n\n try {\n const user = await userService.getUserById(userId);\n\n if (!user) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n }\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUserByEmailParams = { email: string };\nexport type GetUserByEmailResult = ResponseData<UserAPI>;\n\nexport const getUserByEmail = async (\n req: Request<GetUserByEmailParams>,\n res: ResponseWithInformation<GetUserByEmailResult>,\n _next: NextFunction\n): Promise<void> => {\n const { email } = req.params;\n\n try {\n const user = await userService.getUserByEmail(email);\n\n if (!user) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n }\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n};\n\nexport type GetUserByAccountParams = {\n providerAccountId: string;\n provider: SessionProviders['provider'];\n};\nexport type GetUserByAccountResult = ResponseData<UserAPI>;\n\n/**\n * Retrieves a user by account.\n */\nexport const getUserByAccount = async (\n req: Request<GetUserByAccountParams>,\n res: ResponseWithInformation<GetUserByAccountResult>,\n _next: NextFunction\n): Promise<void> => {\n const { providerAccountId, provider } = req.params;\n\n try {\n const user = await userService.getUserByAccount(\n provider,\n providerAccountId\n );\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n};\n\nexport type UpdateUserBody = Partial<User>;\nexport type UpdateUserResult = ResponseData<UserAPI>;\n\n/**\n * Updates user information (phone number, date of birth).\n */\nexport const updateUser = async (\n req: Request<any, any, UpdateUserBody | undefined>,\n res: ResponseWithInformation<UpdateUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const userData = req.body;\n const { user } = res.locals;\n\n if (!user) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_FOUND');\n return;\n }\n }\n\n if (typeof userData !== 'object') {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND');\n return;\n }\n\n try {\n const updatedUser = await userService.updateUserById(user._id, userData);\n\n logger.info(\n `User updated: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n const formattedUser = mapUserToAPI(updatedUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteUserParams = { userId: string };\nexport type DeleteUserResult = ResponseData<UserAPI>;\n\n/**\n * Deletes a user based on the provided ID.\n */\nexport const deleteUser = async (\n req: Request<any, any, DeleteUserParams>,\n res: ResponseWithInformation<DeleteUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId } = req.params;\n\n try {\n const user = await userService.deleteUser(userId);\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/user.controller.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\nimport { sendEmail } from '@services/email.service';\nimport * as userService from '@services/user.service';\nimport { AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { getOrganizationFiltersAndPagination } from '@utils/filtersAndPagination/getOrganizationFiltersAndPagination';\nimport type { UserFiltersParam } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport { mapUsersToAPI, mapUserToAPI } from '@utils/mapper/user';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { SessionProviders } from '@/types/session.types';\nimport type {\n User,\n UserAPI,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\n\nexport type CreateUserBody = { email: string; password?: string };\nexport type CreateUserResult = ResponseData<UserAPI>;\n\n/**\n * Creates a new user.\n */\nexport const createUser = async (\n req: Request<any, any, UserWithPasswordNotHashed>,\n res: ResponseWithInformation<CreateUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const user: UserWithPasswordNotHashed | undefined = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n try {\n const newUser = await userService.createUser(user);\n\n await sendEmail({\n type: 'welcome',\n to: newUser.email,\n username: newUser.name,\n loginLink: sessionAuthRoutes.loginEmailPassword.url,\n });\n\n const formattedUser = mapUserToAPI(newUser);\n\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUsersParams = FiltersAndPagination<UserFiltersParam>;\nexport type GetUsersResult = PaginatedResponse<UserAPI>;\n\n/**\n * Retrieves a list of users based on filters and pagination.\n */\nexport const getUsers = async (\n req: Request<GetUsersParams>,\n res: ResponseWithInformation<GetUsersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getOrganizationFiltersAndPagination(req);\n\n try {\n const users = await userService.findUsers(filters, skip, pageSize);\n const totalItems = await userService.countUsers(filters);\n\n const formattedUsers = mapUsersToAPI(users);\n\n const responseData = formatPaginatedResponse<UserAPI>({\n data: formattedUsers,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUserByIdParams = { userId: string };\nexport type GetUserByIdResult = ResponseData<UserAPI>;\n\nexport const getUserById = async (\n req: Request<GetUserByIdParams>,\n res: ResponseWithInformation<GetUserByIdResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId } = req.params;\n\n try {\n const user = await userService.getUserById(userId);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetUserByEmailParams = { email: string };\nexport type GetUserByEmailResult = ResponseData<UserAPI>;\n\nexport const getUserByEmail = async (\n req: Request<GetUserByEmailParams>,\n res: ResponseWithInformation<GetUserByEmailResult>,\n _next: NextFunction\n): Promise<void> => {\n const { email } = req.params;\n\n try {\n const user = await userService.getUserByEmail(email);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n};\n\nexport type GetUserByAccountParams = {\n providerAccountId: string;\n provider: SessionProviders['provider'];\n};\nexport type GetUserByAccountResult = ResponseData<UserAPI>;\n\n/**\n * Retrieves a user by account.\n */\nexport const getUserByAccount = async (\n req: Request<GetUserByAccountParams>,\n res: ResponseWithInformation<GetUserByAccountResult>,\n _next: NextFunction\n): Promise<void> => {\n const { providerAccountId, provider } = req.params;\n\n try {\n const user = await userService.getUserByAccount(\n provider,\n providerAccountId\n );\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n }\n};\n\nexport type UpdateUserBody = Partial<User>;\nexport type UpdateUserResult = ResponseData<UserAPI>;\n\n/**\n * Updates user information (phone number, date of birth).\n */\nexport const updateUser = async (\n req: Request<any, any, UpdateUserBody | undefined>,\n res: ResponseWithInformation<UpdateUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const userData = req.body;\n const { user } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (typeof userData !== 'object') {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_DATA_NOT_FOUND');\n return;\n }\n\n try {\n const updatedUser = await userService.updateUserById(user._id, userData);\n\n logger.info(\n `User updated: Name: ${updatedUser.name}, id: ${String(updatedUser._id)}`\n );\n\n const formattedUser = mapUserToAPI(updatedUser);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteUserParams = { userId: string };\nexport type DeleteUserResult = ResponseData<UserAPI>;\n\n/**\n * Deletes a user based on the provided ID.\n */\nexport const deleteUser = async (\n req: Request<any, any, DeleteUserParams>,\n res: ResponseWithInformation<DeleteUserResult>,\n _next: NextFunction\n): Promise<void> => {\n const { userId } = req.params;\n\n try {\n const user = await userService.deleteUser(userId);\n\n const formattedUser = mapUserToAPI(user);\n const responseData = formatResponse<UserAPI>({ data: formattedUser });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
package/dist/esm/export.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/export.ts"],"sourcesContent":["// Routes\nexport { userRoutes } from '@routes/user.routes';\nexport { organizationRoutes } from '@routes/organization.routes';\nexport { projectRoutes } from '@routes/project.routes';\nexport { dictionaryRoutes } from '@routes/dictionary.routes';\nexport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\n\n// Controllers types\nexport type * from '@controllers/sessionAuth.controller';\nexport type * from '@controllers/oAuth2.controller';\nexport type * from '@controllers/organization.controller';\nexport type * from '@controllers/project.controller';\nexport type * from '@controllers/projectAccessKey.controller';\nexport type * from '@controllers/user.controller';\nexport type * from '@controllers/dictionary.controller';\n\n// Objects types\nexport type * from '@/types/organization.types';\nexport type * from '@/types/project.types';\nexport type * from '@/types/user.types';\nexport type * from '@/types/dictionary.types';\n\n// Utils\nexport * from '@utils/cookies';\nexport * from '@utils/httpStatusCodes';\n"],"mappings":"AACA,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;
|
|
1
|
+
{"version":3,"sources":["../../src/export.ts"],"sourcesContent":["// Routes\nexport { userRoutes } from '@routes/user.routes';\nexport { organizationRoutes } from '@routes/organization.routes';\nexport { projectRoutes } from '@routes/project.routes';\nexport { dictionaryRoutes } from '@routes/dictionary.routes';\nexport { sessionAuthRoutes } from '@routes/sessionAuth.routes';\n\n// Controllers types\nexport type * from '@controllers/sessionAuth.controller';\nexport type * from '@controllers/oAuth2.controller';\nexport type * from '@controllers/organization.controller';\nexport type * from '@controllers/project.controller';\nexport type * from '@controllers/projectAccessKey.controller';\nexport type * from '@controllers/user.controller';\nexport type * from '@controllers/dictionary.controller';\n\n// Objects types\nexport type * from '@/types/organization.types';\nexport type * from '@/types/project.types';\nexport type * from '@/types/user.types';\nexport type * from '@/types/dictionary.types';\nexport type * from '@/types/plan.types';\n\n// Utils\nexport * from '@utils/cookies';\nexport * from '@utils/httpStatusCodes';\n"],"mappings":"AACA,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAmBlC,cAAc;AACd,cAAc;","names":[]}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -2,9 +2,8 @@ import compression from "compression";
|
|
|
2
2
|
import cookieParser from "cookie-parser";
|
|
3
3
|
import cors from "cors";
|
|
4
4
|
import dotenv from "dotenv";
|
|
5
|
-
import express from "express";
|
|
5
|
+
import express, { raw } from "express";
|
|
6
6
|
import { intlayer, t } from "express-intlayer";
|
|
7
|
-
import { checkAdmin } from './middlewares/admin.middleware.mjs';
|
|
8
7
|
import {
|
|
9
8
|
attachOAuthInstance,
|
|
10
9
|
authenticateOAuth2
|
|
@@ -13,13 +12,15 @@ import { logAPIRequestURL } from './middlewares/request.middleware.mjs';
|
|
|
13
12
|
import {
|
|
14
13
|
checkUser,
|
|
15
14
|
checkOrganization,
|
|
16
|
-
checkProject
|
|
15
|
+
checkProject,
|
|
16
|
+
checkAdmin
|
|
17
17
|
} from './middlewares/sessionAuth.middleware.mjs';
|
|
18
18
|
import { dictionaryRouter } from './routes/dictionary.routes.mjs';
|
|
19
19
|
import { organizationRouter } from './routes/organization.routes.mjs';
|
|
20
20
|
import { projectRouter } from './routes/project.routes.mjs';
|
|
21
21
|
import { sessionAuthRouter } from './routes/sessionAuth.routes.mjs';
|
|
22
22
|
import { userRouter } from './routes/user.routes.mjs';
|
|
23
|
+
import { stripeWebhook } from './webhooks/stripe.mjs';
|
|
23
24
|
import { getOAuth2Token } from './controllers/oAuth2.controller.mjs';
|
|
24
25
|
import {
|
|
25
26
|
getSessionInformation,
|
|
@@ -63,6 +64,8 @@ app.get("/", (_req, res) => {
|
|
|
63
64
|
app.use(/(.*)/, checkUser);
|
|
64
65
|
app.use(/(.*)/, checkOrganization);
|
|
65
66
|
app.use(/(.*)/, checkProject);
|
|
67
|
+
app.use(/(.*)/, checkAdmin);
|
|
68
|
+
app.post("/webhook/stripe", raw({ type: "application/json" }), stripeWebhook);
|
|
66
69
|
if (isDev) {
|
|
67
70
|
app.use(logAPIRequestURL);
|
|
68
71
|
}
|
|
@@ -87,7 +90,6 @@ app.use(/(.*)/, (req, res, next) => {
|
|
|
87
90
|
}
|
|
88
91
|
next();
|
|
89
92
|
});
|
|
90
|
-
app.use(/(.*)/, checkAdmin);
|
|
91
93
|
app.use("/api/user", userRouter);
|
|
92
94
|
app.use("/api/organization", organizationRouter);
|
|
93
95
|
app.use("/api/project", projectRouter);
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["/* eslint-disable import/order */\n\n// Libraries\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport dotenv from 'dotenv';\nimport express, { type Express } from 'express';\nimport { intlayer, t } from 'express-intlayer';\n\n// Middlewares\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["/* eslint-disable import/order */\n\n// Libraries\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport dotenv from 'dotenv';\nimport express, { raw, type Express } from 'express';\nimport { intlayer, t } from 'express-intlayer';\n\n// Middlewares\nimport {\n attachOAuthInstance,\n authenticateOAuth2,\n RequestWithOAuth2Information,\n} from '@middlewares/oAuth2.middleware';\nimport { logAPIRequestURL } from '@middlewares/request.middleware';\nimport {\n checkUser,\n checkOrganization,\n checkProject,\n checkAdmin,\n ResponseWithInformation,\n} from '@middlewares/sessionAuth.middleware';\n\n// Routes\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport { organizationRouter } from '@routes/organization.routes';\nimport { projectRouter } from '@routes/project.routes';\nimport { sessionAuthRouter } from '@routes/sessionAuth.routes';\nimport { userRouter } from '@routes/user.routes';\n\n// Webhooks\nimport { stripeWebhook } from '@webhooks/stripe';\n\n// Controllers\nimport { getOAuth2Token } from '@controllers/oAuth2.controller';\nimport {\n getSessionInformation,\n setCSRFToken,\n} from '@controllers/sessionAuth.controller';\n\n// Utils\nimport { doubleCsrfProtection } from '@utils/CSRF';\nimport { connectDB } from '@utils/mongoDB/connectDB';\n\n// Logger\nimport { logger } from './logger';\n\nconst app: Express = express();\n\napp.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\n\n// Environment variables\nconst env = app.get('env');\n\nlogger.info(`run as ${env}`);\n\ndotenv.config({ path: ['.env', `.env.${env}`] });\n\nconst isDev = env === 'development';\n\nconnectDB();\n\n// Compress all HTTP responses\napp.use(compression());\n\n// Parse incoming requests with JSON payloads\napp.use(express.json({ limit: '50mb' }));\n\n// Parse incoming requests with urlencoded payloads\napp.use(express.urlencoded({ extended: true }));\n\n// Parse incoming requests with cookies\napp.use(cookieParser());\n\n// Load internationalization request handler\napp.use(intlayer());\n\n// CORS\nconst whitelist: string[] = [process.env.CLIENT_URL!];\nconst corsOptions: CorsOptions = {\n origin: whitelist,\n credentials: true,\n allowedHeaders: ['authorization', 'Content-Type', 'credentials'],\n exposedHeaders: [''],\n preflightContinue: false,\n methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n};\napp.use(cors(corsOptions));\nlogger.info('url whitelist : ', whitelist.join(', '));\n\n// Liveness check\napp.get('/', (_req, res) => {\n res.send(\n t({\n en: 'Ok - locale: en',\n fr: 'Ok - locale: fr',\n es: 'Ok - locale: es',\n })\n );\n});\n\n// middleware - jwt & session auth\napp.use(/(.*)/, checkUser);\napp.use(/(.*)/, checkOrganization);\napp.use(/(.*)/, checkProject);\napp.use(/(.*)/, checkAdmin);\n\n// Stripe webhook\napp.post('/webhook/stripe', raw({ type: 'application/json' }), stripeWebhook);\n\n// debug\nif (isDev) {\n app.use(logAPIRequestURL);\n}\n\n// Sessions\napp.get('/session', getSessionInformation);\napp.use('/api/auth', sessionAuthRouter);\n\n// CSRF\napp.get('/csrf-token', setCSRFToken);\n\n// oAuth2\napp.use(/(.*)/, attachOAuthInstance);\napp.post('/oauth2/token', getOAuth2Token); // Route to get the token\napp.use(/(.*)/, (req, res, next) => {\n // If the request is not already authenticated check the oAuth2 token\n if (!res.locals.authType) {\n return authenticateOAuth2(\n req as RequestWithOAuth2Information,\n res as ResponseWithInformation,\n next\n );\n }\n next();\n});\n\n// CSRF protection\napp.use(/(.*)/, (req, res, next) => {\n // If the request is authenticated using the session auth check the CSRF token\n if (res.locals.authType === 'session') {\n return doubleCsrfProtection(req, res, next);\n }\n next();\n});\n\n// Routes\napp.use('/api/user', userRouter);\napp.use('/api/organization', organizationRouter);\napp.use('/api/project', projectRouter);\napp.use('/api/dictionary', dictionaryRouter);\n\n// Server\napp.listen(process.env.PORT, () => {\n logger.info(`Listening on port ${process.env.PORT}`);\n});\n\n// Export tu use as serverless function\nexport default app;\n"],"mappings":"AAGA,OAAO,iBAAiB;AACxB,OAAO,kBAAkB;AACzB,OAAO,UAAgC;AACvC,OAAO,YAAY;AACnB,OAAO,WAAW,WAAyB;AAC3C,SAAS,UAAU,SAAS;AAG5B;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAGP,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAG3B,SAAS,qBAAqB;AAG9B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAGP,SAAS,4BAA4B;AACrC,SAAS,iBAAiB;AAG1B,SAAS,cAAc;AAEvB,MAAM,MAAe,QAAQ;AAE7B,IAAI,QAAQ,cAAc;AAG1B,MAAM,MAAM,IAAI,IAAI,KAAK;AAEzB,OAAO,KAAK,UAAU,GAAG,EAAE;AAE3B,OAAO,OAAO,EAAE,MAAM,CAAC,QAAQ,QAAQ,GAAG,EAAE,EAAE,CAAC;AAE/C,MAAM,QAAQ,QAAQ;AAEtB,UAAU;AAGV,IAAI,IAAI,YAAY,CAAC;AAGrB,IAAI,IAAI,QAAQ,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC;AAGvC,IAAI,IAAI,QAAQ,WAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAG9C,IAAI,IAAI,aAAa,CAAC;AAGtB,IAAI,IAAI,SAAS,CAAC;AAGlB,MAAM,YAAsB,CAAC,QAAQ,IAAI,UAAW;AACpD,MAAM,cAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,gBAAgB,CAAC,iBAAiB,gBAAgB,aAAa;AAAA,EAC/D,gBAAgB,CAAC,EAAE;AAAA,EACnB,mBAAmB;AAAA,EACnB,SAAS;AACX;AACA,IAAI,IAAI,KAAK,WAAW,CAAC;AACzB,OAAO,KAAK,oBAAoB,UAAU,KAAK,IAAI,CAAC;AAGpD,IAAI,IAAI,KAAK,CAAC,MAAM,QAAQ;AAC1B,MAAI;AAAA,IACF,EAAE;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IACN,CAAC;AAAA,EACH;AACF,CAAC;AAGD,IAAI,IAAI,QAAQ,SAAS;AACzB,IAAI,IAAI,QAAQ,iBAAiB;AACjC,IAAI,IAAI,QAAQ,YAAY;AAC5B,IAAI,IAAI,QAAQ,UAAU;AAG1B,IAAI,KAAK,mBAAmB,IAAI,EAAE,MAAM,mBAAmB,CAAC,GAAG,aAAa;AAG5E,IAAI,OAAO;AACT,MAAI,IAAI,gBAAgB;AAC1B;AAGA,IAAI,IAAI,YAAY,qBAAqB;AACzC,IAAI,IAAI,aAAa,iBAAiB;AAGtC,IAAI,IAAI,eAAe,YAAY;AAGnC,IAAI,IAAI,QAAQ,mBAAmB;AACnC,IAAI,KAAK,iBAAiB,cAAc;AACxC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS;AAElC,MAAI,CAAC,IAAI,OAAO,UAAU;AACxB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,OAAK;AACP,CAAC;AAGD,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS;AAElC,MAAI,IAAI,OAAO,aAAa,WAAW;AACrC,WAAO,qBAAqB,KAAK,KAAK,IAAI;AAAA,EAC5C;AACA,OAAK;AACP,CAAC;AAGD,IAAI,IAAI,aAAa,UAAU;AAC/B,IAAI,IAAI,qBAAqB,kBAAkB;AAC/C,IAAI,IAAI,gBAAgB,aAAa;AACrC,IAAI,IAAI,mBAAmB,gBAAgB;AAG3C,IAAI,OAAO,QAAQ,IAAI,MAAM,MAAM;AACjC,SAAO,KAAK,qBAAqB,QAAQ,IAAI,IAAI,EAAE;AACrD,CAAC;AAGD,IAAO,cAAQ;","names":[]}
|
|
@@ -30,6 +30,16 @@ const authenticateOAuth2 = async (req, res, next) => {
|
|
|
30
30
|
oauthResponse,
|
|
31
31
|
authenticateOptions
|
|
32
32
|
);
|
|
33
|
+
const {
|
|
34
|
+
organization: organizationRights,
|
|
35
|
+
project: projectRights,
|
|
36
|
+
dictionary: dictionaryRights
|
|
37
|
+
} = oAuthToken.rights;
|
|
38
|
+
res.locals.organizationRights = organizationRights;
|
|
39
|
+
res.locals.isOrganizationAdmin = organizationRights?.admin ?? false;
|
|
40
|
+
res.locals.projectRights = projectRights;
|
|
41
|
+
res.locals.isProjectAdmin = projectRights?.admin ?? false;
|
|
42
|
+
res.locals.dictionaryRights = dictionaryRights;
|
|
33
43
|
const user = await UserModel.findById(oAuthToken.user._id);
|
|
34
44
|
if (user) {
|
|
35
45
|
res.locals.user = user;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/middlewares/oAuth2.middleware.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport { OrganizationModel } from '@models/organization.model';\nimport { ProjectModel } from '@models/project.model';\nimport { UserModel } from '@models/user.model';\nimport { getAuthModel, authenticateOptions } from '@utils/oAuth2';\nimport { NextFunction, Request, Response } from 'express';\nimport OAuth2Server, {\n Request as OAuthRequest,\n Response as OAuthResponse,\n} from 'oauth2-server';\nimport { ResponseWithInformation } from './sessionAuth.middleware';\n\n// Configuration of the OAuth server\nconst oauth = new OAuth2Server({\n model: getAuthModel(),\n accessTokenLifetime: 60 * 60, // 1 hour\n allowBearerTokensInQueryString: true,\n});\n\nexport type RequestWithOAuth2Information<\n P = any,\n ResBody = any,\n ReqBody = any,\n ReqQuery = qs.ParsedQs,\n> = Request<P, ResBody, ReqBody, ReqQuery> & {\n oauth: OAuth2Server;\n};\n\nexport const attachOAuthInstance = async (\n req: Request,\n _res: Response,\n next: NextFunction\n) => {\n // Attach the instance OAuth to the requests\n (req as RequestWithOAuth2Information).oauth = oauth;\n\n next();\n};\n\n// Middleware to authenticate requests\nexport const authenticateOAuth2 = async (\n req: RequestWithOAuth2Information,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n try {\n const hasToken = !!req.headers.authorization;\n\n if (!hasToken) {\n // If the request does not have a token, skip the oAuth2 authentication\n // Necessary because the oAuth2 library will throw an error if the token is not present\n return next();\n }\n\n // Authenticate the request using OAuth2\n const oauthRequest = new OAuthRequest(req);\n\n const oauthResponse = new OAuthResponse(res);\n\n const oAuthToken = await req.oauth.authenticate(\n oauthRequest,\n oauthResponse,\n authenticateOptions\n );\n\n const user = await UserModel.findById(oAuthToken.user._id);\n\n if (user) {\n res.locals.user = user;\n res.locals.authType = 'oauth2';\n }\n\n const organization = await OrganizationModel.findById(\n oAuthToken.organization._id\n );\n\n if (organization) {\n res.locals.organization = organization;\n }\n
|
|
1
|
+
{"version":3,"sources":["../../../src/middlewares/oAuth2.middleware.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { logger } from '@logger';\nimport { OrganizationModel } from '@models/organization.model';\nimport { ProjectModel } from '@models/project.model';\nimport { UserModel } from '@models/user.model';\nimport { getAuthModel, authenticateOptions } from '@utils/oAuth2';\nimport { NextFunction, Request, Response } from 'express';\nimport OAuth2Server, {\n Request as OAuthRequest,\n Response as OAuthResponse,\n} from 'oauth2-server';\nimport { ResponseWithInformation } from './sessionAuth.middleware';\n\n// Configuration of the OAuth server\nconst oauth = new OAuth2Server({\n model: getAuthModel(),\n accessTokenLifetime: 60 * 60, // 1 hour\n allowBearerTokensInQueryString: true,\n});\n\nexport type RequestWithOAuth2Information<\n P = any,\n ResBody = any,\n ReqBody = any,\n ReqQuery = qs.ParsedQs,\n> = Request<P, ResBody, ReqBody, ReqQuery> & {\n oauth: OAuth2Server;\n};\n\nexport const attachOAuthInstance = async (\n req: Request,\n _res: Response,\n next: NextFunction\n) => {\n // Attach the instance OAuth to the requests\n (req as RequestWithOAuth2Information).oauth = oauth;\n\n next();\n};\n\n// Middleware to authenticate requests\nexport const authenticateOAuth2 = async (\n req: RequestWithOAuth2Information,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n try {\n const hasToken = !!req.headers.authorization;\n\n if (!hasToken) {\n // If the request does not have a token, skip the oAuth2 authentication\n // Necessary because the oAuth2 library will throw an error if the token is not present\n return next();\n }\n\n // Authenticate the request using OAuth2\n const oauthRequest = new OAuthRequest(req);\n\n const oauthResponse = new OAuthResponse(res);\n\n const oAuthToken = await req.oauth.authenticate(\n oauthRequest,\n oauthResponse,\n authenticateOptions\n );\n\n const {\n organization: organizationRights,\n project: projectRights,\n dictionary: dictionaryRights,\n } = oAuthToken.rights;\n\n res.locals.organizationRights = organizationRights;\n res.locals.isOrganizationAdmin = organizationRights?.admin ?? false;\n res.locals.projectRights = projectRights;\n res.locals.isProjectAdmin = projectRights?.admin ?? false;\n res.locals.dictionaryRights = dictionaryRights;\n\n const user = await UserModel.findById(oAuthToken.user._id);\n\n if (user) {\n res.locals.user = user;\n res.locals.authType = 'oauth2';\n }\n\n const organization = await OrganizationModel.findById(\n oAuthToken.organization._id\n );\n\n if (organization) {\n res.locals.organization = organization;\n }\n const project = await ProjectModel.findById(oAuthToken.project._id);\n\n if (project) {\n res.locals.project = project;\n }\n } catch (err) {\n logger.info(err);\n }\n next();\n};\n"],"mappings":"AACA,SAAS,cAAc;AACvB,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,cAAc,2BAA2B;AAElD,OAAO;AAAA,EACL,WAAW;AAAA,EACX,YAAY;AAAA,OACP;AAIP,MAAM,QAAQ,IAAI,aAAa;AAAA,EAC7B,OAAO,aAAa;AAAA,EACpB,qBAAqB,KAAK;AAAA;AAAA,EAC1B,gCAAgC;AAClC,CAAC;AAWM,MAAM,sBAAsB,OACjC,KACA,MACA,SACG;AAEH,EAAC,IAAqC,QAAQ;AAE9C,OAAK;AACP;AAGO,MAAM,qBAAqB,OAChC,KACA,KACA,SACkB;AAClB,MAAI;AACF,UAAM,WAAW,CAAC,CAAC,IAAI,QAAQ;AAE/B,QAAI,CAAC,UAAU;AAGb,aAAO,KAAK;AAAA,IACd;AAGA,UAAM,eAAe,IAAI,aAAa,GAAG;AAEzC,UAAM,gBAAgB,IAAI,cAAc,GAAG;AAE3C,UAAM,aAAa,MAAM,IAAI,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,cAAc;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,IACd,IAAI,WAAW;AAEf,QAAI,OAAO,qBAAqB;AAChC,QAAI,OAAO,sBAAsB,oBAAoB,SAAS;AAC9D,QAAI,OAAO,gBAAgB;AAC3B,QAAI,OAAO,iBAAiB,eAAe,SAAS;AACpD,QAAI,OAAO,mBAAmB;AAE9B,UAAM,OAAO,MAAM,UAAU,SAAS,WAAW,KAAK,GAAG;AAEzD,QAAI,MAAM;AACR,UAAI,OAAO,OAAO;AAClB,UAAI,OAAO,WAAW;AAAA,IACxB;AAEA,UAAM,eAAe,MAAM,kBAAkB;AAAA,MAC3C,WAAW,aAAa;AAAA,IAC1B;AAEA,QAAI,cAAc;AAChB,UAAI,OAAO,eAAe;AAAA,IAC5B;AACA,UAAM,UAAU,MAAM,aAAa,SAAS,WAAW,QAAQ,GAAG;AAElE,QAAI,SAAS;AACX,UAAI,OAAO,UAAU;AAAA,IACvB;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,GAAG;AAAA,EACjB;AACA,OAAK;AACP;","names":[]}
|
|
@@ -7,11 +7,6 @@ import {
|
|
|
7
7
|
import { getUserBySession as getUserBySessionService } from './../services/user.service.mjs';
|
|
8
8
|
import { Cookies } from './../utils/cookies.mjs';
|
|
9
9
|
import jwt from "jsonwebtoken";
|
|
10
|
-
var AuthInformationType = /* @__PURE__ */ ((AuthInformationType2) => {
|
|
11
|
-
AuthInformationType2[AuthInformationType2["IsNull"] = 0] = "IsNull";
|
|
12
|
-
AuthInformationType2[AuthInformationType2["IsDefined"] = 1] = "IsDefined";
|
|
13
|
-
return AuthInformationType2;
|
|
14
|
-
})(AuthInformationType || {});
|
|
15
10
|
const checkUser = async (req, res, next) => {
|
|
16
11
|
const { [Cookies.JWT_AUTH]: sessionToken } = req.cookies;
|
|
17
12
|
res.locals.user = null;
|
|
@@ -87,8 +82,55 @@ const checkProject = async (req, res, next) => {
|
|
|
87
82
|
}
|
|
88
83
|
return next();
|
|
89
84
|
};
|
|
85
|
+
const checkAdmin = async (_req, res, next) => {
|
|
86
|
+
const { organization, project, user, authType } = res.locals;
|
|
87
|
+
if (authType !== "session") {
|
|
88
|
+
return next();
|
|
89
|
+
}
|
|
90
|
+
res.locals.organizationRights = {
|
|
91
|
+
read: false,
|
|
92
|
+
write: false,
|
|
93
|
+
admin: false
|
|
94
|
+
};
|
|
95
|
+
res.locals.projectRights = {
|
|
96
|
+
read: false,
|
|
97
|
+
write: false,
|
|
98
|
+
admin: false
|
|
99
|
+
};
|
|
100
|
+
res.locals.projectRights = {
|
|
101
|
+
read: false,
|
|
102
|
+
write: false,
|
|
103
|
+
admin: false
|
|
104
|
+
};
|
|
105
|
+
if (user) {
|
|
106
|
+
if (organization) {
|
|
107
|
+
const isOrganizationAdmin = organization.adminsIds.map((id) => String(id)).includes(String(user._id)) ?? false;
|
|
108
|
+
res.locals.isOrganizationAdmin = isOrganizationAdmin;
|
|
109
|
+
res.locals.organizationRights = {
|
|
110
|
+
read: true,
|
|
111
|
+
write: isOrganizationAdmin,
|
|
112
|
+
admin: isOrganizationAdmin
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (project) {
|
|
116
|
+
const isProjectAdmin = project.adminsIds.map((id) => String(id)).includes(String(user._id)) ?? false;
|
|
117
|
+
res.locals.isProjectAdmin = isProjectAdmin;
|
|
118
|
+
res.locals.projectRights = {
|
|
119
|
+
read: true,
|
|
120
|
+
write: isProjectAdmin,
|
|
121
|
+
admin: isProjectAdmin
|
|
122
|
+
};
|
|
123
|
+
res.locals.dictionaryRights = {
|
|
124
|
+
read: true,
|
|
125
|
+
write: true,
|
|
126
|
+
admin: true
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return next();
|
|
131
|
+
};
|
|
90
132
|
export {
|
|
91
|
-
|
|
133
|
+
checkAdmin,
|
|
92
134
|
checkOrganization,
|
|
93
135
|
checkProject,
|
|
94
136
|
checkUser
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/middlewares/sessionAuth.middleware.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { OrganizationModel } from '@models/organization.model';\nimport { ProjectModel } from '@models/project.model';\nimport {\n clearOrganizationAuth,\n clearProjectAuth,\n} from '@services/sessionAuth.service';\nimport { getUserBySession as getUserBySessionService } from '@services/user.service';\nimport { Cookies } from '@utils/cookies';\nimport type { Request, Response, NextFunction } from 'express';\nimport jwt from 'jsonwebtoken';\nimport type {\n Organization,\n OrganizationDocument,\n} from '@/types/organization.types';\nimport type { Project, ProjectDocument } from '@/types/project.types';\nimport type { User, UserDocument } from '@/types/user.types';\n\nexport
|
|
1
|
+
{"version":3,"sources":["../../../src/middlewares/sessionAuth.middleware.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { OrganizationModel } from '@models/organization.model';\nimport { ProjectModel } from '@models/project.model';\nimport {\n clearOrganizationAuth,\n clearProjectAuth,\n} from '@services/sessionAuth.service';\nimport { getUserBySession as getUserBySessionService } from '@services/user.service';\nimport { Cookies } from '@utils/cookies';\nimport type { Request, Response, NextFunction } from 'express';\nimport jwt from 'jsonwebtoken';\nimport type {\n Organization,\n OrganizationDocument,\n} from '@/types/organization.types';\nimport type { Project, ProjectDocument, Rights } from '@/types/project.types';\nimport type { User, UserDocument } from '@/types/user.types';\n\nexport type ResponseWithInformation<ResBody = any> = Response<\n ResBody,\n {\n user: User | null;\n // Auth Context\n organization: Organization | null;\n project: Project | null;\n authType: 'session' | 'oauth2' | null;\n // Auth Rights - oAuth2 Auth\n organizationRights: Rights | null;\n projectRights: Rights | null;\n dictionaryRights: Rights | null;\n // Auth Rights - Session Auth\n isOrganizationAdmin: boolean | null;\n isProjectAdmin: boolean | null;\n }\n>;\n\nexport const checkUser = async (\n req: Request,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n const { [Cookies.JWT_AUTH]: sessionToken } = req.cookies;\n\n res.locals.user = null;\n res.locals.authType = null;\n\n try {\n if (sessionToken) {\n const user: UserDocument | null = (await getUserBySessionService(\n sessionToken\n )) as UserDocument | null;\n\n if (user) {\n res.locals.user = user.toObject();\n res.locals.authType = 'session';\n }\n }\n } catch (error) {\n console.error('Error fetching session:', error);\n }\n\n return next();\n};\n\nexport const checkOrganization = async (\n req: Request,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n const jwtTokenOrganization = req.cookies[Cookies.JWT_ORGANIZATION];\n\n res.locals.organization = null;\n\n try {\n if (!jwtTokenOrganization || jwtTokenOrganization === 'undefined') {\n clearOrganizationAuth(res);\n return next();\n }\n\n const organizationData = jwt.verify(\n jwtTokenOrganization,\n process.env.JWT_TOKEN_SECRET!\n ) as Organization;\n\n if (!organizationData) {\n clearOrganizationAuth(res);\n return next();\n }\n\n const organization: OrganizationDocument | null =\n await OrganizationModel.findById(organizationData._id);\n\n if (!organization) {\n clearOrganizationAuth(res);\n return next();\n }\n\n res.locals.organization = organization.toObject();\n } catch (error) {\n console.error('Error fetching organization:', error);\n }\n\n return next();\n};\n\nexport const checkProject = async (\n req: Request,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n const jwtTokenProject = req.cookies[Cookies.JWT_PROJECT];\n res.locals.project = null;\n\n try {\n if (!jwtTokenProject || jwtTokenProject === 'undefined') {\n clearProjectAuth(res);\n return next();\n }\n\n const decodedTokenProject = jwt.verify(\n jwtTokenProject,\n process.env.JWT_TOKEN_SECRET!\n ) as Project;\n\n if (!decodedTokenProject) {\n clearProjectAuth(res);\n return next();\n }\n\n const project: ProjectDocument | null = await ProjectModel.findById(\n decodedTokenProject._id\n );\n\n if (\n !project ||\n !res.locals.organization ||\n String(project.organizationId) !== String(res.locals.organization._id)\n ) {\n clearProjectAuth(res);\n return next();\n }\n\n res.locals.project = project.toObject();\n } catch (error) {\n console.error('Error fetching project:', error);\n }\n\n return next();\n};\n\n/**\n * Middleware to check if the user is an admin of the organization or project\n * Sets the following properties in res.locals:\n * - isOrganizationAdmin: boolean\n * - isProjectAdmin: boolean\n */\nexport const checkAdmin = async (\n _req: Request,\n res: ResponseWithInformation,\n next: NextFunction\n): Promise<void> => {\n const { organization, project, user, authType } = res.locals;\n\n if (authType !== 'session') {\n return next();\n }\n\n res.locals.organizationRights = {\n read: false,\n write: false,\n admin: false,\n };\n res.locals.projectRights = {\n read: false,\n write: false,\n admin: false,\n };\n res.locals.projectRights = {\n read: false,\n write: false,\n admin: false,\n };\n\n if (user) {\n if (organization) {\n const isOrganizationAdmin: boolean =\n organization.adminsIds\n .map((id) => String(id))\n .includes(String(user._id)) ?? false;\n\n res.locals.isOrganizationAdmin = isOrganizationAdmin;\n\n res.locals.organizationRights = {\n read: true,\n write: isOrganizationAdmin,\n admin: isOrganizationAdmin,\n };\n }\n\n if (project) {\n const isProjectAdmin: boolean =\n project.adminsIds.map((id) => String(id)).includes(String(user._id)) ??\n false;\n\n res.locals.isProjectAdmin = isProjectAdmin;\n\n res.locals.projectRights = {\n read: true,\n write: isProjectAdmin,\n admin: isProjectAdmin,\n };\n\n res.locals.dictionaryRights = {\n read: true,\n write: true,\n admin: true,\n };\n }\n }\n\n return next();\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/models/plan.moddel.ts"],"sourcesContent":["import { planSchema } from '@schemas/plans.schema';\nimport { model } from 'mongoose';\nimport { Plan } from '@/types/plan.types';\n\nexport const PlanModel = model<Plan>('plan', planSchema);\n"],"mappings":"AAAA,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AAGf,MAAM,YAAY,MAAY,QAAQ,UAAU;","names":[]}
|