@intlayer/backend 5.4.1 → 5.4.2

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.
@@ -50,13 +50,13 @@ __export(sessionAuth_service_exports, {
50
50
  updateUserProvider: () => updateUserProvider
51
51
  });
52
52
  module.exports = __toCommonJS(sessionAuth_service_exports);
53
- var import_crypto = __toESM(require("crypto"), 1);
54
53
  var import_logger = require('./../logger/index.cjs');
55
54
  var import_cookies = require('./../utils/cookies.cjs');
56
55
  var import_ensureMongoDocumentToObject = require('./../utils/ensureMongoDocumentToObject.cjs');
57
56
  var import_errors = require('./../utils/errors/index.cjs');
58
57
  var import_user = require('./../utils/mapper/user.cjs');
59
- var import_bcrypt = require("bcrypt");
58
+ var import_bcryptjs = require("bcryptjs");
59
+ var import_crypto = __toESM(require("crypto"), 1);
60
60
  var import_express_intlayer = require("express-intlayer");
61
61
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
62
62
  var import_uuid = require("uuid");
@@ -193,7 +193,7 @@ const resetUserPassword = async (userId, secret, newPassword) => {
193
193
  throw new import_errors.GenericError("USER_PROVIDER_SECRET_NOT_VALID", { userId });
194
194
  }
195
195
  const updatedUser = await updateUserProvider(userId, "email", {
196
- passwordHash: await (0, import_bcrypt.hash)(newPassword, await (0, import_bcrypt.genSalt)()),
196
+ passwordHash: await (0, import_bcryptjs.hash)(newPassword, await (0, import_bcryptjs.genSalt)()),
197
197
  secret
198
198
  });
199
199
  return updatedUser;
@@ -311,7 +311,7 @@ const testUserPassword = async (email, password) => {
311
311
  };
312
312
  return { user: null, error: (0, import_express_intlayer.t)(errorMessages) };
313
313
  }
314
- const isMatch = await (0, import_bcrypt.compare)(
314
+ const isMatch = await (0, import_bcryptjs.compare)(
315
315
  password,
316
316
  userEmailPasswordProvider.passwordHash
317
317
  );
@@ -334,7 +334,7 @@ const hashUserPassword = async (userWithPasswordNotHashed) => {
334
334
  throw new import_errors.GenericError("USER_PASSWORD_NOT_DEFINED", { user });
335
335
  }
336
336
  const userProvider = formatUserProviderUpdate("email", user, {
337
- passwordHash: await (0, import_bcrypt.hash)(password, await (0, import_bcrypt.genSalt)()),
337
+ passwordHash: await (0, import_bcryptjs.hash)(password, await (0, import_bcryptjs.genSalt)()),
338
338
  secret: generateSecret(35)
339
339
  });
340
340
  return { ...user, provider: userProvider };
@@ -345,7 +345,7 @@ const changeUserPassword = async (userId, newPassword) => {
345
345
  throw new import_errors.GenericError("USER_NOT_FOUND", { userId });
346
346
  }
347
347
  const updatedUser = await updateUserProvider(userId, "email", {
348
- passwordHash: await (0, import_bcrypt.hash)(newPassword, await (0, import_bcrypt.genSalt)())
348
+ passwordHash: await (0, import_bcryptjs.hash)(newPassword, await (0, import_bcryptjs.genSalt)())
349
349
  });
350
350
  return updatedUser;
351
351
  };
@@ -355,7 +355,7 @@ const resetPassword = async (userId, password) => {
355
355
  throw new import_errors.GenericError("USER_NOT_FOUND", { userId });
356
356
  }
357
357
  const updatedUser = await updateUserProvider(userId, "email", {
358
- passwordHash: await (0, import_bcrypt.hash)(password, await (0, import_bcrypt.genSalt)())
358
+ passwordHash: await (0, import_bcryptjs.hash)(password, await (0, import_bcryptjs.genSalt)())
359
359
  });
360
360
  return updatedUser;
361
361
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/sessionAuth.service.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport {\n Cookies,\n getClearCookieOptions,\n getCookieOptions,\n MAX_AGE,\n} from '@utils/cookies';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { hash, genSalt, compare } from 'bcrypt';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport { t } from 'express-intlayer';\nimport jwt from 'jsonwebtoken';\nimport type { ObjectId } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getUserByEmail, getUserById, updateUserById } from './user.service';\nimport type { Organization } from '@/types/organization.types';\nimport type { Project } from '@/types/project.types';\nimport type {\n SessionProviders,\n EmailPasswordSessionProvider,\n GoogleSessionProvider,\n GithubSessionProvider,\n Session,\n} from '@/types/session.types';\nimport type {\n User,\n UserDocument,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\n\n/**\n * Adds a session to a user or updates the existing one.\n * @param user - User object.\n * @returns Updated user object.\n */\nexport const addSession = async (user: User): Promise<UserDocument> => {\n const userSessionToken = uuidv4();\n\n const session: Session = {\n sessionToken: userSessionToken,\n expires: new Date(Date.now() + MAX_AGE),\n };\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\nexport const removeSession = async (user: User): Promise<UserDocument> => {\n const session = undefined;\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\n/**\n * Set user auth locals object\n * @param res - Express response object.\n * @param user - User object.\n */\nexport const setUserAuth = async (res: Response, user: User) => {\n const formattedUser = mapUserToAPI(user);\n\n const userToken = jwt.sign(formattedUser, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!userToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_USER', { user });\n }\n\n const cookieOptions = getCookieOptions();\n\n res.cookie(Cookies.JWT_USER, userToken, cookieOptions);\n\n const userWithSession: UserDocument = await addSession(user);\n\n const userSessionToken = userWithSession.session?.sessionToken;\n\n res.cookie(Cookies.JWT_AUTH, userSessionToken, cookieOptions);\n\n res.locals.user = user;\n logger.info(\n `User logged in - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n};\n\n/**\n * Clears the JWT auth cookies and user locals object.\n * @param res - Express response object.\n */\nexport const clearUserAuth = async (res: ResponseWithInformation) => {\n const { user } = res.locals;\n const cookiesOptions = getClearCookieOptions();\n\n if (user) {\n await removeSession(user);\n }\n\n res.cookie(Cookies.JWT_AUTH, '', cookiesOptions);\n res.cookie(Cookies.JWT_USER, '', cookiesOptions);\n\n res.locals.user = null;\n res.locals.authType = null;\n};\n\n/**\n *\n * @param res\n * @param organization\n * @returns\n */\nexport const setOrganizationAuth = (\n res: ResponseWithInformation,\n organization: Organization\n) => {\n const organizationData = {\n _id: organization._id,\n name: organization.name,\n };\n\n const organizationToken = jwt.sign(\n organizationData,\n process.env.JWT_TOKEN_SECRET!,\n {\n expiresIn: MAX_AGE,\n }\n );\n\n if (!organizationToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_ORGANIZATION', {\n organization,\n });\n }\n\n res.cookie(Cookies.JWT_ORGANIZATION, organizationToken, getCookieOptions());\n\n res.locals.organization = organization;\n};\n\n/**\n * Clears the JWT organization cookies and organization locals object.\n * @param res - Express response object.\n */\nexport const clearOrganizationAuth = (res: ResponseWithInformation) => {\n res.locals.organization = null;\n\n res.cookie(Cookies.JWT_ORGANIZATION, '', getClearCookieOptions());\n};\n\n/**\n * Set project auth locals object\n * @param res - Express response object.\n * @param project - Project object.\n */\nexport const setProjectAuth = (\n res: ResponseWithInformation,\n project: Project\n) => {\n const { organization } = res.locals;\n const projectData = {\n _id: project._id,\n name: project.name,\n };\n\n const projectToken = jwt.sign(projectData, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!projectToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_PROJECT', {\n project,\n });\n }\n\n res.cookie(Cookies.JWT_PROJECT, projectToken, getCookieOptions());\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n project,\n });\n }\n\n if (\n // if the project is not in the organization's projects\n String(organization._id) !== String(project.organizationId)\n ) {\n throw new GenericError('JWT_TOKEN_ORGANIZATION_MISMATCH_PROJECT', {\n project,\n });\n }\n\n res.locals.project = project;\n};\n\n/**\n * Clears the JWT project cookies and project locals object.\n * @param res - Express response object.\n */\nexport const clearProjectAuth = (res: Response) => {\n res.locals.project = null;\n\n res.cookie(Cookies.JWT_PROJECT, '', getClearCookieOptions());\n};\n\n/**\n * Generates a random secret string of a specified length.\n * @param length - The length of the secret.\n * @returns The generated secret string.\n */\nexport const generateSecret = (length: number): string => {\n const characters =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n return Array.from({ length }, () =>\n characters.charAt(Math.floor(Math.random() * characters.length))\n ).join('');\n};\n\n/**\n * Handles a password reset request for a user.\n * @param email - The user's email.\n * @param organization - The organization associated with the user.\n * @returns The user object or null if no user was found.\n */\nexport const requestPasswordReset = async (\n email: string\n): Promise<User | null> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { email });\n }\n\n return updateUserProvider(user._id as unknown as string, 'email', {\n secret: generateSecret(35),\n });\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetUserPassword = async (\n userId: string | ObjectId,\n secret: string,\n newPassword: string\n): Promise<User> => {\n const emailAndPasswordProvider = await getUserProvider(userId, 'email');\n\n if (!emailAndPasswordProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', { userId });\n }\n\n if (!emailAndPasswordProvider.secret) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_DEFINED', { userId });\n }\n\n if (\n !crypto.timingSafeEqual(\n Buffer.from(emailAndPasswordProvider.secret),\n Buffer.from(secret)\n )\n ) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_VALID', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n secret,\n });\n\n return updatedUser;\n};\n\ntype UserProvider<T extends SessionProviders['provider']> = T extends 'email'\n ? EmailPasswordSessionProvider\n : T extends 'google'\n ? GoogleSessionProvider\n : T extends 'github'\n ? GithubSessionProvider\n : SessionProviders;\n\n/**\n * Gets a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to get.\n * @returns The user's provider.\n */\nexport const getUserProvider = async <T extends SessionProviders['provider']>(\n userId: string | ObjectId,\n provider: T,\n providerAccountId?: string\n): Promise<UserProvider<T> | null> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const userProvider = user.provider?.find(\n (providerEl) =>\n (providerEl.provider === provider && !providerAccountId) ||\n (providerAccountId &&\n (providerEl as GithubSessionProvider).providerAccountId ===\n providerAccountId)\n );\n\n return (userProvider as UserProvider<T>) ?? null;\n};\n\n/**\n * Formats the given fields of a user's provider.\n * @param provider - The provider to update.\n * @param user - The user object.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user provider.\n */\nexport const formatUserProviderUpdate = <\n T extends SessionProviders['provider'],\n>(\n provider: T,\n user: Partial<User>,\n providerUpdate: Partial<UserProvider<T>>\n): User['provider'] => {\n const userProvider: SessionProviders[] = ensureMongoDocumentToObject<\n SessionProviders[]\n >(user.provider ?? []);\n\n const userProviderToUpdate = userProvider?.find(\n (providerEl) => providerEl.provider === provider\n );\n\n let updatedProvider: User['provider'];\n\n if (userProviderToUpdate) {\n const otherProviders =\n user.provider?.filter((p) => p.provider !== provider) ?? [];\n\n updatedProvider = [\n ...otherProviders,\n { ...userProviderToUpdate, ...providerUpdate, provider },\n ];\n } else {\n updatedProvider = [\n ...(user.provider ?? []),\n { ...providerUpdate, provider } as SessionProviders,\n ];\n }\n\n return updatedProvider;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to update.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const updateUserProvider = async <\n T extends SessionProviders['provider'],\n>(\n userId: string | ObjectId,\n provider: T,\n providerUpdate: Partial<UserProvider<T>>\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const formattedProviderToUpdate = formatUserProviderUpdate(\n provider,\n user,\n providerUpdate\n );\n\n const updatedUser: UserDocument = await updateUserById(userId, {\n provider: formattedProviderToUpdate,\n });\n\n logger.info(\n `User provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const addUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(userId, provider.provider);\n\n if (existingProvider) {\n throw new GenericError('USER_PROVIDER_ALREADY_EXISTS', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = [...(user.provider ?? []), provider];\n\n const updatedUser = await updateUserById(userId, {\n provider: updatedProvider,\n });\n\n logger.info(\n `User provider added - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider.provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Removes a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to remove.\n * @returns The updated user.\n */\nexport const removeUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders['provider'],\n providerAccountId?: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(\n userId,\n provider,\n providerAccountId\n );\n\n if (!existingProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = user.provider?.filter(\n (p) =>\n p.provider !== provider &&\n (!providerAccountId ||\n (providerAccountId &&\n (p as GithubSessionProvider).providerAccountId !== providerAccountId))\n );\n\n return await updateUserById(userId, {\n provider: updatedProvider,\n });\n};\n\ntype TestUserPasswordResult = { user: User | null; error?: string };\n\n/**\n * Logs in a user.\n * @param email - The user's email.\n * @param password - The user's password.\n * @returns The user object.\n */\nexport const testUserPassword = async (\n email: string,\n password: string\n): Promise<TestUserPasswordResult> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n const errorMessages = {\n en: `User not found - ${email}`,\n fr: `Utilisateur non trouvé - ${email}`,\n es: `Usuario no encontrado - ${email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const userEmailPasswordProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (!userEmailPasswordProvider?.passwordHash) {\n const errorMessages = {\n en: `User request to login but no password defined: ${user.email}`,\n fr: `Demande de connexion d'utilisateur mais pas de mot de passe défini : ${user.email}`,\n es: `Solicitud de inicio de sesión de usuario pero no se define la contraseña : ${user.email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const isMatch = await compare(\n password,\n userEmailPasswordProvider.passwordHash\n );\n\n if (!isMatch) {\n const errorMessages = {\n en: `Incorrect email or password: ${email}`,\n fr: `Email ou mot de passe incorrect : ${email}`,\n es: `Correo electrónico o contraseña incorrecta : ${email}`,\n };\n\n logger.error(errorMessages.en);\n\n // Await a random time to prevent brute force attacks\n const randomNumber = Math.floor(Math.random() * 1000) + 1000;\n await new Promise((resolve) => setTimeout(resolve, randomNumber));\n\n return { user: null, error: t(errorMessages) };\n }\n\n return { user };\n};\n\n/**\n * Hashes a user's password.\n * @param userWithPasswordNotHashed - The user object with password not hashed.\n * @returns The user object with hashed password.\n */\nexport const hashUserPassword = async (\n userWithPasswordNotHashed: UserWithPasswordNotHashed\n): Promise<Partial<UserDocument>> => {\n const { password, ...user } = userWithPasswordNotHashed;\n\n if (!password) {\n throw new GenericError('USER_PASSWORD_NOT_DEFINED', { user });\n }\n\n const userProvider = formatUserProviderUpdate('email', user, {\n passwordHash: await hash(password, await genSalt()),\n secret: generateSecret(35),\n });\n\n return { ...user, provider: userProvider };\n};\n\n/**\n * Changes a user's password.\n * @param userId - The ID of the user.\n * @param newPassword - The user's new password.\n * @returns The updated user or null if the password change failed.\n */\nexport const changeUserPassword = async (\n userId: string | ObjectId,\n newPassword: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n });\n\n return updatedUser;\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetPassword = async (userId: string, password: string) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: UserDocument = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(password, await genSalt()),\n });\n\n return updatedUser;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AACnB,oBAAuB;AAEvB,qBAKO;AACP,yCAA4C;AAC5C,oBAA6B;AAC7B,kBAA6B;AAC7B,oBAAuC;AAGvC,8BAAkB;AAClB,0BAAgB;AAEhB,kBAA6B;AAC7B,IAAAA,eAA4D;AAqBrD,MAAM,aAAa,OAAO,SAAsC;AACrE,QAAM,uBAAmB,YAAAC,IAAO;AAEhC,QAAM,UAAmB;AAAA,IACvB,cAAc;AAAA,IACd,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,sBAAO;AAAA,EACxC;AAEA,QAAM,cAA4B,UAAM,6BAAe,KAAK,KAAK,EAAE,QAAQ,CAAC;AAE5E,SAAO;AACT;AAEO,MAAM,gBAAgB,OAAO,SAAsC;AACxE,QAAM,UAAU;AAEhB,QAAM,cAA4B,UAAM,6BAAe,KAAK,KAAK,EAAE,QAAQ,CAAC;AAE5E,SAAO;AACT;AAOO,MAAM,cAAc,OAAO,KAAe,SAAe;AAC9D,QAAM,oBAAgB,0BAAa,IAAI;AAEvC,QAAM,YAAY,oBAAAC,QAAI,KAAK,eAAe,QAAQ,IAAI,kBAAmB;AAAA,IACvE,WAAW;AAAA,EACb,CAAC;AAED,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,2BAAa,kCAAkC,EAAE,KAAK,CAAC;AAAA,EACnE;AAEA,QAAM,oBAAgB,iCAAiB;AAEvC,MAAI,OAAO,uBAAQ,UAAU,WAAW,aAAa;AAErD,QAAM,kBAAgC,MAAM,WAAW,IAAI;AAE3D,QAAM,mBAAmB,gBAAgB,SAAS;AAElD,MAAI,OAAO,uBAAQ,UAAU,kBAAkB,aAAa;AAE5D,MAAI,OAAO,OAAO;AAClB,uBAAO;AAAA,IACL,gCAAgC,KAAK,IAAI,SAAS,OAAO,KAAK,GAAG,CAAC;AAAA,EACpE;AACF;AAMO,MAAM,gBAAgB,OAAO,QAAiC;AACnE,QAAM,EAAE,KAAK,IAAI,IAAI;AACrB,QAAM,qBAAiB,sCAAsB;AAE7C,MAAI,MAAM;AACR,UAAM,cAAc,IAAI;AAAA,EAC1B;AAEA,MAAI,OAAO,uBAAQ,UAAU,IAAI,cAAc;AAC/C,MAAI,OAAO,uBAAQ,UAAU,IAAI,cAAc;AAE/C,MAAI,OAAO,OAAO;AAClB,MAAI,OAAO,WAAW;AACxB;AAQO,MAAM,sBAAsB,CACjC,KACA,iBACG;AACH,QAAM,mBAAmB;AAAA,IACvB,KAAK,aAAa;AAAA,IAClB,MAAM,aAAa;AAAA,EACrB;AAEA,QAAM,oBAAoB,oBAAAA,QAAI;AAAA,IAC5B;AAAA,IACA,QAAQ,IAAI;AAAA,IACZ;AAAA,MACE,WAAW;AAAA,IACb;AAAA,EACF;AAEA,MAAI,CAAC,mBAAmB;AACtB,UAAM,IAAI,2BAAa,0CAA0C;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,uBAAQ,kBAAkB,uBAAmB,iCAAiB,CAAC;AAE1E,MAAI,OAAO,eAAe;AAC5B;AAMO,MAAM,wBAAwB,CAAC,QAAiC;AACrE,MAAI,OAAO,eAAe;AAE1B,MAAI,OAAO,uBAAQ,kBAAkB,QAAI,sCAAsB,CAAC;AAClE;AAOO,MAAM,iBAAiB,CAC5B,KACA,YACG;AACH,QAAM,EAAE,aAAa,IAAI,IAAI;AAC7B,QAAM,cAAc;AAAA,IAClB,KAAK,QAAQ;AAAA,IACb,MAAM,QAAQ;AAAA,EAChB;AAEA,QAAM,eAAe,oBAAAA,QAAI,KAAK,aAAa,QAAQ,IAAI,kBAAmB;AAAA,IACxE,WAAW;AAAA,EACb,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,2BAAa,qCAAqC;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,uBAAQ,aAAa,kBAAc,iCAAiB,CAAC;AAEhE,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,2BAAa,0BAA0B;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAEA;AAAA;AAAA,IAEE,OAAO,aAAa,GAAG,MAAM,OAAO,QAAQ,cAAc;AAAA,IAC1D;AACA,UAAM,IAAI,2BAAa,2CAA2C;AAAA,MAChE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,UAAU;AACvB;AAMO,MAAM,mBAAmB,CAAC,QAAkB;AACjD,MAAI,OAAO,UAAU;AAErB,MAAI,OAAO,uBAAQ,aAAa,QAAI,sCAAsB,CAAC;AAC7D;AAOO,MAAM,iBAAiB,CAAC,WAA2B;AACxD,QAAM,aACJ;AACF,SAAO,MAAM;AAAA,IAAK,EAAE,OAAO;AAAA,IAAG,MAC5B,WAAW,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,WAAW,MAAM,CAAC;AAAA,EACjE,EAAE,KAAK,EAAE;AACX;AAQO,MAAM,uBAAuB,OAClC,UACyB;AACzB,QAAM,OAAO,UAAM,6BAAe,KAAK;AAEvC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,MAAM,CAAC;AAAA,EACpD;AAEA,SAAO,mBAAmB,KAAK,KAA0B,SAAS;AAAA,IAChE,QAAQ,eAAe,EAAE;AAAA,EAC3B,CAAC;AACH;AASO,MAAM,oBAAoB,OAC/B,QACA,QACA,gBACkB;AAClB,QAAM,2BAA2B,MAAM,gBAAgB,QAAQ,OAAO;AAEtE,MAAI,CAAC,0BAA0B;AAC7B,UAAM,IAAI,2BAAa,2BAA2B,EAAE,OAAO,CAAC;AAAA,EAC9D;AAEA,MAAI,CAAC,yBAAyB,QAAQ;AACpC,UAAM,IAAI,2BAAa,oCAAoC,EAAE,OAAO,CAAC;AAAA,EACvE;AAEA,MACE,CAAC,cAAAC,QAAO;AAAA,IACN,OAAO,KAAK,yBAAyB,MAAM;AAAA,IAC3C,OAAO,KAAK,MAAM;AAAA,EACpB,GACA;AACA,UAAM,IAAI,2BAAa,kCAAkC,EAAE,OAAO,CAAC;AAAA,EACrE;AAEA,QAAM,cAAoB,MAAM,mBAAmB,QAAQ,SAAS;AAAA,IAClE,cAAc,UAAM,oBAAK,aAAa,UAAM,uBAAQ,CAAC;AAAA,IACrD;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAgBO,MAAM,kBAAkB,OAC7B,QACA,UACA,sBACoC;AACpC,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,eAAe,KAAK,UAAU;AAAA,IAClC,CAAC,eACE,WAAW,aAAa,YAAY,CAAC,qBACrC,qBACE,WAAqC,sBACpC;AAAA,EACR;AAEA,SAAQ,gBAAoC;AAC9C;AASO,MAAM,2BAA2B,CAGtC,UACA,MACA,mBACqB;AACrB,QAAM,mBAAmC,gEAEvC,KAAK,YAAY,CAAC,CAAC;AAErB,QAAM,uBAAuB,cAAc;AAAA,IACzC,CAAC,eAAe,WAAW,aAAa;AAAA,EAC1C;AAEA,MAAI;AAEJ,MAAI,sBAAsB;AACxB,UAAM,iBACJ,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ,KAAK,CAAC;AAE5D,sBAAkB;AAAA,MAChB,GAAG;AAAA,MACH,EAAE,GAAG,sBAAsB,GAAG,gBAAgB,SAAS;AAAA,IACzD;AAAA,EACF,OAAO;AACL,sBAAkB;AAAA,MAChB,GAAI,KAAK,YAAY,CAAC;AAAA,MACtB,EAAE,GAAG,gBAAgB,SAAS;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;AASO,MAAM,qBAAqB,OAGhC,QACA,UACA,mBAC0B;AAC1B,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,4BAA4B;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,cAA4B,UAAM,6BAAe,QAAQ;AAAA,IAC7D,UAAU;AAAA,EACZ,CAAC;AAED,uBAAO;AAAA,IACL,uCAAuC,YAAY,IAAI,SAAS,OAAO,YAAY,GAAG,CAAC,gBAAgB,QAAQ;AAAA,EACjH;AAEA,SAAO;AACT;AAQO,MAAM,kBAAkB,OAC7B,QACA,aAC0B;AAC1B,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,mBAAmB,MAAM,gBAAgB,QAAQ,SAAS,QAAQ;AAExE,MAAI,kBAAkB;AACpB,UAAM,IAAI,2BAAa,gCAAgC;AAAA,MACrD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkB,CAAC,GAAI,KAAK,YAAY,CAAC,GAAI,QAAQ;AAE3D,QAAM,cAAc,UAAM,6BAAe,QAAQ;AAAA,IAC/C,UAAU;AAAA,EACZ,CAAC;AAED,uBAAO;AAAA,IACL,qCAAqC,YAAY,IAAI,SAAS,OAAO,YAAY,GAAG,CAAC,gBAAgB,SAAS,QAAQ;AAAA,EACxH;AAEA,SAAO;AACT;AAQO,MAAM,qBAAqB,OAChC,QACA,UACA,sBACG;AACH,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,mBAAmB,MAAM;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,2BAAa,2BAA2B;AAAA,MAChD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkB,KAAK,UAAU;AAAA,IACrC,CAAC,MACC,EAAE,aAAa,aACd,CAAC,qBACC,qBACE,EAA4B,sBAAsB;AAAA,EAC3D;AAEA,SAAO,UAAM,6BAAe,QAAQ;AAAA,IAClC,UAAU;AAAA,EACZ,CAAC;AACH;AAUO,MAAM,mBAAmB,OAC9B,OACA,aACoC;AACpC,QAAM,OAAO,UAAM,6BAAe,KAAK;AAEvC,MAAI,CAAC,MAAM;AACT,UAAM,gBAAgB;AAAA,MACpB,IAAI,oBAAoB,KAAK;AAAA,MAC7B,IAAI,+BAA4B,KAAK;AAAA,MACrC,IAAI,2BAA2B,KAAK;AAAA,IACtC;AAEA,WAAO,EAAE,MAAM,MAAM,WAAO,2BAAE,aAAa,EAAE;AAAA,EAC/C;AAEA,QAAM,4BAA4B,KAAK,UAAU;AAAA,IAC/C,CAAC,aAAa,SAAS,aAAa;AAAA,EACtC;AAEA,MAAI,CAAC,2BAA2B,cAAc;AAC5C,UAAM,gBAAgB;AAAA,MACpB,IAAI,kDAAkD,KAAK,KAAK;AAAA,MAChE,IAAI,2EAAwE,KAAK,KAAK;AAAA,MACtF,IAAI,oFAA8E,KAAK,KAAK;AAAA,IAC9F;AAEA,WAAO,EAAE,MAAM,MAAM,WAAO,2BAAE,aAAa,EAAE;AAAA,EAC/C;AAEA,QAAM,UAAU,UAAM;AAAA,IACpB;AAAA,IACA,0BAA0B;AAAA,EAC5B;AAEA,MAAI,CAAC,SAAS;AACZ,UAAM,gBAAgB;AAAA,MACpB,IAAI,gCAAgC,KAAK;AAAA,MACzC,IAAI,qCAAqC,KAAK;AAAA,MAC9C,IAAI,sDAAgD,KAAK;AAAA,IAC3D;AAEA,yBAAO,MAAM,cAAc,EAAE;AAG7B,UAAM,eAAe,KAAK,MAAM,KAAK,OAAO,IAAI,GAAI,IAAI;AACxD,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,YAAY,CAAC;AAEhE,WAAO,EAAE,MAAM,MAAM,WAAO,2BAAE,aAAa,EAAE;AAAA,EAC/C;AAEA,SAAO,EAAE,KAAK;AAChB;AAOO,MAAM,mBAAmB,OAC9B,8BACmC;AACnC,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAE9B,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,2BAAa,6BAA6B,EAAE,KAAK,CAAC;AAAA,EAC9D;AAEA,QAAM,eAAe,yBAAyB,SAAS,MAAM;AAAA,IAC3D,cAAc,UAAM,oBAAK,UAAU,UAAM,uBAAQ,CAAC;AAAA,IAClD,QAAQ,eAAe,EAAE;AAAA,EAC3B,CAAC;AAED,SAAO,EAAE,GAAG,MAAM,UAAU,aAAa;AAC3C;AAQO,MAAM,qBAAqB,OAChC,QACA,gBACG;AACH,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,cAAoB,MAAM,mBAAmB,QAAQ,SAAS;AAAA,IAClE,cAAc,UAAM,oBAAK,aAAa,UAAM,uBAAQ,CAAC;AAAA,EACvD,CAAC;AAED,SAAO;AACT;AASO,MAAM,gBAAgB,OAAO,QAAgB,aAAqB;AACvE,QAAM,OAAO,UAAM,0BAAY,MAAM;AAErC,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,2BAAa,kBAAkB,EAAE,OAAO,CAAC;AAAA,EACrD;AAEA,QAAM,cAA4B,MAAM,mBAAmB,QAAQ,SAAS;AAAA,IAC1E,cAAc,UAAM,oBAAK,UAAU,UAAM,uBAAQ,CAAC;AAAA,EACpD,CAAC;AAED,SAAO;AACT;","names":["import_user","uuidv4","jwt","crypto"]}
1
+ {"version":3,"sources":["../../../src/services/sessionAuth.service.ts"],"sourcesContent":["import { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport {\n Cookies,\n getClearCookieOptions,\n getCookieOptions,\n MAX_AGE,\n} from '@utils/cookies';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { compare, genSalt, hash } from 'bcryptjs';\nimport crypto from 'crypto';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport type { Organization } from '@/types/organization.types';\nimport type { Project } from '@/types/project.types';\nimport type {\n EmailPasswordSessionProvider,\n GithubSessionProvider,\n GoogleSessionProvider,\n Session,\n SessionProviders,\n} from '@/types/session.types';\nimport type {\n User,\n UserDocument,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\nimport { t } from 'express-intlayer';\nimport jwt from 'jsonwebtoken';\nimport type { ObjectId } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getUserByEmail, getUserById, updateUserById } from './user.service';\n\n/**\n * Adds a session to a user or updates the existing one.\n * @param user - User object.\n * @returns Updated user object.\n */\nexport const addSession = async (user: User): Promise<UserDocument> => {\n const userSessionToken = uuidv4();\n\n const session: Session = {\n sessionToken: userSessionToken,\n expires: new Date(Date.now() + MAX_AGE),\n };\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\nexport const removeSession = async (user: User): Promise<UserDocument> => {\n const session = undefined;\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\n/**\n * Set user auth locals object\n * @param res - Express response object.\n * @param user - User object.\n */\nexport const setUserAuth = async (res: Response, user: User) => {\n const formattedUser = mapUserToAPI(user);\n\n const userToken = jwt.sign(formattedUser, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!userToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_USER', { user });\n }\n\n const cookieOptions = getCookieOptions();\n\n res.cookie(Cookies.JWT_USER, userToken, cookieOptions);\n\n const userWithSession: UserDocument = await addSession(user);\n\n const userSessionToken = userWithSession.session?.sessionToken;\n\n res.cookie(Cookies.JWT_AUTH, userSessionToken, cookieOptions);\n\n res.locals.user = user;\n logger.info(\n `User logged in - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n};\n\n/**\n * Clears the JWT auth cookies and user locals object.\n * @param res - Express response object.\n */\nexport const clearUserAuth = async (res: ResponseWithInformation) => {\n const { user } = res.locals;\n const cookiesOptions = getClearCookieOptions();\n\n if (user) {\n await removeSession(user);\n }\n\n res.cookie(Cookies.JWT_AUTH, '', cookiesOptions);\n res.cookie(Cookies.JWT_USER, '', cookiesOptions);\n\n res.locals.user = null;\n res.locals.authType = null;\n};\n\n/**\n *\n * @param res\n * @param organization\n * @returns\n */\nexport const setOrganizationAuth = (\n res: ResponseWithInformation,\n organization: Organization\n) => {\n const organizationData = {\n _id: organization._id,\n name: organization.name,\n };\n\n const organizationToken = jwt.sign(\n organizationData,\n process.env.JWT_TOKEN_SECRET!,\n {\n expiresIn: MAX_AGE,\n }\n );\n\n if (!organizationToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_ORGANIZATION', {\n organization,\n });\n }\n\n res.cookie(Cookies.JWT_ORGANIZATION, organizationToken, getCookieOptions());\n\n res.locals.organization = organization;\n};\n\n/**\n * Clears the JWT organization cookies and organization locals object.\n * @param res - Express response object.\n */\nexport const clearOrganizationAuth = (res: ResponseWithInformation) => {\n res.locals.organization = null;\n\n res.cookie(Cookies.JWT_ORGANIZATION, '', getClearCookieOptions());\n};\n\n/**\n * Set project auth locals object\n * @param res - Express response object.\n * @param project - Project object.\n */\nexport const setProjectAuth = (\n res: ResponseWithInformation,\n project: Project\n) => {\n const { organization } = res.locals;\n const projectData = {\n _id: project._id,\n name: project.name,\n };\n\n const projectToken = jwt.sign(projectData, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!projectToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_PROJECT', {\n project,\n });\n }\n\n res.cookie(Cookies.JWT_PROJECT, projectToken, getCookieOptions());\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n project,\n });\n }\n\n if (\n // if the project is not in the organization's projects\n String(organization._id) !== String(project.organizationId)\n ) {\n throw new GenericError('JWT_TOKEN_ORGANIZATION_MISMATCH_PROJECT', {\n project,\n });\n }\n\n res.locals.project = project;\n};\n\n/**\n * Clears the JWT project cookies and project locals object.\n * @param res - Express response object.\n */\nexport const clearProjectAuth = (res: Response) => {\n res.locals.project = null;\n\n res.cookie(Cookies.JWT_PROJECT, '', getClearCookieOptions());\n};\n\n/**\n * Generates a random secret string of a specified length.\n * @param length - The length of the secret.\n * @returns The generated secret string.\n */\nexport const generateSecret = (length: number): string => {\n const characters =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n return Array.from({ length }, () =>\n characters.charAt(Math.floor(Math.random() * characters.length))\n ).join('');\n};\n\n/**\n * Handles a password reset request for a user.\n * @param email - The user's email.\n * @param organization - The organization associated with the user.\n * @returns The user object or null if no user was found.\n */\nexport const requestPasswordReset = async (\n email: string\n): Promise<User | null> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { email });\n }\n\n return updateUserProvider(user._id as unknown as string, 'email', {\n secret: generateSecret(35),\n });\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetUserPassword = async (\n userId: string | ObjectId,\n secret: string,\n newPassword: string\n): Promise<User> => {\n const emailAndPasswordProvider = await getUserProvider(userId, 'email');\n\n if (!emailAndPasswordProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', { userId });\n }\n\n if (!emailAndPasswordProvider.secret) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_DEFINED', { userId });\n }\n\n if (\n !crypto.timingSafeEqual(\n Buffer.from(emailAndPasswordProvider.secret),\n Buffer.from(secret)\n )\n ) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_VALID', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n secret,\n });\n\n return updatedUser;\n};\n\ntype UserProvider<T extends SessionProviders['provider']> = T extends 'email'\n ? EmailPasswordSessionProvider\n : T extends 'google'\n ? GoogleSessionProvider\n : T extends 'github'\n ? GithubSessionProvider\n : SessionProviders;\n\n/**\n * Gets a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to get.\n * @returns The user's provider.\n */\nexport const getUserProvider = async <T extends SessionProviders['provider']>(\n userId: string | ObjectId,\n provider: T,\n providerAccountId?: string\n): Promise<UserProvider<T> | null> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const userProvider = user.provider?.find(\n (providerEl) =>\n (providerEl.provider === provider && !providerAccountId) ||\n (providerAccountId &&\n (providerEl as GithubSessionProvider).providerAccountId ===\n providerAccountId)\n );\n\n return (userProvider as UserProvider<T>) ?? null;\n};\n\n/**\n * Formats the given fields of a user's provider.\n * @param provider - The provider to update.\n * @param user - The user object.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user provider.\n */\nexport const formatUserProviderUpdate = <\n T extends SessionProviders['provider'],\n>(\n provider: T,\n user: Partial<User>,\n providerUpdate: Partial<UserProvider<T>>\n): User['provider'] => {\n const userProvider: SessionProviders[] = ensureMongoDocumentToObject<\n SessionProviders[]\n >(user.provider ?? []);\n\n const userProviderToUpdate = userProvider?.find(\n (providerEl) => providerEl.provider === provider\n );\n\n let updatedProvider: User['provider'];\n\n if (userProviderToUpdate) {\n const otherProviders =\n user.provider?.filter((p) => p.provider !== provider) ?? [];\n\n updatedProvider = [\n ...otherProviders,\n { ...userProviderToUpdate, ...providerUpdate, provider },\n ];\n } else {\n updatedProvider = [\n ...(user.provider ?? []),\n { ...providerUpdate, provider } as SessionProviders,\n ];\n }\n\n return updatedProvider;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to update.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const updateUserProvider = async <\n T extends SessionProviders['provider'],\n>(\n userId: string | ObjectId,\n provider: T,\n providerUpdate: Partial<UserProvider<T>>\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const formattedProviderToUpdate = formatUserProviderUpdate(\n provider,\n user,\n providerUpdate\n );\n\n const updatedUser: UserDocument = await updateUserById(userId, {\n provider: formattedProviderToUpdate,\n });\n\n logger.info(\n `User provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const addUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(userId, provider.provider);\n\n if (existingProvider) {\n throw new GenericError('USER_PROVIDER_ALREADY_EXISTS', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = [...(user.provider ?? []), provider];\n\n const updatedUser = await updateUserById(userId, {\n provider: updatedProvider,\n });\n\n logger.info(\n `User provider added - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider.provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Removes a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to remove.\n * @returns The updated user.\n */\nexport const removeUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders['provider'],\n providerAccountId?: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(\n userId,\n provider,\n providerAccountId\n );\n\n if (!existingProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = user.provider?.filter(\n (p) =>\n p.provider !== provider &&\n (!providerAccountId ||\n (providerAccountId &&\n (p as GithubSessionProvider).providerAccountId !== providerAccountId))\n );\n\n return await updateUserById(userId, {\n provider: updatedProvider,\n });\n};\n\ntype TestUserPasswordResult = { user: User | null; error?: string };\n\n/**\n * Logs in a user.\n * @param email - The user's email.\n * @param password - The user's password.\n * @returns The user object.\n */\nexport const testUserPassword = async (\n email: string,\n password: string\n): Promise<TestUserPasswordResult> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n const errorMessages = {\n en: `User not found - ${email}`,\n fr: `Utilisateur non trouvé - ${email}`,\n es: `Usuario no encontrado - ${email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const userEmailPasswordProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (!userEmailPasswordProvider?.passwordHash) {\n const errorMessages = {\n en: `User request to login but no password defined: ${user.email}`,\n fr: `Demande de connexion d'utilisateur mais pas de mot de passe défini : ${user.email}`,\n es: `Solicitud de inicio de sesión de usuario pero no se define la contraseña : ${user.email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const isMatch = await compare(\n password,\n userEmailPasswordProvider.passwordHash\n );\n\n if (!isMatch) {\n const errorMessages = {\n en: `Incorrect email or password: ${email}`,\n fr: `Email ou mot de passe incorrect : ${email}`,\n es: `Correo electrónico o contraseña incorrecta : ${email}`,\n };\n\n logger.error(errorMessages.en);\n\n // Await a random time to prevent brute force attacks\n const randomNumber = Math.floor(Math.random() * 1000) + 1000;\n await new Promise((resolve) => setTimeout(resolve, randomNumber));\n\n return { user: null, error: t(errorMessages) };\n }\n\n return { user };\n};\n\n/**\n * Hashes a user's password.\n * @param userWithPasswordNotHashed - The user object with password not hashed.\n * @returns The user object with hashed password.\n */\nexport const hashUserPassword = async (\n userWithPasswordNotHashed: UserWithPasswordNotHashed\n): Promise<Partial<UserDocument>> => {\n const { password, ...user } = userWithPasswordNotHashed;\n\n if (!password) {\n throw new GenericError('USER_PASSWORD_NOT_DEFINED', { user });\n }\n\n const userProvider = formatUserProviderUpdate('email', user, {\n passwordHash: await hash(password, await genSalt()),\n secret: generateSecret(35),\n });\n\n return { ...user, provider: userProvider };\n};\n\n/**\n * Changes a user's password.\n * @param userId - The ID of the user.\n * @param newPassword - The user's new password.\n * @returns The updated user or null if the password change failed.\n */\nexport const changeUserPassword = async (\n userId: string | ObjectId,\n newPassword: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n });\n\n return updatedUser;\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetPassword = async (userId: string, password: string) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: UserDocument = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(password, await genSalt()),\n });\n\n return updatedUser;\n};\n"],"mappings":"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","names":["import_user","uuidv4","jwt","crypto"]}
@@ -1,4 +1,3 @@
1
- import crypto from "crypto";
2
1
  import { logger } from "./../logger/index.mjs";
3
2
  import {
4
3
  Cookies,
@@ -9,7 +8,8 @@ import {
9
8
  import { ensureMongoDocumentToObject } from "./../utils/ensureMongoDocumentToObject.mjs";
10
9
  import { GenericError } from "./../utils/errors/index.mjs";
11
10
  import { mapUserToAPI } from "./../utils/mapper/user.mjs";
12
- import { hash, genSalt, compare } from "bcrypt";
11
+ import { compare, genSalt, hash } from "bcryptjs";
12
+ import crypto from "crypto";
13
13
  import { t } from "express-intlayer";
14
14
  import jwt from "jsonwebtoken";
15
15
  import { v4 as uuidv4 } from "uuid";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/sessionAuth.service.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport {\n Cookies,\n getClearCookieOptions,\n getCookieOptions,\n MAX_AGE,\n} from '@utils/cookies';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { hash, genSalt, compare } from 'bcrypt';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport { t } from 'express-intlayer';\nimport jwt from 'jsonwebtoken';\nimport type { ObjectId } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getUserByEmail, getUserById, updateUserById } from './user.service';\nimport type { Organization } from '@/types/organization.types';\nimport type { Project } from '@/types/project.types';\nimport type {\n SessionProviders,\n EmailPasswordSessionProvider,\n GoogleSessionProvider,\n GithubSessionProvider,\n Session,\n} from '@/types/session.types';\nimport type {\n User,\n UserDocument,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\n\n/**\n * Adds a session to a user or updates the existing one.\n * @param user - User object.\n * @returns Updated user object.\n */\nexport const addSession = async (user: User): Promise<UserDocument> => {\n const userSessionToken = uuidv4();\n\n const session: Session = {\n sessionToken: userSessionToken,\n expires: new Date(Date.now() + MAX_AGE),\n };\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\nexport const removeSession = async (user: User): Promise<UserDocument> => {\n const session = undefined;\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\n/**\n * Set user auth locals object\n * @param res - Express response object.\n * @param user - User object.\n */\nexport const setUserAuth = async (res: Response, user: User) => {\n const formattedUser = mapUserToAPI(user);\n\n const userToken = jwt.sign(formattedUser, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!userToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_USER', { user });\n }\n\n const cookieOptions = getCookieOptions();\n\n res.cookie(Cookies.JWT_USER, userToken, cookieOptions);\n\n const userWithSession: UserDocument = await addSession(user);\n\n const userSessionToken = userWithSession.session?.sessionToken;\n\n res.cookie(Cookies.JWT_AUTH, userSessionToken, cookieOptions);\n\n res.locals.user = user;\n logger.info(\n `User logged in - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n};\n\n/**\n * Clears the JWT auth cookies and user locals object.\n * @param res - Express response object.\n */\nexport const clearUserAuth = async (res: ResponseWithInformation) => {\n const { user } = res.locals;\n const cookiesOptions = getClearCookieOptions();\n\n if (user) {\n await removeSession(user);\n }\n\n res.cookie(Cookies.JWT_AUTH, '', cookiesOptions);\n res.cookie(Cookies.JWT_USER, '', cookiesOptions);\n\n res.locals.user = null;\n res.locals.authType = null;\n};\n\n/**\n *\n * @param res\n * @param organization\n * @returns\n */\nexport const setOrganizationAuth = (\n res: ResponseWithInformation,\n organization: Organization\n) => {\n const organizationData = {\n _id: organization._id,\n name: organization.name,\n };\n\n const organizationToken = jwt.sign(\n organizationData,\n process.env.JWT_TOKEN_SECRET!,\n {\n expiresIn: MAX_AGE,\n }\n );\n\n if (!organizationToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_ORGANIZATION', {\n organization,\n });\n }\n\n res.cookie(Cookies.JWT_ORGANIZATION, organizationToken, getCookieOptions());\n\n res.locals.organization = organization;\n};\n\n/**\n * Clears the JWT organization cookies and organization locals object.\n * @param res - Express response object.\n */\nexport const clearOrganizationAuth = (res: ResponseWithInformation) => {\n res.locals.organization = null;\n\n res.cookie(Cookies.JWT_ORGANIZATION, '', getClearCookieOptions());\n};\n\n/**\n * Set project auth locals object\n * @param res - Express response object.\n * @param project - Project object.\n */\nexport const setProjectAuth = (\n res: ResponseWithInformation,\n project: Project\n) => {\n const { organization } = res.locals;\n const projectData = {\n _id: project._id,\n name: project.name,\n };\n\n const projectToken = jwt.sign(projectData, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!projectToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_PROJECT', {\n project,\n });\n }\n\n res.cookie(Cookies.JWT_PROJECT, projectToken, getCookieOptions());\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n project,\n });\n }\n\n if (\n // if the project is not in the organization's projects\n String(organization._id) !== String(project.organizationId)\n ) {\n throw new GenericError('JWT_TOKEN_ORGANIZATION_MISMATCH_PROJECT', {\n project,\n });\n }\n\n res.locals.project = project;\n};\n\n/**\n * Clears the JWT project cookies and project locals object.\n * @param res - Express response object.\n */\nexport const clearProjectAuth = (res: Response) => {\n res.locals.project = null;\n\n res.cookie(Cookies.JWT_PROJECT, '', getClearCookieOptions());\n};\n\n/**\n * Generates a random secret string of a specified length.\n * @param length - The length of the secret.\n * @returns The generated secret string.\n */\nexport const generateSecret = (length: number): string => {\n const characters =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n return Array.from({ length }, () =>\n characters.charAt(Math.floor(Math.random() * characters.length))\n ).join('');\n};\n\n/**\n * Handles a password reset request for a user.\n * @param email - The user's email.\n * @param organization - The organization associated with the user.\n * @returns The user object or null if no user was found.\n */\nexport const requestPasswordReset = async (\n email: string\n): Promise<User | null> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { email });\n }\n\n return updateUserProvider(user._id as unknown as string, 'email', {\n secret: generateSecret(35),\n });\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetUserPassword = async (\n userId: string | ObjectId,\n secret: string,\n newPassword: string\n): Promise<User> => {\n const emailAndPasswordProvider = await getUserProvider(userId, 'email');\n\n if (!emailAndPasswordProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', { userId });\n }\n\n if (!emailAndPasswordProvider.secret) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_DEFINED', { userId });\n }\n\n if (\n !crypto.timingSafeEqual(\n Buffer.from(emailAndPasswordProvider.secret),\n Buffer.from(secret)\n )\n ) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_VALID', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n secret,\n });\n\n return updatedUser;\n};\n\ntype UserProvider<T extends SessionProviders['provider']> = T extends 'email'\n ? EmailPasswordSessionProvider\n : T extends 'google'\n ? GoogleSessionProvider\n : T extends 'github'\n ? GithubSessionProvider\n : SessionProviders;\n\n/**\n * Gets a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to get.\n * @returns The user's provider.\n */\nexport const getUserProvider = async <T extends SessionProviders['provider']>(\n userId: string | ObjectId,\n provider: T,\n providerAccountId?: string\n): Promise<UserProvider<T> | null> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const userProvider = user.provider?.find(\n (providerEl) =>\n (providerEl.provider === provider && !providerAccountId) ||\n (providerAccountId &&\n (providerEl as GithubSessionProvider).providerAccountId ===\n providerAccountId)\n );\n\n return (userProvider as UserProvider<T>) ?? null;\n};\n\n/**\n * Formats the given fields of a user's provider.\n * @param provider - The provider to update.\n * @param user - The user object.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user provider.\n */\nexport const formatUserProviderUpdate = <\n T extends SessionProviders['provider'],\n>(\n provider: T,\n user: Partial<User>,\n providerUpdate: Partial<UserProvider<T>>\n): User['provider'] => {\n const userProvider: SessionProviders[] = ensureMongoDocumentToObject<\n SessionProviders[]\n >(user.provider ?? []);\n\n const userProviderToUpdate = userProvider?.find(\n (providerEl) => providerEl.provider === provider\n );\n\n let updatedProvider: User['provider'];\n\n if (userProviderToUpdate) {\n const otherProviders =\n user.provider?.filter((p) => p.provider !== provider) ?? [];\n\n updatedProvider = [\n ...otherProviders,\n { ...userProviderToUpdate, ...providerUpdate, provider },\n ];\n } else {\n updatedProvider = [\n ...(user.provider ?? []),\n { ...providerUpdate, provider } as SessionProviders,\n ];\n }\n\n return updatedProvider;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to update.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const updateUserProvider = async <\n T extends SessionProviders['provider'],\n>(\n userId: string | ObjectId,\n provider: T,\n providerUpdate: Partial<UserProvider<T>>\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const formattedProviderToUpdate = formatUserProviderUpdate(\n provider,\n user,\n providerUpdate\n );\n\n const updatedUser: UserDocument = await updateUserById(userId, {\n provider: formattedProviderToUpdate,\n });\n\n logger.info(\n `User provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const addUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(userId, provider.provider);\n\n if (existingProvider) {\n throw new GenericError('USER_PROVIDER_ALREADY_EXISTS', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = [...(user.provider ?? []), provider];\n\n const updatedUser = await updateUserById(userId, {\n provider: updatedProvider,\n });\n\n logger.info(\n `User provider added - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider.provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Removes a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to remove.\n * @returns The updated user.\n */\nexport const removeUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders['provider'],\n providerAccountId?: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(\n userId,\n provider,\n providerAccountId\n );\n\n if (!existingProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = user.provider?.filter(\n (p) =>\n p.provider !== provider &&\n (!providerAccountId ||\n (providerAccountId &&\n (p as GithubSessionProvider).providerAccountId !== providerAccountId))\n );\n\n return await updateUserById(userId, {\n provider: updatedProvider,\n });\n};\n\ntype TestUserPasswordResult = { user: User | null; error?: string };\n\n/**\n * Logs in a user.\n * @param email - The user's email.\n * @param password - The user's password.\n * @returns The user object.\n */\nexport const testUserPassword = async (\n email: string,\n password: string\n): Promise<TestUserPasswordResult> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n const errorMessages = {\n en: `User not found - ${email}`,\n fr: `Utilisateur non trouvé - ${email}`,\n es: `Usuario no encontrado - ${email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const userEmailPasswordProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (!userEmailPasswordProvider?.passwordHash) {\n const errorMessages = {\n en: `User request to login but no password defined: ${user.email}`,\n fr: `Demande de connexion d'utilisateur mais pas de mot de passe défini : ${user.email}`,\n es: `Solicitud de inicio de sesión de usuario pero no se define la contraseña : ${user.email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const isMatch = await compare(\n password,\n userEmailPasswordProvider.passwordHash\n );\n\n if (!isMatch) {\n const errorMessages = {\n en: `Incorrect email or password: ${email}`,\n fr: `Email ou mot de passe incorrect : ${email}`,\n es: `Correo electrónico o contraseña incorrecta : ${email}`,\n };\n\n logger.error(errorMessages.en);\n\n // Await a random time to prevent brute force attacks\n const randomNumber = Math.floor(Math.random() * 1000) + 1000;\n await new Promise((resolve) => setTimeout(resolve, randomNumber));\n\n return { user: null, error: t(errorMessages) };\n }\n\n return { user };\n};\n\n/**\n * Hashes a user's password.\n * @param userWithPasswordNotHashed - The user object with password not hashed.\n * @returns The user object with hashed password.\n */\nexport const hashUserPassword = async (\n userWithPasswordNotHashed: UserWithPasswordNotHashed\n): Promise<Partial<UserDocument>> => {\n const { password, ...user } = userWithPasswordNotHashed;\n\n if (!password) {\n throw new GenericError('USER_PASSWORD_NOT_DEFINED', { user });\n }\n\n const userProvider = formatUserProviderUpdate('email', user, {\n passwordHash: await hash(password, await genSalt()),\n secret: generateSecret(35),\n });\n\n return { ...user, provider: userProvider };\n};\n\n/**\n * Changes a user's password.\n * @param userId - The ID of the user.\n * @param newPassword - The user's new password.\n * @returns The updated user or null if the password change failed.\n */\nexport const changeUserPassword = async (\n userId: string | ObjectId,\n newPassword: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n });\n\n return updatedUser;\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetPassword = async (userId: string, password: string) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: UserDocument = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(password, await genSalt()),\n });\n\n return updatedUser;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/services/sessionAuth.service.ts"],"sourcesContent":["import { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport {\n Cookies,\n getClearCookieOptions,\n getCookieOptions,\n MAX_AGE,\n} from '@utils/cookies';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport { mapUserToAPI } from '@utils/mapper/user';\nimport { compare, genSalt, hash } from 'bcryptjs';\nimport crypto from 'crypto';\nimport type { Response } from 'express';\n// @ts-ignore express-intlayer not build yet\nimport type { Organization } from '@/types/organization.types';\nimport type { Project } from '@/types/project.types';\nimport type {\n EmailPasswordSessionProvider,\n GithubSessionProvider,\n GoogleSessionProvider,\n Session,\n SessionProviders,\n} from '@/types/session.types';\nimport type {\n User,\n UserDocument,\n UserWithPasswordNotHashed,\n} from '@/types/user.types';\nimport { t } from 'express-intlayer';\nimport jwt from 'jsonwebtoken';\nimport type { ObjectId } from 'mongoose';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getUserByEmail, getUserById, updateUserById } from './user.service';\n\n/**\n * Adds a session to a user or updates the existing one.\n * @param user - User object.\n * @returns Updated user object.\n */\nexport const addSession = async (user: User): Promise<UserDocument> => {\n const userSessionToken = uuidv4();\n\n const session: Session = {\n sessionToken: userSessionToken,\n expires: new Date(Date.now() + MAX_AGE),\n };\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\nexport const removeSession = async (user: User): Promise<UserDocument> => {\n const session = undefined;\n\n const updatedUser: UserDocument = await updateUserById(user._id, { session });\n\n return updatedUser;\n};\n\n/**\n * Set user auth locals object\n * @param res - Express response object.\n * @param user - User object.\n */\nexport const setUserAuth = async (res: Response, user: User) => {\n const formattedUser = mapUserToAPI(user);\n\n const userToken = jwt.sign(formattedUser, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!userToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_USER', { user });\n }\n\n const cookieOptions = getCookieOptions();\n\n res.cookie(Cookies.JWT_USER, userToken, cookieOptions);\n\n const userWithSession: UserDocument = await addSession(user);\n\n const userSessionToken = userWithSession.session?.sessionToken;\n\n res.cookie(Cookies.JWT_AUTH, userSessionToken, cookieOptions);\n\n res.locals.user = user;\n logger.info(\n `User logged in - User: Name: ${user.name}, id: ${String(user._id)}`\n );\n};\n\n/**\n * Clears the JWT auth cookies and user locals object.\n * @param res - Express response object.\n */\nexport const clearUserAuth = async (res: ResponseWithInformation) => {\n const { user } = res.locals;\n const cookiesOptions = getClearCookieOptions();\n\n if (user) {\n await removeSession(user);\n }\n\n res.cookie(Cookies.JWT_AUTH, '', cookiesOptions);\n res.cookie(Cookies.JWT_USER, '', cookiesOptions);\n\n res.locals.user = null;\n res.locals.authType = null;\n};\n\n/**\n *\n * @param res\n * @param organization\n * @returns\n */\nexport const setOrganizationAuth = (\n res: ResponseWithInformation,\n organization: Organization\n) => {\n const organizationData = {\n _id: organization._id,\n name: organization.name,\n };\n\n const organizationToken = jwt.sign(\n organizationData,\n process.env.JWT_TOKEN_SECRET!,\n {\n expiresIn: MAX_AGE,\n }\n );\n\n if (!organizationToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_ORGANIZATION', {\n organization,\n });\n }\n\n res.cookie(Cookies.JWT_ORGANIZATION, organizationToken, getCookieOptions());\n\n res.locals.organization = organization;\n};\n\n/**\n * Clears the JWT organization cookies and organization locals object.\n * @param res - Express response object.\n */\nexport const clearOrganizationAuth = (res: ResponseWithInformation) => {\n res.locals.organization = null;\n\n res.cookie(Cookies.JWT_ORGANIZATION, '', getClearCookieOptions());\n};\n\n/**\n * Set project auth locals object\n * @param res - Express response object.\n * @param project - Project object.\n */\nexport const setProjectAuth = (\n res: ResponseWithInformation,\n project: Project\n) => {\n const { organization } = res.locals;\n const projectData = {\n _id: project._id,\n name: project.name,\n };\n\n const projectToken = jwt.sign(projectData, process.env.JWT_TOKEN_SECRET!, {\n expiresIn: MAX_AGE,\n });\n\n if (!projectToken) {\n throw new GenericError('JWT_TOKEN_CREATION_FAILED_PROJECT', {\n project,\n });\n }\n\n res.cookie(Cookies.JWT_PROJECT, projectToken, getCookieOptions());\n\n if (!organization) {\n throw new GenericError('ORGANIZATION_NOT_FOUND', {\n project,\n });\n }\n\n if (\n // if the project is not in the organization's projects\n String(organization._id) !== String(project.organizationId)\n ) {\n throw new GenericError('JWT_TOKEN_ORGANIZATION_MISMATCH_PROJECT', {\n project,\n });\n }\n\n res.locals.project = project;\n};\n\n/**\n * Clears the JWT project cookies and project locals object.\n * @param res - Express response object.\n */\nexport const clearProjectAuth = (res: Response) => {\n res.locals.project = null;\n\n res.cookie(Cookies.JWT_PROJECT, '', getClearCookieOptions());\n};\n\n/**\n * Generates a random secret string of a specified length.\n * @param length - The length of the secret.\n * @returns The generated secret string.\n */\nexport const generateSecret = (length: number): string => {\n const characters =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n return Array.from({ length }, () =>\n characters.charAt(Math.floor(Math.random() * characters.length))\n ).join('');\n};\n\n/**\n * Handles a password reset request for a user.\n * @param email - The user's email.\n * @param organization - The organization associated with the user.\n * @returns The user object or null if no user was found.\n */\nexport const requestPasswordReset = async (\n email: string\n): Promise<User | null> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { email });\n }\n\n return updateUserProvider(user._id as unknown as string, 'email', {\n secret: generateSecret(35),\n });\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetUserPassword = async (\n userId: string | ObjectId,\n secret: string,\n newPassword: string\n): Promise<User> => {\n const emailAndPasswordProvider = await getUserProvider(userId, 'email');\n\n if (!emailAndPasswordProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', { userId });\n }\n\n if (!emailAndPasswordProvider.secret) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_DEFINED', { userId });\n }\n\n if (\n !crypto.timingSafeEqual(\n Buffer.from(emailAndPasswordProvider.secret),\n Buffer.from(secret)\n )\n ) {\n throw new GenericError('USER_PROVIDER_SECRET_NOT_VALID', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n secret,\n });\n\n return updatedUser;\n};\n\ntype UserProvider<T extends SessionProviders['provider']> = T extends 'email'\n ? EmailPasswordSessionProvider\n : T extends 'google'\n ? GoogleSessionProvider\n : T extends 'github'\n ? GithubSessionProvider\n : SessionProviders;\n\n/**\n * Gets a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to get.\n * @returns The user's provider.\n */\nexport const getUserProvider = async <T extends SessionProviders['provider']>(\n userId: string | ObjectId,\n provider: T,\n providerAccountId?: string\n): Promise<UserProvider<T> | null> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const userProvider = user.provider?.find(\n (providerEl) =>\n (providerEl.provider === provider && !providerAccountId) ||\n (providerAccountId &&\n (providerEl as GithubSessionProvider).providerAccountId ===\n providerAccountId)\n );\n\n return (userProvider as UserProvider<T>) ?? null;\n};\n\n/**\n * Formats the given fields of a user's provider.\n * @param provider - The provider to update.\n * @param user - The user object.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user provider.\n */\nexport const formatUserProviderUpdate = <\n T extends SessionProviders['provider'],\n>(\n provider: T,\n user: Partial<User>,\n providerUpdate: Partial<UserProvider<T>>\n): User['provider'] => {\n const userProvider: SessionProviders[] = ensureMongoDocumentToObject<\n SessionProviders[]\n >(user.provider ?? []);\n\n const userProviderToUpdate = userProvider?.find(\n (providerEl) => providerEl.provider === provider\n );\n\n let updatedProvider: User['provider'];\n\n if (userProviderToUpdate) {\n const otherProviders =\n user.provider?.filter((p) => p.provider !== provider) ?? [];\n\n updatedProvider = [\n ...otherProviders,\n { ...userProviderToUpdate, ...providerUpdate, provider },\n ];\n } else {\n updatedProvider = [\n ...(user.provider ?? []),\n { ...providerUpdate, provider } as SessionProviders,\n ];\n }\n\n return updatedProvider;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to update.\n * @param providerUpdate - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const updateUserProvider = async <\n T extends SessionProviders['provider'],\n>(\n userId: string | ObjectId,\n provider: T,\n providerUpdate: Partial<UserProvider<T>>\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const formattedProviderToUpdate = formatUserProviderUpdate(\n provider,\n user,\n providerUpdate\n );\n\n const updatedUser: UserDocument = await updateUserById(userId, {\n provider: formattedProviderToUpdate,\n });\n\n logger.info(\n `User provider updated - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Updates the given fields of a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The updates to apply to the provider.\n * @returns The updated user.\n */\nexport const addUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders\n): Promise<UserDocument> => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(userId, provider.provider);\n\n if (existingProvider) {\n throw new GenericError('USER_PROVIDER_ALREADY_EXISTS', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = [...(user.provider ?? []), provider];\n\n const updatedUser = await updateUserById(userId, {\n provider: updatedProvider,\n });\n\n logger.info(\n `User provider added - User: Name: ${updatedUser.name}, id: ${String(updatedUser._id)} - Provider: ${provider.provider}`\n );\n\n return updatedUser;\n};\n\n/**\n * Removes a user's provider.\n * @param userId - The ID of the user.\n * @param provider - The provider to remove.\n * @returns The updated user.\n */\nexport const removeUserProvider = async (\n userId: string | ObjectId,\n provider: SessionProviders['provider'],\n providerAccountId?: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const existingProvider = await getUserProvider(\n userId,\n provider,\n providerAccountId\n );\n\n if (!existingProvider) {\n throw new GenericError('USER_PROVIDER_NOT_FOUND', {\n userId,\n provider,\n });\n }\n\n const updatedProvider = user.provider?.filter(\n (p) =>\n p.provider !== provider &&\n (!providerAccountId ||\n (providerAccountId &&\n (p as GithubSessionProvider).providerAccountId !== providerAccountId))\n );\n\n return await updateUserById(userId, {\n provider: updatedProvider,\n });\n};\n\ntype TestUserPasswordResult = { user: User | null; error?: string };\n\n/**\n * Logs in a user.\n * @param email - The user's email.\n * @param password - The user's password.\n * @returns The user object.\n */\nexport const testUserPassword = async (\n email: string,\n password: string\n): Promise<TestUserPasswordResult> => {\n const user = await getUserByEmail(email);\n\n if (!user) {\n const errorMessages = {\n en: `User not found - ${email}`,\n fr: `Utilisateur non trouvé - ${email}`,\n es: `Usuario no encontrado - ${email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const userEmailPasswordProvider = user.provider?.find(\n (provider) => provider.provider === 'email'\n );\n\n if (!userEmailPasswordProvider?.passwordHash) {\n const errorMessages = {\n en: `User request to login but no password defined: ${user.email}`,\n fr: `Demande de connexion d'utilisateur mais pas de mot de passe défini : ${user.email}`,\n es: `Solicitud de inicio de sesión de usuario pero no se define la contraseña : ${user.email}`,\n };\n\n return { user: null, error: t(errorMessages) };\n }\n\n const isMatch = await compare(\n password,\n userEmailPasswordProvider.passwordHash\n );\n\n if (!isMatch) {\n const errorMessages = {\n en: `Incorrect email or password: ${email}`,\n fr: `Email ou mot de passe incorrect : ${email}`,\n es: `Correo electrónico o contraseña incorrecta : ${email}`,\n };\n\n logger.error(errorMessages.en);\n\n // Await a random time to prevent brute force attacks\n const randomNumber = Math.floor(Math.random() * 1000) + 1000;\n await new Promise((resolve) => setTimeout(resolve, randomNumber));\n\n return { user: null, error: t(errorMessages) };\n }\n\n return { user };\n};\n\n/**\n * Hashes a user's password.\n * @param userWithPasswordNotHashed - The user object with password not hashed.\n * @returns The user object with hashed password.\n */\nexport const hashUserPassword = async (\n userWithPasswordNotHashed: UserWithPasswordNotHashed\n): Promise<Partial<UserDocument>> => {\n const { password, ...user } = userWithPasswordNotHashed;\n\n if (!password) {\n throw new GenericError('USER_PASSWORD_NOT_DEFINED', { user });\n }\n\n const userProvider = formatUserProviderUpdate('email', user, {\n passwordHash: await hash(password, await genSalt()),\n secret: generateSecret(35),\n });\n\n return { ...user, provider: userProvider };\n};\n\n/**\n * Changes a user's password.\n * @param userId - The ID of the user.\n * @param newPassword - The user's new password.\n * @returns The updated user or null if the password change failed.\n */\nexport const changeUserPassword = async (\n userId: string | ObjectId,\n newPassword: string\n) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: User = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(newPassword, await genSalt()),\n });\n\n return updatedUser;\n};\n\n/**\n * Resets a user's password.\n * @param userId - The ID of the user.\n * @param secret - The secret token associated with the user.\n * @param newPassword - The new password to set.\n * @returns The updated user or null if the reset failed.\n */\nexport const resetPassword = async (userId: string, password: string) => {\n const user = await getUserById(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n const updatedUser: UserDocument = await updateUserProvider(userId, 'email', {\n passwordHash: await hash(password, await genSalt()),\n });\n\n return updatedUser;\n};\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import type { ResponseWithInformation } from '../middlewares/sessionAuth.middleware';
2
2
  import type { Response } from 'express';
3
- import type { ObjectId } from 'mongoose';
4
3
  import type { Organization } from '../types/organization.types';
5
4
  import type { Project } from '../types/project.types';
6
- import type { SessionProviders, EmailPasswordSessionProvider, GoogleSessionProvider, GithubSessionProvider } from '../types/session.types';
5
+ import type { EmailPasswordSessionProvider, GithubSessionProvider, GoogleSessionProvider, SessionProviders } from '../types/session.types';
7
6
  import type { User, UserDocument, UserWithPasswordNotHashed } from '../types/user.types';
7
+ import type { ObjectId } from 'mongoose';
8
8
  /**
9
9
  * Adds a session to a user or updates the existing one.
10
10
  * @param user - User object.
@@ -1 +1 @@
1
- {"version":3,"file":"sessionAuth.service.d.ts","sourceRoot":"","sources":["../../../src/services/sessionAuth.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessionAuth.service.d.ts","sourceRoot":"","sources":["../../../src/services/sessionAuth.service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/backend",
3
- "version": "5.4.1",
3
+ "version": "5.4.2",
4
4
  "private": false,
5
5
  "description": "Intlayer Backend is a an application that allow you to manage your Intlayer content and interact with the intlayer editor.",
6
6
  "keywords": [
@@ -51,8 +51,7 @@
51
51
  ],
52
52
  "dependencies": {
53
53
  "@react-email/components": "^0.0.34",
54
- "@types/node": "^22.13.10",
55
- "bcrypt": "^5.1.1",
54
+ "bcryptjs": "^3.0.2",
56
55
  "compression": "^1.8.0",
57
56
  "cookie-parser": "^1.4.7",
58
57
  "cors": "^2.8.5",
@@ -74,10 +73,9 @@
74
73
  "uuid": "^11.1.0",
75
74
  "validator": "^13.12.0",
76
75
  "winston": "^3.17.0",
77
- "express-intlayer": "5.4.1"
76
+ "express-intlayer": "5.4.2"
78
77
  },
79
78
  "devDependencies": {
80
- "@types/bcrypt": "^5.0.2",
81
79
  "@types/body-parser": "^1.19.5",
82
80
  "@types/compression": "^1.7.5",
83
81
  "@types/cookie-parser": "^1.4.8",
@@ -99,15 +97,15 @@
99
97
  "tsup": "^8.4.0",
100
98
  "tsx": "^4.19.3",
101
99
  "typescript": "^5.8.2",
102
- "@intlayer/blog": "5.4.1",
103
- "@intlayer/config": "5.4.1",
100
+ "@intlayer/core": "5.4.2",
101
+ "@intlayer/config": "5.4.2",
104
102
  "@utils/eslint-config": "1.0.4",
105
- "@intlayer/core": "5.4.1",
106
103
  "@utils/ts-config": "1.0.4",
107
- "@utils/tsup-config": "1.0.4",
108
- "@intlayer/docs": "5.4.1",
109
104
  "@utils/ts-config-types": "1.0.4",
110
- "intlayer": "5.4.1"
105
+ "@utils/tsup-config": "1.0.4",
106
+ "intlayer": "5.4.2",
107
+ "@intlayer/blog": "5.4.2",
108
+ "@intlayer/docs": "5.4.2"
111
109
  },
112
110
  "scripts": {
113
111
  "build": "pnpm build:package & pnpm build:types",