cca-auth-module 0.1.74 → 0.1.76

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.
@@ -8,5 +8,5 @@ export declare class TwoFactorEnableUseCase implements IBaseService {
8
8
  private isInitialized;
9
9
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
10
10
  initialize(): Promise<void>;
11
- execute(userId: string, dto: ITwoFactorEnable): Promise<void>;
11
+ execute(dto: ITwoFactorEnable): Promise<void>;
12
12
  }
@@ -8,5 +8,5 @@ export declare class TwoFactorSetupUseCase implements IBaseService {
8
8
  private isInitialized;
9
9
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
10
10
  initialize(): Promise<void>;
11
- execute(token: string): Promise<ITwoFactorSetupResponse>;
11
+ execute(userId: string): Promise<ITwoFactorSetupResponse>;
12
12
  }
package/dist/index.d.mts CHANGED
@@ -155,7 +155,7 @@ declare class TwoFactorSetupUseCase implements IBaseService {
155
155
  private isInitialized;
156
156
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
157
157
  initialize(): Promise<void>;
158
- execute(token: string): Promise<ITwoFactorSetupResponse>;
158
+ execute(userId: string): Promise<ITwoFactorSetupResponse>;
159
159
  }
160
160
 
161
161
  interface ITwoFactorEnable {
@@ -169,7 +169,7 @@ declare class TwoFactorEnableUseCase implements IBaseService {
169
169
  private isInitialized;
170
170
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
171
171
  initialize(): Promise<void>;
172
- execute(userId: string, dto: ITwoFactorEnable): Promise<void>;
172
+ execute(dto: ITwoFactorEnable): Promise<void>;
173
173
  }
174
174
 
175
175
  interface ITwoFactorVerify {
package/dist/index.d.ts CHANGED
@@ -155,7 +155,7 @@ declare class TwoFactorSetupUseCase implements IBaseService {
155
155
  private isInitialized;
156
156
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
157
157
  initialize(): Promise<void>;
158
- execute(token: string): Promise<ITwoFactorSetupResponse>;
158
+ execute(userId: string): Promise<ITwoFactorSetupResponse>;
159
159
  }
160
160
 
161
161
  interface ITwoFactorEnable {
@@ -169,7 +169,7 @@ declare class TwoFactorEnableUseCase implements IBaseService {
169
169
  private isInitialized;
170
170
  constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository);
171
171
  initialize(): Promise<void>;
172
- execute(userId: string, dto: ITwoFactorEnable): Promise<void>;
172
+ execute(dto: ITwoFactorEnable): Promise<void>;
173
173
  }
174
174
 
175
175
  interface ITwoFactorVerify {
package/dist/index.js CHANGED
@@ -546,7 +546,6 @@ __name(_RefreshTokenUseCase, "RefreshTokenUseCase");
546
546
  var RefreshTokenUseCase = _RefreshTokenUseCase;
547
547
 
548
548
  // src/application/useCase/TwoFactorSetupUseCase.ts
549
- var import_jwt_decode2 = require("jwt-decode");
550
549
  var _TwoFactorSetupUseCase = class _TwoFactorSetupUseCase {
551
550
  constructor(twoFactorService, authRepository) {
552
551
  this.isInitialized = false;
@@ -560,24 +559,20 @@ var _TwoFactorSetupUseCase = class _TwoFactorSetupUseCase {
560
559
  ]);
561
560
  this.isInitialized = true;
562
561
  }
563
- async execute(token) {
562
+ async execute(userId) {
564
563
  if (!this.isInitialized) {
565
564
  await this.initialize();
566
565
  }
567
- if (!token) {
568
- throw new TwoFactorError("Token is required");
569
- }
570
- const decoded = (0, import_jwt_decode2.jwtDecode)(token);
571
- const user = await this.authRepository.findByUserId(decoded.userId);
566
+ const user = await this.authRepository.findByUserId(userId);
572
567
  if (!user) {
573
- throw new TwoFactorError("User not found");
568
+ throw new ForbiddenError("User not found");
574
569
  }
575
570
  if (user.twoFactorEnabled) {
576
571
  throw new TwoFactorError("Two-factor authentication is already enabled");
577
572
  }
578
573
  const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);
579
574
  const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);
580
- await this.authRepository.updateTwoFactorSecret(decoded.userId, secret);
575
+ await this.authRepository.updateTwoFactorSecret(userId, secret);
581
576
  return { qrCodeUrl };
582
577
  }
583
578
  };
@@ -600,11 +595,11 @@ var _TwoFactorEnableUseCase = class _TwoFactorEnableUseCase {
600
595
  ]);
601
596
  this.isInitialized = true;
602
597
  }
603
- async execute(userId, dto) {
598
+ async execute(dto) {
604
599
  if (!this.isInitialized) {
605
600
  await this.initialize();
606
601
  }
607
- const { token } = dto;
602
+ const { token, userId } = dto;
608
603
  if (!token) {
609
604
  throw new TwoFactorError("Token is required");
610
605
  }
@@ -807,10 +802,10 @@ var _AuthController = class _AuthController {
807
802
  }, "refreshToken");
808
803
  this.setup2FA = /* @__PURE__ */ __name(async (req, res, next) => {
809
804
  try {
810
- console.log(" req.headers.authorization", req.headers.authorization);
811
- const authHeader = req.headers.authorization;
812
- const token = authHeader?.split(" ")[1]?.replace(/^"|"$/g, "");
813
- const result = await this.twoFactorSetupUseCase.execute(token);
805
+ if (!req.auth || !req.auth.id) {
806
+ throw new ForbiddenError("User authentication required");
807
+ }
808
+ const result = await this.twoFactorSetupUseCase.execute(req.auth.id);
814
809
  res.status(200).json(result);
815
810
  } catch (error) {
816
811
  next(error);
@@ -818,9 +813,9 @@ var _AuthController = class _AuthController {
818
813
  }, "setup2FA");
819
814
  this.enable2FA = /* @__PURE__ */ __name(async (req, res, next) => {
820
815
  try {
821
- const userId = req.auth?.id;
822
816
  const dto = req.body;
823
- await this.twoFactorEnableUseCase.execute(userId, dto);
817
+ dto.userId = req.auth?.id;
818
+ await this.twoFactorEnableUseCase.execute(dto);
824
819
  res.status(200).json({ message: "Two-factor authentication has been enabled successfully" });
825
820
  } catch (error) {
826
821
  next(error);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/application/config/ConfigManager.ts","../src/utils/Errors.ts","../src/application/service/utils/configInstance.ts","../src/infrastructure/container/createAuthContainer.ts","../src/application/useCase/LoginUseCase.ts","../src/application/validators/authValidation.ts","../src/application/useCase/LoginAdminUseCase.ts","../src/application/useCase/LogoutUseCase.ts","../src/application/useCase/RegisterUseCase.ts","../src/application/mappers/utils/mapper.ts","../src/application/mappers/createUserMappings.ts","../src/application/dtos/RegisterDTO.ts","../src/application/dtos/UserDTO.ts","../src/application/dtos/AdminDTO.ts","../src/application/useCase/RefreshTokenUseCase.ts","../src/application/useCase/TwoFactorSetupUseCase.ts","../src/application/useCase/TwoFactorEnableUseCase.ts","../src/application/useCase/TwoFactorVerifyUseCase.ts","../src/application/useCase/TwoFactorDisableUseCase.ts","../src/presentation/controller/AuthController.ts","../src/presentation/middleware/RequireComplete2FA.ts","../src/infrastructure/repository/AuthRepository.ts","../src/infrastructure/services/JwtAuthService.ts","../src/infrastructure/services/TwoFactorService.ts"],"sourcesContent":["import { authConfig } from \"./application/service/utils/configInstance\";\r\nimport { ConfigSource, IConfig } from \"./domain/interfaces/configTypes\";\r\nimport { createAuthContainer } from \"./infrastructure/container/createAuthContainer\";\r\nimport { AuthController } from \"./presentation/controller/AuthController\";\r\n\r\nexport { createAuthContainer, AuthController, authConfig, ConfigSource, IConfig };\r\n","import { EventEmitter } from \"events\";\r\nimport { IConfig, ConfigSource } from \"../../domain/interfaces/configTypes\";\r\nimport { ConfigNotFoundException } from \"../../utils/Errors\";\r\n\r\nexport class ConfigManager extends EventEmitter {\r\n private config?: IConfig;\r\n private configSource?: ConfigSource;\r\n\r\n setConfigSource(source: ConfigSource): void {\r\n this.configSource = source;\r\n }\r\n\r\n setConfig(cfg: IConfig): void {\r\n this.config = { ...cfg };\r\n this.emit(\"configAvailable\", this.config);\r\n }\r\n\r\n getConfig(): IConfig | undefined {\r\n return this.config;\r\n }\r\n\r\n async loadConfig(): Promise<IConfig> {\r\n if (!this.configSource) {\r\n throw new ConfigNotFoundException(\"Config source not set\");\r\n }\r\n try {\r\n const config = await this.configSource();\r\n this.setConfig(config);\r\n return config;\r\n } catch (error) {\r\n throw new ConfigNotFoundException(\"Error loading configuration\");\r\n }\r\n }\r\n}\r\n\r\nexport const configManager = new ConfigManager();\r\n","export class AppError extends Error {\r\n constructor(\r\n public message: string,\r\n public statusCode: number = 500,\r\n public name: string = \"AppError\"\r\n ) {\r\n super(message);\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n Error.captureStackTrace(this);\r\n }\r\n}\r\n\r\nexport class ValidationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"ValidationError\";\r\n }\r\n}\r\n\r\nexport class ConfigNotFoundException extends AppError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"ConfigNotFoundException\";\r\n }\r\n}\r\n\r\nexport class NotFoundError extends AppError {\r\n constructor(message: string) {\r\n super(message, 404, \"UserNotFoundError\");\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends AppError {\r\n constructor(message: string = \"Forbidden access\") {\r\n super(message, 403);\r\n this.name = \"ForbiddenError\";\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends AppError {\r\n constructor(message: string = \"Unauthorized access\") {\r\n super(message, 401);\r\n this.name = \"UnauthorizedError\";\r\n }\r\n}\r\n\r\nexport class JwtError extends AppError {\r\n constructor(message: string) {\r\n super(message, 401);\r\n this.name = \"JwtError\";\r\n }\r\n}\r\n\r\nexport class RegistrationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"RegistrationError\";\r\n }\r\n}\r\n\r\nexport class TwoFactorError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"TwoFactorERROR\";\r\n }\r\n}","import { configManager } from \"../../config/ConfigManager\";\r\nimport { IConfig, ConfigSource } from \"../../../domain/interfaces/configTypes\";\r\n\r\nexport const authConfig = (configSource: ConfigSource): void => {\r\n configManager.setConfigSource(configSource);\r\n};\r\n\r\nexport const createConfigInstance = async (): Promise<IConfig> => {\r\n return configManager.getConfig() ?? (await configManager.loadConfig());\r\n};\r\n","import { BaseContainer, BaseDatabase } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { AuthController } from \"../../presentation/controller/AuthController\";\r\nimport { RequireComplete2FA } from \"../../presentation/middleware/RequireComplete2FA\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { JwtAuthService } from \"../services/JwtAuthService\";\r\nimport { TwoFactorService } from \"../services/TwoFactorService\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\n\r\nasync function createAuthContainer(database: BaseDatabase) {\r\n const container = new BaseContainer({ database });\r\n\r\n const authRepository = new AuthRepository(\r\n database.getRepository(AuthEntity)\r\n );\r\n container.registerRepository<AuthEntity>(\"AuthRepository\", authRepository);\r\n\r\n const jwtAuthService = new JwtAuthService(authRepository);\r\n container.registerService(\"JwtAuthService\", jwtAuthService);\r\n\r\n const configData = await createConfigInstance();\r\n\r\n const twoFactorService = new TwoFactorService(configData);\r\n container.registerService(\"TwoFactorService\", twoFactorService);\r\n\r\n const requireComplete2FA = new RequireComplete2FA(jwtAuthService);\r\n\r\n const loginUseCase = new LoginUseCase(authRepository, jwtAuthService);\r\n const loginAdminUseCase = new LoginAdminUseCase(\r\n authRepository\r\n );\r\n const logoutUseCase = new LogoutUseCase(authRepository);\r\n const registerUseCase = new RegisterUseCase(authRepository);\r\n const refreshTokenUseCase = new RefreshTokenUseCase(\r\n authRepository,\r\n jwtAuthService\r\n );\r\n\r\n const twoFactorSetupUseCase = new TwoFactorSetupUseCase(twoFactorService, authRepository);\r\n const twoFactorEnableUseCase = new TwoFactorEnableUseCase(twoFactorService, authRepository);\r\n const twoFactorVerifyUseCase = new TwoFactorVerifyUseCase(\r\n twoFactorService,\r\n authRepository,\r\n jwtAuthService\r\n );\r\n const twoFactorDisableUseCase = new TwoFactorDisableUseCase(twoFactorService, authRepository);\r\n\r\n container.registerService(\"LoginUseCase\", loginUseCase);\r\n container.registerService(\"LoginAdminUseCase\", loginAdminUseCase);\r\n container.registerService(\"LogoutUseCase\", logoutUseCase);\r\n container.registerService(\"RegisterUseCase\", registerUseCase);\r\n container.registerService(\"RefreshTokenUseCase\", refreshTokenUseCase);\r\n container.registerService(\"TwoFactorSetupUseCase\", twoFactorSetupUseCase);\r\n container.registerService(\"TwoFactorEnableUseCase\", twoFactorEnableUseCase);\r\n container.registerService(\"TwoFactorVerifyUseCase\", twoFactorVerifyUseCase);\r\n container.registerService(\"TwoFactorDisableUseCase\", twoFactorDisableUseCase);\r\n\r\n const authController = new AuthController(\r\n loginUseCase,\r\n loginAdminUseCase,\r\n logoutUseCase,\r\n registerUseCase,\r\n refreshTokenUseCase,\r\n twoFactorSetupUseCase,\r\n twoFactorEnableUseCase,\r\n twoFactorVerifyUseCase,\r\n twoFactorDisableUseCase\r\n );\r\n\r\n return { container, authController, requireComplete2FA };\r\n}\r\n\r\nexport { createAuthContainer };","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { jwtDecode } from \"jwt-decode\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateLoginDTO } from \"../validators/authValidation\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { IJwtPayload } from \"../../domain/interfaces/IJwtPayload\";\r\n\r\n\r\nexport class LoginUseCase implements IBaseService {\r\n\r\n constructor(\r\n private readonly repository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO): Promise<{ id: string, accessToken: string, expiresAt: number , enabled?: boolean }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n \r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n const expiresAt = jwtDecode<IJwtPayload>(accessToken).exp;\r\n\r\n if (auth.twoFactorEnabled) {\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt, enabled: auth.twoFactorEnabled };\r\n }\r\n\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt };\r\n }\r\n}","import * as yup from \"yup\";\r\nimport { AuthEntity, UserRole } from \"cca-entities\";\r\nimport bcrypt from \"bcrypt\";\r\n\r\nimport {\r\n ForbiddenError,\r\n NotFoundError,\r\n ValidationError,\r\n} from \"../../utils/Errors\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\n\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { createConfigInstance } from \"../service/utils/configInstance\";\r\n\r\nconst schemas = {\r\n id: yup.string().uuid(\"Invalid user ID format\"),\r\n email: yup\r\n .string()\r\n .email(\"Invalid email format\")\r\n .max(255, \"Email cannot exceed 255 characters\"),\r\n name: yup\r\n .string()\r\n .required(\"Name is required\")\r\n .min(2, \"Name must be at least 2 characters long\")\r\n .max(50, \"Name cannot exceed 50 characters\")\r\n .matches(/^[a-zA-Z\\s]+$/, \"Name must only contain letters and spaces\"),\r\n password: yup\r\n .string()\r\n .required(\"Password required\")\r\n .min(8, \"Password too short\")\r\n .max(100, \"Password too long\")\r\n .matches(\r\n /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]/,\r\n \"Password must contain uppercase, lowercase, number and special character\"\r\n ),\r\n role: yup\r\n .string()\r\n .oneOf(Object.values(UserRole), \"Invalid role specified\"),\r\n};\r\n\r\nexport const validateEmail = async (\r\n email: string,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n const user = await repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\r\n \"The email address or password is incorrect. Please retry\"\r\n );\r\n }\r\n return user;\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid email format\");\r\n }\r\n};\r\n\r\nexport const validatePassword = async (password?: string): Promise<void> => {\r\n if (password) {\r\n try {\r\n await schemas.password.validate(password);\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid password format\");\r\n }\r\n }\r\n};\r\n\r\nexport const validateEmailUniqueness = async (\r\n repository: AuthRepository,\r\n email: string,\r\n excludeUserId?: string\r\n): Promise<void> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n\r\n const existingUser = await repository.findByEmail(email);\r\n\r\n if (!existingUser) return;\r\n if (existingUser.id === excludeUserId) return;\r\n\r\n throw new ValidationError(`Email ${email} is already in use.`);\r\n } catch (error: any) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"user email validation failed\");\r\n }\r\n};\r\n\r\nexport const validateRegisterDTO = async (\r\n auth: RegisterDTO,\r\n repository: AuthRepository\r\n): Promise<void> => {\r\n const { name, email, role, password } = auth;\r\n\r\n await Promise.all([\r\n schemas.name.validate(name),\r\n schemas.role.validate(role),\r\n validateEmailUniqueness(repository, email),\r\n validatePassword(password),\r\n ]);\r\n};\r\n\r\nexport const validateLoginDTO = async (\r\n data: LoginDTO,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n const { email, role, password } = data;\r\n\r\n if (role) {\r\n await schemas.role.validate(role);\r\n }\r\n\r\n await schemas.password.validate(password);\r\n\r\n const auth = await validateEmail(email, repository);\r\n if (!auth || !auth.password) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const isMatch = await bcrypt.compare(password, auth.password);\r\n if (!isMatch) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return auth;\r\n};\r\n\r\nexport const validateAdminSecret = async (\r\n secretPassword?: string\r\n): Promise<void> => {\r\n if (!secretPassword) {\r\n throw new ValidationError(\"Admin password is required\");\r\n }\r\n\r\n try {\r\n const config = await createConfigInstance();\r\n\r\n if (!config.adminSecretPassword) {\r\n throw new ValidationError(\"ADMIN_SECRET_PASSWORD not found in config\");\r\n }\r\n\r\n if (parseInt(secretPassword) !== parseInt(config.adminSecretPassword)) {\r\n throw new ValidationError(\"Invalid admin password\");\r\n }\r\n } catch (error) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"Error validating admin password\");\r\n }\r\n};\r\n","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateAdminSecret, validateLoginDTO } from \"../validators/authValidation\";\r\n\r\nexport class LoginAdminUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n\r\n constructor(\r\n repository: AuthRepository\r\n ) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO, adminPassword: string): Promise<string> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\n\r\nexport class LogoutUseCase implements IBaseService {\r\n private readonly repository: AuthRepository\r\n\r\n constructor(repository: AuthRepository) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(authId: string): Promise<void> {\r\n try {\r\n await this.repository.logout(authId);\r\n } catch (error) {\r\n new NotFoundError(\"Auth not found\");\r\n }\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { AdminEntity, AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private readonly SALT_ROUNDS = 10;\r\n\r\n constructor(private readonly repository: AuthRepository) {}\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo) => repo.getAll());\r\n }\r\n\r\n public async execute(\r\n email: string,\r\n name: string,\r\n password: string,\r\n role: UserRole = UserRole.GUEST,\r\n adminPassword?: string\r\n ): Promise<AuthEntity | undefined> {\r\n try {\r\n const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });\r\n\r\n const isAdminUser = await this._validateAdminRegistration(\r\n normalizedDTO.role,\r\n normalizedDTO.adminPassword\r\n );\r\n\r\n await validateRegisterDTO(normalizedDTO, this.repository);\r\n\r\n const hashedPassword = await this._hashPassword(normalizedDTO.password);\r\n const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);\r\n\r\n return this.repository.create(authEntity);\r\n } catch (error) {\r\n throw new RegistrationError(\r\n `Registration failed: ${error instanceof Error ? error.message : \"Unknown error\"}`\r\n );\r\n }\r\n }\r\n\r\n private _normalizeInput(dto: RegisterDTO): RegisterDTO {\r\n return {\r\n name: dto.name.trim(),\r\n email: dto.email.trim().toLowerCase(),\r\n password: dto.password.trim(),\r\n role: dto.role,\r\n adminPassword: dto.adminPassword?.trim()\r\n };\r\n }\r\n\r\n private async _hashPassword(password: string): Promise<string> {\r\n return bcrypt.hash(password, this.SALT_ROUNDS);\r\n }\r\n\r\n private async _validateAdminRegistration(\r\n role: UserRole,\r\n adminPassword?: string\r\n ): Promise<boolean> {\r\n if (role !== UserRole.ADMIN) return false;\r\n\r\n if (!adminPassword) {\r\n throw new UnauthorizedError(\"Admin password is required for admin registration\");\r\n }\r\n\r\n await validateAdminSecret(adminPassword);\r\n return true;\r\n }\r\n\r\n private _buildMappedAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): AuthEntity {\r\n const authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userOrAdminEntity = isAdmin\r\n ? mapper.map(dto, RegisterDTO, AdminEntity)\r\n : mapper.map(dto, RegisterDTO, UserEntity);\r\n\r\n userOrAdminEntity.updatedAt = undefined as unknown as Date;\r\n\r\n if (isAdmin) {\r\n authEntity.admin = userOrAdminEntity;\r\n } else {\r\n authEntity.user = userOrAdminEntity;\r\n }\r\n\r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n\r\n return authEntity;\r\n }\r\n}\r\n","import { createMapper } from '@automapper/core';\r\nimport { classes } from '@automapper/classes';\r\n\r\nimport { createUserMappings } from '../createUserMappings';\r\n\r\nexport const mapper = createMapper({\r\n strategyInitializer: classes(),\r\n});\r\n\r\ncreateUserMappings(mapper);\r\n","import { Mapper, createMap, forMember, mapFrom } from '@automapper/core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { RegisterDTO } from '../dtos/RegisterDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\n\r\nexport function createUserMappings(mapper: Mapper): void {\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AuthEntity,\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.password, mapFrom(src => src.password)),\r\n forMember(dest => dest.role, mapFrom(src => src.role)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n UserEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AdminEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n UserEntity,\r\n UserDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.profileImageUrl, mapFrom(src => getProfileImageUrl(src))));\r\n\r\n\r\n createMap(\r\n mapper,\r\n AdminEntity,\r\n AdminDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n const getProfileImageUrl = (src: UserEntity): string | undefined => {\r\n const image = src.images?.[0];\r\n if (!image) return undefined;\r\n return image.mdUrl ?? image.smUrl ?? image.lgUrl ?? image.thumbUrl ?? image.originalUrl ?? image.xlUrl;\r\n };\r\n}","import { UserRole } from \"cca-entities\";\r\n\r\nexport class RegisterDTO {\r\n email!: string;\r\n name!: string;\r\n password!: string;\r\n role!: UserRole;\r\n adminPassword?: string;\r\n}\r\n","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class UserDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n @AutoMap()\r\n profileImageUrl?: string;\r\n}","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class AdminDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n adminPassword!: string;\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { ITokenPair } from \"../../domain/interfaces/ITokenPair\";\r\n\r\nexport class RefreshTokenUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n private readonly service: JwtAuthService;\r\n\r\n constructor(repository: AuthRepository, service: JwtAuthService) {\r\n this.repository = repository;\r\n this.service = service;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n public async execute(refreshToken: string): Promise<ITokenPair | null> {\r\n try {\r\n const decoded = await this.service.verifyRefreshToken(refreshToken);\r\n\r\n if (!decoded.userId) {\r\n return null;\r\n }\r\n\r\n let authEntity = await this.repository.findByUseAdminId(decoded.userId);\r\n\r\n if (!authEntity) {\r\n authEntity = await this.repository.findByUseAdminId(decoded.userId, true);\r\n }\r\n\r\n if (!authEntity) {\r\n return null;\r\n }\r\n\r\n const user = authEntity.role === \"admin\" ? authEntity.admin : authEntity.user;\r\n\r\n const accessToken = this.service.generateAccessToken(user, authEntity.role);\r\n const newRefreshToken = this.service.generateRefreshToken(user);\r\n\r\n await this.repository.update(authEntity.id, {\r\n refreshToken: newRefreshToken\r\n });\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken\r\n };\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n}","import { IBaseService } from 'cca-core';\r\nimport { jwtDecode } from 'jwt-decode';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorSetupResponse } from '../../domain/interfaces/ITwoFactorSetupResponse';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { IJwtPayload } from '../../domain/interfaces/IJwtPayload';\r\n\r\nexport class TwoFactorSetupUseCase implements IBaseService {\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n await Promise.all([\r\n this.twoFactorService.initialize()\r\n ]);\r\n\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(token: string): Promise<ITwoFactorSetupResponse> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n const decoded = jwtDecode<IJwtPayload>(token);\r\n const user = await this.authRepository.findByUserId(decoded.userId);\r\n\r\n if (!user) {\r\n throw new TwoFactorError('User not found');\r\n }\r\n\r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n\r\n const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);\r\n const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);\r\n\r\n await this.authRepository.updateTwoFactorSecret(decoded.userId, secret);\r\n\r\n return { qrCodeUrl };\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorEnableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n \r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n \r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto;\r\n \r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret) {\r\n throw new TwoFactorError('Please set up two-factor authentication first');\r\n }\r\n \r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.enableTwoFactor(user);\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\nimport { ITwoFactorVerify } from '../../domain/interfaces/ITwoFactorVerify';\r\nimport { ITokenPair } from '../../domain/interfaces/ITokenPair';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { mapper } from '../mappers/utils/mapper';\r\n\r\nexport class TwoFactorVerifyUseCase implements IBaseService {\r\n private isInitialized = false;\r\n\r\n constructor(\r\n private readonly twoFactorService: TwoFactorService,\r\n private readonly authRepository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n this.jwtService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n this.isInitialized = true;\r\n }\r\n\r\n public async execute(dto: ITwoFactorVerify): Promise<{ token: string; refreshToken: string; data?: AdminDTO | UserDTO } | null> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const { userId, token } = dto;\r\n if (!userId || !token) {\r\n throw new TwoFactorError('User ID and token are required.');\r\n }\r\n\r\n const auth: AuthEntity | null = await this.authRepository.findByUserId(userId);\r\n if (!auth || !auth.twoFactorSecret || !auth.twoFactorEnabled) {\r\n throw new TwoFactorError('Invalid request.');\r\n }\r\n\r\n const isValid = this.twoFactorService.verifyToken(token, auth.twoFactorSecret);\r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code.');\r\n }\r\n\r\n const tokenPair: ITokenPair = this.generateTokens(auth);\r\n await this.updateUserStatus(auth);\r\n await this.updateUserRefreshToken(auth, tokenPair.refreshToken);\r\n\r\n if (auth.admin) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapAdminToDTO(auth.admin)\r\n };\r\n }\r\n\r\n if (auth.user) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapUserToDTO(auth.user)\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private mapAdminToDTO(admin: AdminEntity): AdminDTO {\r\n return mapper.map(admin, AdminEntity, AdminDTO);\r\n }\r\n\r\n private mapUserToDTO(user: UserEntity): UserDTO {\r\n return mapper.map(user, UserEntity, UserDTO);\r\n }\r\n\r\n private async updateUserStatus(auth: AuthEntity): Promise<void> {\r\n auth.user.lastLoginAt = new Date();\r\n auth.user.isActive = true;\r\n await this.authRepository.update(auth.id, auth);\r\n }\r\n\r\n private async updateUserRefreshToken(auth: AuthEntity, refreshToken: string): Promise<void> {\r\n auth.refreshToken = refreshToken;\r\n await this.authRepository.update(auth.id, { refreshToken });\r\n }\r\n\r\n private generateTokens(auth: AuthEntity): ITokenPair {\r\n return {\r\n accessToken: this.jwtService.generateAccessToken(auth.user, auth.role),\r\n refreshToken: this.jwtService.generateRefreshToken(auth.user)\r\n };\r\n }\r\n}\r\n","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorDisableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n4\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto; \r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret || !user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is not enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.disableTwoFactor(user);\r\n }\r\n}","import { NextFunction, Request, Response } from \"express\";\r\n\r\nimport { LoginDTO } from \"../../application/dtos/LoginDTO\";\r\nimport { RegisterDTO } from \"../../application/dtos/RegisterDTO\";\r\n\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { IRefreshTokenRequest } from \"../../domain/interfaces/IRefreshTokenRequest\";\r\nimport { ITwoFactorEnable } from \"../../domain/interfaces/ITwoFactorEnable\";\r\nimport { ITwoFactorVerify } from \"../../domain/interfaces/ITwoFactorVerify\";\r\nimport { ForbiddenError } from \"../../utils/Errors\";\r\n\r\nexport class AuthController {\r\n private readonly loginUseCase: LoginUseCase;\r\n private readonly adminLoginUseCase: LoginAdminUseCase;\r\n private readonly logoutUseCase: LogoutUseCase;\r\n private readonly registerUseCase: RegisterUseCase;\r\n private readonly refreshTokenUseCase: RefreshTokenUseCase;\r\n\r\n private twoFactorSetupUseCase: TwoFactorSetupUseCase;\r\n private twoFactorEnableUseCase: TwoFactorEnableUseCase;\r\n private twoFactorVerifyUseCase: TwoFactorVerifyUseCase;\r\n private twoFactorDisableUseCase: TwoFactorDisableUseCase;\r\n\r\n constructor(\r\n loginUseCase: LoginUseCase,\r\n adminLoginUseCase: LoginAdminUseCase,\r\n logoutUseCase: LogoutUseCase,\r\n registerUseCase: RegisterUseCase,\r\n refreshTokenUseCase: RefreshTokenUseCase,\r\n twoFactorSetupUseCase: TwoFactorSetupUseCase,\r\n twoFactorEnableUseCase: TwoFactorEnableUseCase,\r\n twoFactorVerifyUseCase: TwoFactorVerifyUseCase,\r\n twoFactorDisableUseCase: TwoFactorDisableUseCase\r\n ) {\r\n this.loginUseCase = loginUseCase;\r\n this.adminLoginUseCase = adminLoginUseCase;\r\n this.logoutUseCase = logoutUseCase;\r\n this.registerUseCase = registerUseCase;\r\n this.refreshTokenUseCase = refreshTokenUseCase;\r\n this.twoFactorSetupUseCase = twoFactorSetupUseCase;\r\n this.twoFactorEnableUseCase = twoFactorEnableUseCase;\r\n this.twoFactorVerifyUseCase = twoFactorVerifyUseCase;\r\n this.twoFactorDisableUseCase = twoFactorDisableUseCase;\r\n }\r\n\r\n login = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const loginDTO: LoginDTO = req.body;\r\n\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n if (result.enabled) {\r\n return res.status(201).json({\r\n status: \"pending\",\r\n message: \"Enter 2FA code\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n }\r\n\r\n res.status(200).json({\r\n status: \"success\",\r\n message: \"Login successful\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n adminLogin = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n if (!adminPassword) {\r\n throw new ForbiddenError(\"Admin password is required\");\r\n }\r\n const result = await this.adminLoginUseCase.execute(loginDTO, adminPassword);\r\n res.status(201).json(result);\r\n }\r\n catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n logout = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n await this.logoutUseCase.execute(req.body.id);\r\n res.status(200).json({ message: 'Logged out successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n register = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const { email, name, password, role, adminPassword }: RegisterDTO = req.body;\r\n\r\n await this.registerUseCase.execute(email, name, password, role, adminPassword);\r\n res.status(200).json({ status: \"success\" });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n refreshToken = async (req: Request, res: Response) => {\r\n const { refreshToken }: IRefreshTokenRequest = req.body;\r\n\r\n const result = await this.refreshTokenUseCase.execute(refreshToken);\r\n res.json(result);\r\n };\r\n\r\n setup2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n console.log(\" req.headers.authorization\", req.headers.authorization);\r\n\r\n const authHeader = req.headers.authorization;\r\n const token = authHeader?.split(' ')[1]?.replace(/^\"|\"$/g, '') as string;\r\n\r\n const result = await this.twoFactorSetupUseCase.execute(token);\r\n res.status(200).json(result);\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n enable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth?.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorEnableUseCase.execute(userId, dto);\r\n res.status(200).json({ message: 'Two-factor authentication has been enabled successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n verify2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorVerify = req.body;\r\n\r\n const result = await this.twoFactorVerifyUseCase.execute(dto);\r\n res.status(200).json({\r\n message: 'Two-factor authentication successful',\r\n ...result\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n disable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth!.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorDisableUseCase.execute(userId, dto);\r\n res.status(200).json({\r\n status: \"success\",\r\n message: 'Two-factor authentication has been disabled successfully'\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n","import { NextFunction, Request, Response } from 'express';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\n\r\nexport class RequireComplete2FA {\r\n private readonly jwtService: JwtAuthService;\r\n\r\n constructor(jwtService: JwtAuthService) {\r\n this.jwtService = jwtService;\r\n }\r\n\r\n public async execute(req: Request, res: Response, next: NextFunction) {\r\n try {\r\n const token = req.headers.authorization?.split(' ')[1];\r\n\r\n if (!token) {\r\n return res.status(401).json({ message: 'Authentication required' });\r\n }\r\n\r\n const decoded = await this.jwtService.verifyAccessToken(token);\r\n\r\n if (!decoded.twoFactorAuthenticated) {\r\n return res.status(403).json({\r\n message: 'Two-factor authentication required',\r\n code: 'REQUIRE_2FA',\r\n userId: decoded.id\r\n });\r\n }\r\n\r\n req.auth = { ...decoded, twoFactorAuthenticated: true };\r\n next();\r\n } catch (error) {\r\n return res.status(401).json({ message: 'Invalid or expired token' });\r\n }\r\n }\r\n}","import { BaseRepository, IExtendedBaseRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\nimport { Repository } from \"typeorm\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\nexport class AuthRepository\r\n extends BaseRepository<AuthEntity>\r\n implements IExtendedBaseRepository<AuthEntity> {\r\n constructor(repository: Repository<AuthEntity>) {\r\n super(repository);\r\n }\r\n\r\n async findByEmail(email: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.password\")\r\n .where(\"auth.email = :email\", { email });\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async create(entity: Omit<AuthEntity, \"createdAt\">): Promise<AuthEntity> {\r\n return super.create(entity);\r\n }\r\n\r\n async findByUserId(userId: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.twoFactorSecret\")\r\n .where(\"user.id = :userId\", { userId });\r\n\r\n return await query.getOne();;\r\n }\r\n\r\n async findByUseAdminId(userId: string, isAdmin: boolean = false): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .addSelect(\"auth.twoFactorSecret\");\r\n\r\n if (isAdmin) {\r\n query.leftJoinAndSelect(\"auth.admin\", \"admin\")\r\n .where(\"admin.id = :userId\", { userId });\r\n } else {\r\n query.leftJoinAndSelect(\"auth.user\", \"user\")\r\n .where(\"user.id = :userId\", { userId });\r\n }\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async logout(userId: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.refreshToken = \"\";\r\n auth.user.isActive = false;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async updateTwoFactorSecret(userId: string, secret: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.twoFactorSecret = secret;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async enableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = true;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async disableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = false;\r\n auth.twoFactorSecret = null;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async isTwoFactorEnabled(userId: string): Promise<boolean> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return !!auth.twoFactorEnabled;\r\n }\r\n\r\n async getTwoFactorSecret(userId: string): Promise<string | null> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return auth.twoFactorSecret;\r\n }\r\n}\r\n","import * as jwt from \"jsonwebtoken\";\r\nimport { Secret, SignOptions } from \"jsonwebtoken\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { IJwtConfig } from \"../../domain/interfaces/IJwtConfig\";\r\nimport { IAuthService } from \"../../domain/interfaces/IAuthService\";\r\nimport { IDecodedToken } from \"../../domain/interfaces/IDecodedToken\";\r\n\r\nimport {\r\n ForbiddenError,\r\n JwtError,\r\n NotFoundError,\r\n UnauthorizedError,\r\n} from \"../../utils/Errors\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\nimport { log } from \"console\";\r\n\r\nexport class JwtAuthService implements IBaseService, IAuthService {\r\n private jwtConfig: IJwtConfig | undefined;\r\n\r\n constructor(private readonly repository: AuthRepository, config?: IJwtConfig) {\r\n this.loadConfig(config);\r\n }\r\n\r\n private async loadConfig(config?: IJwtConfig) {\r\n const configData = await createConfigInstance();\r\n\r\n this.jwtConfig = {\r\n accessTokenSecret: configData.accessTokenSecret,\r\n refreshTokenSecret: configData.refreshTokenSecret,\r\n accessTokenExpiry: parseInt(configData.accessTokenExpiry, 10),\r\n refreshTokenExpiry: parseInt(configData.refreshTokenExpiry, 10),\r\n ...config,\r\n };\r\n\r\n this.validateConfiguration();\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n await validateRepository(this.repository, repo => repo.getAll());\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.jwtConfig?.accessTokenSecret || !this.jwtConfig?.refreshTokenSecret) {\r\n throw new JwtError(\"JWT secrets required in config\");\r\n }\r\n }\r\n\r\n async validateUser(email: string, password: string): Promise<AuthEntity | null> {\r\n const user = await this.repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const validPassword = await bcrypt.compare(password, user.password);\r\n if (!validPassword) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return user;\r\n }\r\n\r\n private verifyJwtConfig() {\r\n if (!this.jwtConfig) throw new JwtError(\"JWT config not loaded\");\r\n }\r\n\r\n generateAccessToken(user: UserEntity, role : UserRole): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id, email: user.email, role: role },\r\n this.jwtConfig!.accessTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.accessTokenExpiry }\r\n );\r\n }\r\n\r\n generateRefreshToken(user: UserEntity): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id },\r\n this.jwtConfig!.refreshTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.refreshTokenExpiry }\r\n );\r\n }\r\n\r\n async verifyToken(token: string, secret: string): Promise<IDecodedToken> {\r\n try {\r\n console.log(\"Verifying token:\", token);\r\n console.log(\"Using secret:\", secret);\r\n \r\n return jwt.verify(token, secret) as IDecodedToken;\r\n } catch(error) {\r\n console.error(\"Error verifying token:\", error);\r\n throw new UnauthorizedError();\r\n }\r\n }\r\n\r\n async verifyAccessToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.accessTokenSecret);\r\n }\r\n\r\n async verifyRefreshToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.refreshTokenSecret);\r\n }\r\n}\r\n","import * as speakeasy from 'speakeasy';\r\nimport * as QRCode from 'qrcode';\r\nimport { IBaseService } from 'cca-core';\r\n\r\nimport { IConfig } from '../../domain/interfaces/configTypes';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorService implements IBaseService {\r\n private readonly config: IConfig;\r\n private initialized: boolean = false;\r\n private readonly twoFactorConfig: {\r\n tokenWindow: number;\r\n secretLength: number;\r\n qrCodeOptions: QRCode.QRCodeToDataURLOptions;\r\n };\r\n\r\n constructor(config: IConfig) {\r\n this.config = config;\r\n \r\n this.twoFactorConfig = {\r\n tokenWindow: parseInt(config.tokenWindow) ?? 1,\r\n secretLength: parseInt(config.secretLength) ?? 20,\r\n qrCodeOptions: {\r\n errorCorrectionLevel: 'M',\r\n margin: 4,\r\n scale: 4,\r\n color: {\r\n dark: '#000000',\r\n light: '#ffffff'\r\n }\r\n }\r\n };\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n this.validateConfiguration();\r\n this.initialized = true;\r\n } catch (error) {\r\n console.error('TwoFactorService initialization failed:', error);\r\n throw new TwoFactorError('Failed to initialize TwoFactorService');\r\n }\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.config.app_name?.trim()) {\r\n throw new TwoFactorError('Application name (appName) is required in configuration');\r\n }\r\n\r\n if (this.twoFactorConfig.secretLength < 16) {\r\n throw new TwoFactorError('Secret length must be at least 16 characters');\r\n }\r\n\r\n if (this.twoFactorConfig.tokenWindow < 0 || this.twoFactorConfig.tokenWindow > 5) {\r\n throw new TwoFactorError('Token verification window must be between 0 and 5');\r\n }\r\n }\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new TwoFactorError('TwoFactorService must be initialized before use');\r\n }\r\n }\r\n\r\n public generateSecret(email: string): { secret: string; otpAuthUrl: string } {\r\n this.ensureInitialized();\r\n\r\n try {\r\n const secretObj = speakeasy.generateSecret({\r\n length: this.twoFactorConfig.secretLength,\r\n name: `${this.config.app_name}:${email}`,\r\n issuer: this.config.app_name\r\n });\r\n \r\n return {\r\n secret: secretObj.base32,\r\n otpAuthUrl: secretObj.otpauth_url || ''\r\n };\r\n } catch (error) {\r\n console.error('Error generating 2FA secret:', error);\r\n throw new TwoFactorError('Failed to generate 2FA secret');\r\n }\r\n }\r\n\r\n public async generateQRCode(otpAuthUrl: string): Promise<string> {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return await QRCode.toDataURL(otpAuthUrl, this.twoFactorConfig.qrCodeOptions);\r\n } catch (error) {\r\n console.error('QR code generation failed:', error);\r\n throw new TwoFactorError('Failed to generate QR code');\r\n }\r\n }\r\n\r\n public verifyToken(token: string, secret: string): boolean {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return speakeasy.totp.verify({\r\n secret,\r\n encoding: 'base32',\r\n token,\r\n window: this.twoFactorConfig.tokenWindow\r\n });\r\n } catch (error) {\r\n console.error('Token verification failed:', error);\r\n throw new TwoFactorError('Failed to verify 2FA token');\r\n }\r\n }\r\n}"],"mappings":"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","names":["import_cca_core","import_cca_entities","bcrypt","import_cca_core","import_cca_core","import_cca_core","bcrypt","import_cca_entities","import_core","import_classes","import_cca_entities","import_classes","mapper","import_cca_core","import_jwt_decode","import_cca_core","import_cca_core","import_cca_entities","import_cca_core","import_cca_core","bcrypt","import_cca_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/application/config/ConfigManager.ts","../src/utils/Errors.ts","../src/application/service/utils/configInstance.ts","../src/infrastructure/container/createAuthContainer.ts","../src/application/useCase/LoginUseCase.ts","../src/application/validators/authValidation.ts","../src/application/useCase/LoginAdminUseCase.ts","../src/application/useCase/LogoutUseCase.ts","../src/application/useCase/RegisterUseCase.ts","../src/application/mappers/utils/mapper.ts","../src/application/mappers/createUserMappings.ts","../src/application/dtos/RegisterDTO.ts","../src/application/dtos/UserDTO.ts","../src/application/dtos/AdminDTO.ts","../src/application/useCase/RefreshTokenUseCase.ts","../src/application/useCase/TwoFactorSetupUseCase.ts","../src/application/useCase/TwoFactorEnableUseCase.ts","../src/application/useCase/TwoFactorVerifyUseCase.ts","../src/application/useCase/TwoFactorDisableUseCase.ts","../src/presentation/controller/AuthController.ts","../src/presentation/middleware/RequireComplete2FA.ts","../src/infrastructure/repository/AuthRepository.ts","../src/infrastructure/services/JwtAuthService.ts","../src/infrastructure/services/TwoFactorService.ts"],"sourcesContent":["import { authConfig } from \"./application/service/utils/configInstance\";\r\nimport { ConfigSource, IConfig } from \"./domain/interfaces/configTypes\";\r\nimport { createAuthContainer } from \"./infrastructure/container/createAuthContainer\";\r\nimport { AuthController } from \"./presentation/controller/AuthController\";\r\n\r\nexport { createAuthContainer, AuthController, authConfig, ConfigSource, IConfig };\r\n","import { EventEmitter } from \"events\";\r\nimport { IConfig, ConfigSource } from \"../../domain/interfaces/configTypes\";\r\nimport { ConfigNotFoundException } from \"../../utils/Errors\";\r\n\r\nexport class ConfigManager extends EventEmitter {\r\n private config?: IConfig;\r\n private configSource?: ConfigSource;\r\n\r\n setConfigSource(source: ConfigSource): void {\r\n this.configSource = source;\r\n }\r\n\r\n setConfig(cfg: IConfig): void {\r\n this.config = { ...cfg };\r\n this.emit(\"configAvailable\", this.config);\r\n }\r\n\r\n getConfig(): IConfig | undefined {\r\n return this.config;\r\n }\r\n\r\n async loadConfig(): Promise<IConfig> {\r\n if (!this.configSource) {\r\n throw new ConfigNotFoundException(\"Config source not set\");\r\n }\r\n try {\r\n const config = await this.configSource();\r\n this.setConfig(config);\r\n return config;\r\n } catch (error) {\r\n throw new ConfigNotFoundException(\"Error loading configuration\");\r\n }\r\n }\r\n}\r\n\r\nexport const configManager = new ConfigManager();\r\n","export class AppError extends Error {\r\n constructor(\r\n public message: string,\r\n public statusCode: number = 500,\r\n public name: string = \"AppError\"\r\n ) {\r\n super(message);\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n Error.captureStackTrace(this);\r\n }\r\n}\r\n\r\nexport class ValidationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"ValidationError\";\r\n }\r\n}\r\n\r\nexport class ConfigNotFoundException extends AppError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"ConfigNotFoundException\";\r\n }\r\n}\r\n\r\nexport class NotFoundError extends AppError {\r\n constructor(message: string) {\r\n super(message, 404, \"UserNotFoundError\");\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends AppError {\r\n constructor(message: string = \"Forbidden access\") {\r\n super(message, 403);\r\n this.name = \"ForbiddenError\";\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends AppError {\r\n constructor(message: string = \"Unauthorized access\") {\r\n super(message, 401);\r\n this.name = \"UnauthorizedError\";\r\n }\r\n}\r\n\r\nexport class JwtError extends AppError {\r\n constructor(message: string) {\r\n super(message, 401);\r\n this.name = \"JwtError\";\r\n }\r\n}\r\n\r\nexport class RegistrationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"RegistrationError\";\r\n }\r\n}\r\n\r\nexport class TwoFactorError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"TwoFactorERROR\";\r\n }\r\n}","import { configManager } from \"../../config/ConfigManager\";\r\nimport { IConfig, ConfigSource } from \"../../../domain/interfaces/configTypes\";\r\n\r\nexport const authConfig = (configSource: ConfigSource): void => {\r\n configManager.setConfigSource(configSource);\r\n};\r\n\r\nexport const createConfigInstance = async (): Promise<IConfig> => {\r\n return configManager.getConfig() ?? (await configManager.loadConfig());\r\n};\r\n","import { BaseContainer, BaseDatabase } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { AuthController } from \"../../presentation/controller/AuthController\";\r\nimport { RequireComplete2FA } from \"../../presentation/middleware/RequireComplete2FA\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { JwtAuthService } from \"../services/JwtAuthService\";\r\nimport { TwoFactorService } from \"../services/TwoFactorService\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\n\r\nasync function createAuthContainer(database: BaseDatabase) {\r\n const container = new BaseContainer({ database });\r\n\r\n const authRepository = new AuthRepository(\r\n database.getRepository(AuthEntity)\r\n );\r\n container.registerRepository<AuthEntity>(\"AuthRepository\", authRepository);\r\n\r\n const jwtAuthService = new JwtAuthService(authRepository);\r\n container.registerService(\"JwtAuthService\", jwtAuthService);\r\n\r\n const configData = await createConfigInstance();\r\n\r\n const twoFactorService = new TwoFactorService(configData);\r\n container.registerService(\"TwoFactorService\", twoFactorService);\r\n\r\n const requireComplete2FA = new RequireComplete2FA(jwtAuthService);\r\n\r\n const loginUseCase = new LoginUseCase(authRepository, jwtAuthService);\r\n const loginAdminUseCase = new LoginAdminUseCase(\r\n authRepository\r\n );\r\n const logoutUseCase = new LogoutUseCase(authRepository);\r\n const registerUseCase = new RegisterUseCase(authRepository);\r\n const refreshTokenUseCase = new RefreshTokenUseCase(\r\n authRepository,\r\n jwtAuthService\r\n );\r\n\r\n const twoFactorSetupUseCase = new TwoFactorSetupUseCase(twoFactorService, authRepository);\r\n const twoFactorEnableUseCase = new TwoFactorEnableUseCase(twoFactorService, authRepository);\r\n const twoFactorVerifyUseCase = new TwoFactorVerifyUseCase(\r\n twoFactorService,\r\n authRepository,\r\n jwtAuthService\r\n );\r\n const twoFactorDisableUseCase = new TwoFactorDisableUseCase(twoFactorService, authRepository);\r\n\r\n container.registerService(\"LoginUseCase\", loginUseCase);\r\n container.registerService(\"LoginAdminUseCase\", loginAdminUseCase);\r\n container.registerService(\"LogoutUseCase\", logoutUseCase);\r\n container.registerService(\"RegisterUseCase\", registerUseCase);\r\n container.registerService(\"RefreshTokenUseCase\", refreshTokenUseCase);\r\n container.registerService(\"TwoFactorSetupUseCase\", twoFactorSetupUseCase);\r\n container.registerService(\"TwoFactorEnableUseCase\", twoFactorEnableUseCase);\r\n container.registerService(\"TwoFactorVerifyUseCase\", twoFactorVerifyUseCase);\r\n container.registerService(\"TwoFactorDisableUseCase\", twoFactorDisableUseCase);\r\n\r\n const authController = new AuthController(\r\n loginUseCase,\r\n loginAdminUseCase,\r\n logoutUseCase,\r\n registerUseCase,\r\n refreshTokenUseCase,\r\n twoFactorSetupUseCase,\r\n twoFactorEnableUseCase,\r\n twoFactorVerifyUseCase,\r\n twoFactorDisableUseCase\r\n );\r\n\r\n return { container, authController, requireComplete2FA };\r\n}\r\n\r\nexport { createAuthContainer };","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { jwtDecode } from \"jwt-decode\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateLoginDTO } from \"../validators/authValidation\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { IJwtPayload } from \"../../domain/interfaces/IJwtPayload\";\r\n\r\n\r\nexport class LoginUseCase implements IBaseService {\r\n\r\n constructor(\r\n private readonly repository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO): Promise<{ id: string, accessToken: string, expiresAt: number , enabled?: boolean }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n \r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n const expiresAt = jwtDecode<IJwtPayload>(accessToken).exp;\r\n\r\n if (auth.twoFactorEnabled) {\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt, enabled: auth.twoFactorEnabled };\r\n }\r\n\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt };\r\n }\r\n}","import * as yup from \"yup\";\r\nimport { AuthEntity, UserRole } from \"cca-entities\";\r\nimport bcrypt from \"bcrypt\";\r\n\r\nimport {\r\n ForbiddenError,\r\n NotFoundError,\r\n ValidationError,\r\n} from \"../../utils/Errors\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\n\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { createConfigInstance } from \"../service/utils/configInstance\";\r\n\r\nconst schemas = {\r\n id: yup.string().uuid(\"Invalid user ID format\"),\r\n email: yup\r\n .string()\r\n .email(\"Invalid email format\")\r\n .max(255, \"Email cannot exceed 255 characters\"),\r\n name: yup\r\n .string()\r\n .required(\"Name is required\")\r\n .min(2, \"Name must be at least 2 characters long\")\r\n .max(50, \"Name cannot exceed 50 characters\")\r\n .matches(/^[a-zA-Z\\s]+$/, \"Name must only contain letters and spaces\"),\r\n password: yup\r\n .string()\r\n .required(\"Password required\")\r\n .min(8, \"Password too short\")\r\n .max(100, \"Password too long\")\r\n .matches(\r\n /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]/,\r\n \"Password must contain uppercase, lowercase, number and special character\"\r\n ),\r\n role: yup\r\n .string()\r\n .oneOf(Object.values(UserRole), \"Invalid role specified\"),\r\n};\r\n\r\nexport const validateEmail = async (\r\n email: string,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n const user = await repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\r\n \"The email address or password is incorrect. Please retry\"\r\n );\r\n }\r\n return user;\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid email format\");\r\n }\r\n};\r\n\r\nexport const validatePassword = async (password?: string): Promise<void> => {\r\n if (password) {\r\n try {\r\n await schemas.password.validate(password);\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid password format\");\r\n }\r\n }\r\n};\r\n\r\nexport const validateEmailUniqueness = async (\r\n repository: AuthRepository,\r\n email: string,\r\n excludeUserId?: string\r\n): Promise<void> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n\r\n const existingUser = await repository.findByEmail(email);\r\n\r\n if (!existingUser) return;\r\n if (existingUser.id === excludeUserId) return;\r\n\r\n throw new ValidationError(`Email ${email} is already in use.`);\r\n } catch (error: any) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"user email validation failed\");\r\n }\r\n};\r\n\r\nexport const validateRegisterDTO = async (\r\n auth: RegisterDTO,\r\n repository: AuthRepository\r\n): Promise<void> => {\r\n const { name, email, role, password } = auth;\r\n\r\n await Promise.all([\r\n schemas.name.validate(name),\r\n schemas.role.validate(role),\r\n validateEmailUniqueness(repository, email),\r\n validatePassword(password),\r\n ]);\r\n};\r\n\r\nexport const validateLoginDTO = async (\r\n data: LoginDTO,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n const { email, role, password } = data;\r\n\r\n if (role) {\r\n await schemas.role.validate(role);\r\n }\r\n\r\n await schemas.password.validate(password);\r\n\r\n const auth = await validateEmail(email, repository);\r\n if (!auth || !auth.password) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const isMatch = await bcrypt.compare(password, auth.password);\r\n if (!isMatch) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return auth;\r\n};\r\n\r\nexport const validateAdminSecret = async (\r\n secretPassword?: string\r\n): Promise<void> => {\r\n if (!secretPassword) {\r\n throw new ValidationError(\"Admin password is required\");\r\n }\r\n\r\n try {\r\n const config = await createConfigInstance();\r\n\r\n if (!config.adminSecretPassword) {\r\n throw new ValidationError(\"ADMIN_SECRET_PASSWORD not found in config\");\r\n }\r\n\r\n if (parseInt(secretPassword) !== parseInt(config.adminSecretPassword)) {\r\n throw new ValidationError(\"Invalid admin password\");\r\n }\r\n } catch (error) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"Error validating admin password\");\r\n }\r\n};\r\n","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateAdminSecret, validateLoginDTO } from \"../validators/authValidation\";\r\n\r\nexport class LoginAdminUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n\r\n constructor(\r\n repository: AuthRepository\r\n ) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO, adminPassword: string): Promise<string> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\n\r\nexport class LogoutUseCase implements IBaseService {\r\n private readonly repository: AuthRepository\r\n\r\n constructor(repository: AuthRepository) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(authId: string): Promise<void> {\r\n try {\r\n await this.repository.logout(authId);\r\n } catch (error) {\r\n new NotFoundError(\"Auth not found\");\r\n }\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { AdminEntity, AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private readonly SALT_ROUNDS = 10;\r\n\r\n constructor(private readonly repository: AuthRepository) {}\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo) => repo.getAll());\r\n }\r\n\r\n public async execute(\r\n email: string,\r\n name: string,\r\n password: string,\r\n role: UserRole = UserRole.GUEST,\r\n adminPassword?: string\r\n ): Promise<AuthEntity | undefined> {\r\n try {\r\n const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });\r\n\r\n const isAdminUser = await this._validateAdminRegistration(\r\n normalizedDTO.role,\r\n normalizedDTO.adminPassword\r\n );\r\n\r\n await validateRegisterDTO(normalizedDTO, this.repository);\r\n\r\n const hashedPassword = await this._hashPassword(normalizedDTO.password);\r\n const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);\r\n\r\n return this.repository.create(authEntity);\r\n } catch (error) {\r\n throw new RegistrationError(\r\n `Registration failed: ${error instanceof Error ? error.message : \"Unknown error\"}`\r\n );\r\n }\r\n }\r\n\r\n private _normalizeInput(dto: RegisterDTO): RegisterDTO {\r\n return {\r\n name: dto.name.trim(),\r\n email: dto.email.trim().toLowerCase(),\r\n password: dto.password.trim(),\r\n role: dto.role,\r\n adminPassword: dto.adminPassword?.trim()\r\n };\r\n }\r\n\r\n private async _hashPassword(password: string): Promise<string> {\r\n return bcrypt.hash(password, this.SALT_ROUNDS);\r\n }\r\n\r\n private async _validateAdminRegistration(\r\n role: UserRole,\r\n adminPassword?: string\r\n ): Promise<boolean> {\r\n if (role !== UserRole.ADMIN) return false;\r\n\r\n if (!adminPassword) {\r\n throw new UnauthorizedError(\"Admin password is required for admin registration\");\r\n }\r\n\r\n await validateAdminSecret(adminPassword);\r\n return true;\r\n }\r\n\r\n private _buildMappedAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): AuthEntity {\r\n const authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userOrAdminEntity = isAdmin\r\n ? mapper.map(dto, RegisterDTO, AdminEntity)\r\n : mapper.map(dto, RegisterDTO, UserEntity);\r\n\r\n userOrAdminEntity.updatedAt = undefined as unknown as Date;\r\n\r\n if (isAdmin) {\r\n authEntity.admin = userOrAdminEntity;\r\n } else {\r\n authEntity.user = userOrAdminEntity;\r\n }\r\n\r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n\r\n return authEntity;\r\n }\r\n}\r\n","import { createMapper } from '@automapper/core';\r\nimport { classes } from '@automapper/classes';\r\n\r\nimport { createUserMappings } from '../createUserMappings';\r\n\r\nexport const mapper = createMapper({\r\n strategyInitializer: classes(),\r\n});\r\n\r\ncreateUserMappings(mapper);\r\n","import { Mapper, createMap, forMember, mapFrom } from '@automapper/core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { RegisterDTO } from '../dtos/RegisterDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\n\r\nexport function createUserMappings(mapper: Mapper): void {\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AuthEntity,\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.password, mapFrom(src => src.password)),\r\n forMember(dest => dest.role, mapFrom(src => src.role)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n UserEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AdminEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n UserEntity,\r\n UserDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.profileImageUrl, mapFrom(src => getProfileImageUrl(src))));\r\n\r\n\r\n createMap(\r\n mapper,\r\n AdminEntity,\r\n AdminDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n const getProfileImageUrl = (src: UserEntity): string | undefined => {\r\n const image = src.images?.[0];\r\n if (!image) return undefined;\r\n return image.mdUrl ?? image.smUrl ?? image.lgUrl ?? image.thumbUrl ?? image.originalUrl ?? image.xlUrl;\r\n };\r\n}","import { UserRole } from \"cca-entities\";\r\n\r\nexport class RegisterDTO {\r\n email!: string;\r\n name!: string;\r\n password!: string;\r\n role!: UserRole;\r\n adminPassword?: string;\r\n}\r\n","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class UserDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n @AutoMap()\r\n profileImageUrl?: string;\r\n}","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class AdminDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n adminPassword!: string;\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { ITokenPair } from \"../../domain/interfaces/ITokenPair\";\r\n\r\nexport class RefreshTokenUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n private readonly service: JwtAuthService;\r\n\r\n constructor(repository: AuthRepository, service: JwtAuthService) {\r\n this.repository = repository;\r\n this.service = service;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n public async execute(refreshToken: string): Promise<ITokenPair | null> {\r\n try {\r\n const decoded = await this.service.verifyRefreshToken(refreshToken);\r\n\r\n if (!decoded.userId) {\r\n return null;\r\n }\r\n\r\n let authEntity = await this.repository.findByUseAdminId(decoded.userId);\r\n\r\n if (!authEntity) {\r\n authEntity = await this.repository.findByUseAdminId(decoded.userId, true);\r\n }\r\n\r\n if (!authEntity) {\r\n return null;\r\n }\r\n\r\n const user = authEntity.role === \"admin\" ? authEntity.admin : authEntity.user;\r\n\r\n const accessToken = this.service.generateAccessToken(user, authEntity.role);\r\n const newRefreshToken = this.service.generateRefreshToken(user);\r\n\r\n await this.repository.update(authEntity.id, {\r\n refreshToken: newRefreshToken\r\n });\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken\r\n };\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n}","import { IBaseService } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorSetupResponse } from '../../domain/interfaces/ITwoFactorSetupResponse';\r\n\r\nimport { ForbiddenError, TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorSetupUseCase implements IBaseService {\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n await Promise.all([\r\n this.twoFactorService.initialize()\r\n ]);\r\n\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string): Promise<ITwoFactorSetupResponse> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const user = await this.authRepository.findByUserId(userId);\r\n\r\n if (!user) {\r\n throw new ForbiddenError('User not found');\r\n }\r\n\r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n\r\n const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);\r\n const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);\r\n\r\n await this.authRepository.updateTwoFactorSecret(userId, secret);\r\n\r\n return { qrCodeUrl };\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorEnableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n \r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n \r\n this.isInitialized = true;\r\n }\r\n\r\n async execute( dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token, userId } = dto;\r\n \r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret) {\r\n throw new TwoFactorError('Please set up two-factor authentication first');\r\n }\r\n \r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.enableTwoFactor(user);\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\nimport { ITwoFactorVerify } from '../../domain/interfaces/ITwoFactorVerify';\r\nimport { ITokenPair } from '../../domain/interfaces/ITokenPair';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { mapper } from '../mappers/utils/mapper';\r\n\r\nexport class TwoFactorVerifyUseCase implements IBaseService {\r\n private isInitialized = false;\r\n\r\n constructor(\r\n private readonly twoFactorService: TwoFactorService,\r\n private readonly authRepository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n this.jwtService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n this.isInitialized = true;\r\n }\r\n\r\n public async execute(dto: ITwoFactorVerify): Promise<{ token: string; refreshToken: string; data?: AdminDTO | UserDTO } | null> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const { userId, token } = dto;\r\n if (!userId || !token) {\r\n throw new TwoFactorError('User ID and token are required.');\r\n }\r\n\r\n const auth: AuthEntity | null = await this.authRepository.findByUserId(userId);\r\n if (!auth || !auth.twoFactorSecret || !auth.twoFactorEnabled) {\r\n throw new TwoFactorError('Invalid request.');\r\n }\r\n\r\n const isValid = this.twoFactorService.verifyToken(token, auth.twoFactorSecret);\r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code.');\r\n }\r\n\r\n const tokenPair: ITokenPair = this.generateTokens(auth);\r\n await this.updateUserStatus(auth);\r\n await this.updateUserRefreshToken(auth, tokenPair.refreshToken);\r\n\r\n if (auth.admin) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapAdminToDTO(auth.admin)\r\n };\r\n }\r\n\r\n if (auth.user) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapUserToDTO(auth.user)\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private mapAdminToDTO(admin: AdminEntity): AdminDTO {\r\n return mapper.map(admin, AdminEntity, AdminDTO);\r\n }\r\n\r\n private mapUserToDTO(user: UserEntity): UserDTO {\r\n return mapper.map(user, UserEntity, UserDTO);\r\n }\r\n\r\n private async updateUserStatus(auth: AuthEntity): Promise<void> {\r\n auth.user.lastLoginAt = new Date();\r\n auth.user.isActive = true;\r\n await this.authRepository.update(auth.id, auth);\r\n }\r\n\r\n private async updateUserRefreshToken(auth: AuthEntity, refreshToken: string): Promise<void> {\r\n auth.refreshToken = refreshToken;\r\n await this.authRepository.update(auth.id, { refreshToken });\r\n }\r\n\r\n private generateTokens(auth: AuthEntity): ITokenPair {\r\n return {\r\n accessToken: this.jwtService.generateAccessToken(auth.user, auth.role),\r\n refreshToken: this.jwtService.generateRefreshToken(auth.user)\r\n };\r\n }\r\n}\r\n","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorDisableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n4\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto; \r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret || !user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is not enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.disableTwoFactor(user);\r\n }\r\n}","import { NextFunction, Request, Response } from \"express\";\r\n\r\nimport { LoginDTO } from \"../../application/dtos/LoginDTO\";\r\nimport { RegisterDTO } from \"../../application/dtos/RegisterDTO\";\r\n\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { IRefreshTokenRequest } from \"../../domain/interfaces/IRefreshTokenRequest\";\r\nimport { ITwoFactorEnable } from \"../../domain/interfaces/ITwoFactorEnable\";\r\nimport { ITwoFactorVerify } from \"../../domain/interfaces/ITwoFactorVerify\";\r\nimport { ForbiddenError } from \"../../utils/Errors\";\r\n\r\nexport class AuthController {\r\n private readonly loginUseCase: LoginUseCase;\r\n private readonly adminLoginUseCase: LoginAdminUseCase;\r\n private readonly logoutUseCase: LogoutUseCase;\r\n private readonly registerUseCase: RegisterUseCase;\r\n private readonly refreshTokenUseCase: RefreshTokenUseCase;\r\n\r\n private twoFactorSetupUseCase: TwoFactorSetupUseCase;\r\n private twoFactorEnableUseCase: TwoFactorEnableUseCase;\r\n private twoFactorVerifyUseCase: TwoFactorVerifyUseCase;\r\n private twoFactorDisableUseCase: TwoFactorDisableUseCase;\r\n\r\n constructor(\r\n loginUseCase: LoginUseCase,\r\n adminLoginUseCase: LoginAdminUseCase,\r\n logoutUseCase: LogoutUseCase,\r\n registerUseCase: RegisterUseCase,\r\n refreshTokenUseCase: RefreshTokenUseCase,\r\n twoFactorSetupUseCase: TwoFactorSetupUseCase,\r\n twoFactorEnableUseCase: TwoFactorEnableUseCase,\r\n twoFactorVerifyUseCase: TwoFactorVerifyUseCase,\r\n twoFactorDisableUseCase: TwoFactorDisableUseCase\r\n ) {\r\n this.loginUseCase = loginUseCase;\r\n this.adminLoginUseCase = adminLoginUseCase;\r\n this.logoutUseCase = logoutUseCase;\r\n this.registerUseCase = registerUseCase;\r\n this.refreshTokenUseCase = refreshTokenUseCase;\r\n this.twoFactorSetupUseCase = twoFactorSetupUseCase;\r\n this.twoFactorEnableUseCase = twoFactorEnableUseCase;\r\n this.twoFactorVerifyUseCase = twoFactorVerifyUseCase;\r\n this.twoFactorDisableUseCase = twoFactorDisableUseCase;\r\n }\r\n\r\n login = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const loginDTO: LoginDTO = req.body;\r\n\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n if (result.enabled) {\r\n return res.status(201).json({\r\n status: \"pending\",\r\n message: \"Enter 2FA code\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n }\r\n\r\n res.status(200).json({\r\n status: \"success\",\r\n message: \"Login successful\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n adminLogin = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n if (!adminPassword) {\r\n throw new ForbiddenError(\"Admin password is required\");\r\n }\r\n const result = await this.adminLoginUseCase.execute(loginDTO, adminPassword);\r\n res.status(201).json(result);\r\n }\r\n catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n logout = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n await this.logoutUseCase.execute(req.body.id);\r\n res.status(200).json({ message: 'Logged out successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n register = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const { email, name, password, role, adminPassword }: RegisterDTO = req.body;\r\n\r\n await this.registerUseCase.execute(email, name, password, role, adminPassword);\r\n res.status(200).json({ status: \"success\" });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n refreshToken = async (req: Request, res: Response) => {\r\n const { refreshToken }: IRefreshTokenRequest = req.body;\r\n\r\n const result = await this.refreshTokenUseCase.execute(refreshToken);\r\n res.json(result);\r\n };\r\n\r\n setup2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (!req.auth || !req.auth.id) {\r\n throw new ForbiddenError(\"User authentication required\");\r\n }\r\n const result = await this.twoFactorSetupUseCase.execute(req.auth.id);\r\n res.status(200).json(result);\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n enable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorEnable = req.body;\r\n dto.userId = req.auth?.id;\r\n\r\n await this.twoFactorEnableUseCase.execute(dto);\r\n res.status(200).json({ message: 'Two-factor authentication has been enabled successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n verify2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorVerify = req.body;\r\n\r\n const result = await this.twoFactorVerifyUseCase.execute(dto);\r\n res.status(200).json({\r\n message: 'Two-factor authentication successful',\r\n ...result\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n disable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth!.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorDisableUseCase.execute(userId, dto);\r\n res.status(200).json({\r\n status: \"success\",\r\n message: 'Two-factor authentication has been disabled successfully'\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n","import { NextFunction, Request, Response } from 'express';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\n\r\nexport class RequireComplete2FA {\r\n private readonly jwtService: JwtAuthService;\r\n\r\n constructor(jwtService: JwtAuthService) {\r\n this.jwtService = jwtService;\r\n }\r\n\r\n public async execute(req: Request, res: Response, next: NextFunction) {\r\n try {\r\n const token = req.headers.authorization?.split(' ')[1];\r\n\r\n if (!token) {\r\n return res.status(401).json({ message: 'Authentication required' });\r\n }\r\n\r\n const decoded = await this.jwtService.verifyAccessToken(token);\r\n\r\n if (!decoded.twoFactorAuthenticated) {\r\n return res.status(403).json({\r\n message: 'Two-factor authentication required',\r\n code: 'REQUIRE_2FA',\r\n userId: decoded.id\r\n });\r\n }\r\n\r\n req.auth = { ...decoded, twoFactorAuthenticated: true };\r\n next();\r\n } catch (error) {\r\n return res.status(401).json({ message: 'Invalid or expired token' });\r\n }\r\n }\r\n}","import { BaseRepository, IExtendedBaseRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\nimport { Repository } from \"typeorm\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\nexport class AuthRepository\r\n extends BaseRepository<AuthEntity>\r\n implements IExtendedBaseRepository<AuthEntity> {\r\n constructor(repository: Repository<AuthEntity>) {\r\n super(repository);\r\n }\r\n\r\n async findByEmail(email: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.password\")\r\n .where(\"auth.email = :email\", { email });\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async create(entity: Omit<AuthEntity, \"createdAt\">): Promise<AuthEntity> {\r\n return super.create(entity);\r\n }\r\n\r\n async findByUserId(userId: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.twoFactorSecret\")\r\n .where(\"user.id = :userId\", { userId });\r\n\r\n return await query.getOne();;\r\n }\r\n\r\n async findByUseAdminId(userId: string, isAdmin: boolean = false): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .addSelect(\"auth.twoFactorSecret\");\r\n\r\n if (isAdmin) {\r\n query.leftJoinAndSelect(\"auth.admin\", \"admin\")\r\n .where(\"admin.id = :userId\", { userId });\r\n } else {\r\n query.leftJoinAndSelect(\"auth.user\", \"user\")\r\n .where(\"user.id = :userId\", { userId });\r\n }\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async logout(userId: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.refreshToken = \"\";\r\n auth.user.isActive = false;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async updateTwoFactorSecret(userId: string, secret: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.twoFactorSecret = secret;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async enableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = true;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async disableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = false;\r\n auth.twoFactorSecret = null;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async isTwoFactorEnabled(userId: string): Promise<boolean> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return !!auth.twoFactorEnabled;\r\n }\r\n\r\n async getTwoFactorSecret(userId: string): Promise<string | null> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return auth.twoFactorSecret;\r\n }\r\n}\r\n","import * as jwt from \"jsonwebtoken\";\r\nimport { Secret, SignOptions } from \"jsonwebtoken\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { IJwtConfig } from \"../../domain/interfaces/IJwtConfig\";\r\nimport { IAuthService } from \"../../domain/interfaces/IAuthService\";\r\nimport { IDecodedToken } from \"../../domain/interfaces/IDecodedToken\";\r\n\r\nimport {\r\n ForbiddenError,\r\n JwtError,\r\n NotFoundError,\r\n UnauthorizedError,\r\n} from \"../../utils/Errors\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\nimport { log } from \"console\";\r\n\r\nexport class JwtAuthService implements IBaseService, IAuthService {\r\n private jwtConfig: IJwtConfig | undefined;\r\n\r\n constructor(private readonly repository: AuthRepository, config?: IJwtConfig) {\r\n this.loadConfig(config);\r\n }\r\n\r\n private async loadConfig(config?: IJwtConfig) {\r\n const configData = await createConfigInstance();\r\n\r\n this.jwtConfig = {\r\n accessTokenSecret: configData.accessTokenSecret,\r\n refreshTokenSecret: configData.refreshTokenSecret,\r\n accessTokenExpiry: parseInt(configData.accessTokenExpiry, 10),\r\n refreshTokenExpiry: parseInt(configData.refreshTokenExpiry, 10),\r\n ...config,\r\n };\r\n\r\n this.validateConfiguration();\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n await validateRepository(this.repository, repo => repo.getAll());\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.jwtConfig?.accessTokenSecret || !this.jwtConfig?.refreshTokenSecret) {\r\n throw new JwtError(\"JWT secrets required in config\");\r\n }\r\n }\r\n\r\n async validateUser(email: string, password: string): Promise<AuthEntity | null> {\r\n const user = await this.repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const validPassword = await bcrypt.compare(password, user.password);\r\n if (!validPassword) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return user;\r\n }\r\n\r\n private verifyJwtConfig() {\r\n if (!this.jwtConfig) throw new JwtError(\"JWT config not loaded\");\r\n }\r\n\r\n generateAccessToken(user: UserEntity, role : UserRole): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id, email: user.email, role: role },\r\n this.jwtConfig!.accessTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.accessTokenExpiry }\r\n );\r\n }\r\n\r\n generateRefreshToken(user: UserEntity): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id },\r\n this.jwtConfig!.refreshTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.refreshTokenExpiry }\r\n );\r\n }\r\n\r\n async verifyToken(token: string, secret: string): Promise<IDecodedToken> {\r\n try {\r\n console.log(\"Verifying token:\", token);\r\n console.log(\"Using secret:\", secret);\r\n \r\n return jwt.verify(token, secret) as IDecodedToken;\r\n } catch(error) {\r\n console.error(\"Error verifying token:\", error);\r\n throw new UnauthorizedError();\r\n }\r\n }\r\n\r\n async verifyAccessToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.accessTokenSecret);\r\n }\r\n\r\n async verifyRefreshToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.refreshTokenSecret);\r\n }\r\n}\r\n","import * as speakeasy from 'speakeasy';\r\nimport * as QRCode from 'qrcode';\r\nimport { IBaseService } from 'cca-core';\r\n\r\nimport { IConfig } from '../../domain/interfaces/configTypes';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorService implements IBaseService {\r\n private readonly config: IConfig;\r\n private initialized: boolean = false;\r\n private readonly twoFactorConfig: {\r\n tokenWindow: number;\r\n secretLength: number;\r\n qrCodeOptions: QRCode.QRCodeToDataURLOptions;\r\n };\r\n\r\n constructor(config: IConfig) {\r\n this.config = config;\r\n \r\n this.twoFactorConfig = {\r\n tokenWindow: parseInt(config.tokenWindow) ?? 1,\r\n secretLength: parseInt(config.secretLength) ?? 20,\r\n qrCodeOptions: {\r\n errorCorrectionLevel: 'M',\r\n margin: 4,\r\n scale: 4,\r\n color: {\r\n dark: '#000000',\r\n light: '#ffffff'\r\n }\r\n }\r\n };\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n this.validateConfiguration();\r\n this.initialized = true;\r\n } catch (error) {\r\n console.error('TwoFactorService initialization failed:', error);\r\n throw new TwoFactorError('Failed to initialize TwoFactorService');\r\n }\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.config.app_name?.trim()) {\r\n throw new TwoFactorError('Application name (appName) is required in configuration');\r\n }\r\n\r\n if (this.twoFactorConfig.secretLength < 16) {\r\n throw new TwoFactorError('Secret length must be at least 16 characters');\r\n }\r\n\r\n if (this.twoFactorConfig.tokenWindow < 0 || this.twoFactorConfig.tokenWindow > 5) {\r\n throw new TwoFactorError('Token verification window must be between 0 and 5');\r\n }\r\n }\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new TwoFactorError('TwoFactorService must be initialized before use');\r\n }\r\n }\r\n\r\n public generateSecret(email: string): { secret: string; otpAuthUrl: string } {\r\n this.ensureInitialized();\r\n\r\n try {\r\n const secretObj = speakeasy.generateSecret({\r\n length: this.twoFactorConfig.secretLength,\r\n name: `${this.config.app_name}:${email}`,\r\n issuer: this.config.app_name\r\n });\r\n \r\n return {\r\n secret: secretObj.base32,\r\n otpAuthUrl: secretObj.otpauth_url || ''\r\n };\r\n } catch (error) {\r\n console.error('Error generating 2FA secret:', error);\r\n throw new TwoFactorError('Failed to generate 2FA secret');\r\n }\r\n }\r\n\r\n public async generateQRCode(otpAuthUrl: string): Promise<string> {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return await QRCode.toDataURL(otpAuthUrl, this.twoFactorConfig.qrCodeOptions);\r\n } catch (error) {\r\n console.error('QR code generation failed:', error);\r\n throw new TwoFactorError('Failed to generate QR code');\r\n }\r\n }\r\n\r\n public verifyToken(token: string, secret: string): boolean {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return speakeasy.totp.verify({\r\n secret,\r\n encoding: 'base32',\r\n token,\r\n window: this.twoFactorConfig.tokenWindow\r\n });\r\n } catch (error) {\r\n console.error('Token verification failed:', error);\r\n throw new TwoFactorError('Failed to verify 2FA token');\r\n }\r\n }\r\n}"],"mappings":"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","names":["import_cca_core","import_cca_entities","bcrypt","import_cca_core","import_cca_core","import_cca_core","bcrypt","import_cca_entities","import_core","import_classes","import_cca_entities","import_classes","mapper","import_cca_core","import_cca_core","import_cca_core","import_cca_entities","import_cca_core","import_cca_core","bcrypt","import_cca_core"]}
package/dist/index.mjs CHANGED
@@ -511,7 +511,6 @@ __name(_RefreshTokenUseCase, "RefreshTokenUseCase");
511
511
  var RefreshTokenUseCase = _RefreshTokenUseCase;
512
512
 
513
513
  // src/application/useCase/TwoFactorSetupUseCase.ts
514
- import { jwtDecode as jwtDecode2 } from "jwt-decode";
515
514
  var _TwoFactorSetupUseCase = class _TwoFactorSetupUseCase {
516
515
  constructor(twoFactorService, authRepository) {
517
516
  this.isInitialized = false;
@@ -525,24 +524,20 @@ var _TwoFactorSetupUseCase = class _TwoFactorSetupUseCase {
525
524
  ]);
526
525
  this.isInitialized = true;
527
526
  }
528
- async execute(token) {
527
+ async execute(userId) {
529
528
  if (!this.isInitialized) {
530
529
  await this.initialize();
531
530
  }
532
- if (!token) {
533
- throw new TwoFactorError("Token is required");
534
- }
535
- const decoded = jwtDecode2(token);
536
- const user = await this.authRepository.findByUserId(decoded.userId);
531
+ const user = await this.authRepository.findByUserId(userId);
537
532
  if (!user) {
538
- throw new TwoFactorError("User not found");
533
+ throw new ForbiddenError("User not found");
539
534
  }
540
535
  if (user.twoFactorEnabled) {
541
536
  throw new TwoFactorError("Two-factor authentication is already enabled");
542
537
  }
543
538
  const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);
544
539
  const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);
545
- await this.authRepository.updateTwoFactorSecret(decoded.userId, secret);
540
+ await this.authRepository.updateTwoFactorSecret(userId, secret);
546
541
  return { qrCodeUrl };
547
542
  }
548
543
  };
@@ -565,11 +560,11 @@ var _TwoFactorEnableUseCase = class _TwoFactorEnableUseCase {
565
560
  ]);
566
561
  this.isInitialized = true;
567
562
  }
568
- async execute(userId, dto) {
563
+ async execute(dto) {
569
564
  if (!this.isInitialized) {
570
565
  await this.initialize();
571
566
  }
572
- const { token } = dto;
567
+ const { token, userId } = dto;
573
568
  if (!token) {
574
569
  throw new TwoFactorError("Token is required");
575
570
  }
@@ -772,10 +767,10 @@ var _AuthController = class _AuthController {
772
767
  }, "refreshToken");
773
768
  this.setup2FA = /* @__PURE__ */ __name(async (req, res, next) => {
774
769
  try {
775
- console.log(" req.headers.authorization", req.headers.authorization);
776
- const authHeader = req.headers.authorization;
777
- const token = authHeader?.split(" ")[1]?.replace(/^"|"$/g, "");
778
- const result = await this.twoFactorSetupUseCase.execute(token);
770
+ if (!req.auth || !req.auth.id) {
771
+ throw new ForbiddenError("User authentication required");
772
+ }
773
+ const result = await this.twoFactorSetupUseCase.execute(req.auth.id);
779
774
  res.status(200).json(result);
780
775
  } catch (error) {
781
776
  next(error);
@@ -783,9 +778,9 @@ var _AuthController = class _AuthController {
783
778
  }, "setup2FA");
784
779
  this.enable2FA = /* @__PURE__ */ __name(async (req, res, next) => {
785
780
  try {
786
- const userId = req.auth?.id;
787
781
  const dto = req.body;
788
- await this.twoFactorEnableUseCase.execute(userId, dto);
782
+ dto.userId = req.auth?.id;
783
+ await this.twoFactorEnableUseCase.execute(dto);
789
784
  res.status(200).json({ message: "Two-factor authentication has been enabled successfully" });
790
785
  } catch (error) {
791
786
  next(error);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/application/config/ConfigManager.ts","../src/utils/Errors.ts","../src/application/service/utils/configInstance.ts","../src/infrastructure/container/createAuthContainer.ts","../src/application/useCase/LoginUseCase.ts","../src/application/validators/authValidation.ts","../src/application/useCase/LoginAdminUseCase.ts","../src/application/useCase/LogoutUseCase.ts","../src/application/useCase/RegisterUseCase.ts","../src/application/mappers/utils/mapper.ts","../src/application/mappers/createUserMappings.ts","../src/application/dtos/RegisterDTO.ts","../src/application/dtos/UserDTO.ts","../src/application/dtos/AdminDTO.ts","../src/application/useCase/RefreshTokenUseCase.ts","../src/application/useCase/TwoFactorSetupUseCase.ts","../src/application/useCase/TwoFactorEnableUseCase.ts","../src/application/useCase/TwoFactorVerifyUseCase.ts","../src/application/useCase/TwoFactorDisableUseCase.ts","../src/presentation/controller/AuthController.ts","../src/presentation/middleware/RequireComplete2FA.ts","../src/infrastructure/repository/AuthRepository.ts","../src/infrastructure/services/JwtAuthService.ts","../src/infrastructure/services/TwoFactorService.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\r\nimport { IConfig, ConfigSource } from \"../../domain/interfaces/configTypes\";\r\nimport { ConfigNotFoundException } from \"../../utils/Errors\";\r\n\r\nexport class ConfigManager extends EventEmitter {\r\n private config?: IConfig;\r\n private configSource?: ConfigSource;\r\n\r\n setConfigSource(source: ConfigSource): void {\r\n this.configSource = source;\r\n }\r\n\r\n setConfig(cfg: IConfig): void {\r\n this.config = { ...cfg };\r\n this.emit(\"configAvailable\", this.config);\r\n }\r\n\r\n getConfig(): IConfig | undefined {\r\n return this.config;\r\n }\r\n\r\n async loadConfig(): Promise<IConfig> {\r\n if (!this.configSource) {\r\n throw new ConfigNotFoundException(\"Config source not set\");\r\n }\r\n try {\r\n const config = await this.configSource();\r\n this.setConfig(config);\r\n return config;\r\n } catch (error) {\r\n throw new ConfigNotFoundException(\"Error loading configuration\");\r\n }\r\n }\r\n}\r\n\r\nexport const configManager = new ConfigManager();\r\n","export class AppError extends Error {\r\n constructor(\r\n public message: string,\r\n public statusCode: number = 500,\r\n public name: string = \"AppError\"\r\n ) {\r\n super(message);\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n Error.captureStackTrace(this);\r\n }\r\n}\r\n\r\nexport class ValidationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"ValidationError\";\r\n }\r\n}\r\n\r\nexport class ConfigNotFoundException extends AppError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"ConfigNotFoundException\";\r\n }\r\n}\r\n\r\nexport class NotFoundError extends AppError {\r\n constructor(message: string) {\r\n super(message, 404, \"UserNotFoundError\");\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends AppError {\r\n constructor(message: string = \"Forbidden access\") {\r\n super(message, 403);\r\n this.name = \"ForbiddenError\";\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends AppError {\r\n constructor(message: string = \"Unauthorized access\") {\r\n super(message, 401);\r\n this.name = \"UnauthorizedError\";\r\n }\r\n}\r\n\r\nexport class JwtError extends AppError {\r\n constructor(message: string) {\r\n super(message, 401);\r\n this.name = \"JwtError\";\r\n }\r\n}\r\n\r\nexport class RegistrationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"RegistrationError\";\r\n }\r\n}\r\n\r\nexport class TwoFactorError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"TwoFactorERROR\";\r\n }\r\n}","import { configManager } from \"../../config/ConfigManager\";\r\nimport { IConfig, ConfigSource } from \"../../../domain/interfaces/configTypes\";\r\n\r\nexport const authConfig = (configSource: ConfigSource): void => {\r\n configManager.setConfigSource(configSource);\r\n};\r\n\r\nexport const createConfigInstance = async (): Promise<IConfig> => {\r\n return configManager.getConfig() ?? (await configManager.loadConfig());\r\n};\r\n","import { BaseContainer, BaseDatabase } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { AuthController } from \"../../presentation/controller/AuthController\";\r\nimport { RequireComplete2FA } from \"../../presentation/middleware/RequireComplete2FA\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { JwtAuthService } from \"../services/JwtAuthService\";\r\nimport { TwoFactorService } from \"../services/TwoFactorService\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\n\r\nasync function createAuthContainer(database: BaseDatabase) {\r\n const container = new BaseContainer({ database });\r\n\r\n const authRepository = new AuthRepository(\r\n database.getRepository(AuthEntity)\r\n );\r\n container.registerRepository<AuthEntity>(\"AuthRepository\", authRepository);\r\n\r\n const jwtAuthService = new JwtAuthService(authRepository);\r\n container.registerService(\"JwtAuthService\", jwtAuthService);\r\n\r\n const configData = await createConfigInstance();\r\n\r\n const twoFactorService = new TwoFactorService(configData);\r\n container.registerService(\"TwoFactorService\", twoFactorService);\r\n\r\n const requireComplete2FA = new RequireComplete2FA(jwtAuthService);\r\n\r\n const loginUseCase = new LoginUseCase(authRepository, jwtAuthService);\r\n const loginAdminUseCase = new LoginAdminUseCase(\r\n authRepository\r\n );\r\n const logoutUseCase = new LogoutUseCase(authRepository);\r\n const registerUseCase = new RegisterUseCase(authRepository);\r\n const refreshTokenUseCase = new RefreshTokenUseCase(\r\n authRepository,\r\n jwtAuthService\r\n );\r\n\r\n const twoFactorSetupUseCase = new TwoFactorSetupUseCase(twoFactorService, authRepository);\r\n const twoFactorEnableUseCase = new TwoFactorEnableUseCase(twoFactorService, authRepository);\r\n const twoFactorVerifyUseCase = new TwoFactorVerifyUseCase(\r\n twoFactorService,\r\n authRepository,\r\n jwtAuthService\r\n );\r\n const twoFactorDisableUseCase = new TwoFactorDisableUseCase(twoFactorService, authRepository);\r\n\r\n container.registerService(\"LoginUseCase\", loginUseCase);\r\n container.registerService(\"LoginAdminUseCase\", loginAdminUseCase);\r\n container.registerService(\"LogoutUseCase\", logoutUseCase);\r\n container.registerService(\"RegisterUseCase\", registerUseCase);\r\n container.registerService(\"RefreshTokenUseCase\", refreshTokenUseCase);\r\n container.registerService(\"TwoFactorSetupUseCase\", twoFactorSetupUseCase);\r\n container.registerService(\"TwoFactorEnableUseCase\", twoFactorEnableUseCase);\r\n container.registerService(\"TwoFactorVerifyUseCase\", twoFactorVerifyUseCase);\r\n container.registerService(\"TwoFactorDisableUseCase\", twoFactorDisableUseCase);\r\n\r\n const authController = new AuthController(\r\n loginUseCase,\r\n loginAdminUseCase,\r\n logoutUseCase,\r\n registerUseCase,\r\n refreshTokenUseCase,\r\n twoFactorSetupUseCase,\r\n twoFactorEnableUseCase,\r\n twoFactorVerifyUseCase,\r\n twoFactorDisableUseCase\r\n );\r\n\r\n return { container, authController, requireComplete2FA };\r\n}\r\n\r\nexport { createAuthContainer };","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { jwtDecode } from \"jwt-decode\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateLoginDTO } from \"../validators/authValidation\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { IJwtPayload } from \"../../domain/interfaces/IJwtPayload\";\r\n\r\n\r\nexport class LoginUseCase implements IBaseService {\r\n\r\n constructor(\r\n private readonly repository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO): Promise<{ id: string, accessToken: string, expiresAt: number , enabled?: boolean }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n \r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n const expiresAt = jwtDecode<IJwtPayload>(accessToken).exp;\r\n\r\n if (auth.twoFactorEnabled) {\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt, enabled: auth.twoFactorEnabled };\r\n }\r\n\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt };\r\n }\r\n}","import * as yup from \"yup\";\r\nimport { AuthEntity, UserRole } from \"cca-entities\";\r\nimport bcrypt from \"bcrypt\";\r\n\r\nimport {\r\n ForbiddenError,\r\n NotFoundError,\r\n ValidationError,\r\n} from \"../../utils/Errors\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\n\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { createConfigInstance } from \"../service/utils/configInstance\";\r\n\r\nconst schemas = {\r\n id: yup.string().uuid(\"Invalid user ID format\"),\r\n email: yup\r\n .string()\r\n .email(\"Invalid email format\")\r\n .max(255, \"Email cannot exceed 255 characters\"),\r\n name: yup\r\n .string()\r\n .required(\"Name is required\")\r\n .min(2, \"Name must be at least 2 characters long\")\r\n .max(50, \"Name cannot exceed 50 characters\")\r\n .matches(/^[a-zA-Z\\s]+$/, \"Name must only contain letters and spaces\"),\r\n password: yup\r\n .string()\r\n .required(\"Password required\")\r\n .min(8, \"Password too short\")\r\n .max(100, \"Password too long\")\r\n .matches(\r\n /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]/,\r\n \"Password must contain uppercase, lowercase, number and special character\"\r\n ),\r\n role: yup\r\n .string()\r\n .oneOf(Object.values(UserRole), \"Invalid role specified\"),\r\n};\r\n\r\nexport const validateEmail = async (\r\n email: string,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n const user = await repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\r\n \"The email address or password is incorrect. Please retry\"\r\n );\r\n }\r\n return user;\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid email format\");\r\n }\r\n};\r\n\r\nexport const validatePassword = async (password?: string): Promise<void> => {\r\n if (password) {\r\n try {\r\n await schemas.password.validate(password);\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid password format\");\r\n }\r\n }\r\n};\r\n\r\nexport const validateEmailUniqueness = async (\r\n repository: AuthRepository,\r\n email: string,\r\n excludeUserId?: string\r\n): Promise<void> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n\r\n const existingUser = await repository.findByEmail(email);\r\n\r\n if (!existingUser) return;\r\n if (existingUser.id === excludeUserId) return;\r\n\r\n throw new ValidationError(`Email ${email} is already in use.`);\r\n } catch (error: any) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"user email validation failed\");\r\n }\r\n};\r\n\r\nexport const validateRegisterDTO = async (\r\n auth: RegisterDTO,\r\n repository: AuthRepository\r\n): Promise<void> => {\r\n const { name, email, role, password } = auth;\r\n\r\n await Promise.all([\r\n schemas.name.validate(name),\r\n schemas.role.validate(role),\r\n validateEmailUniqueness(repository, email),\r\n validatePassword(password),\r\n ]);\r\n};\r\n\r\nexport const validateLoginDTO = async (\r\n data: LoginDTO,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n const { email, role, password } = data;\r\n\r\n if (role) {\r\n await schemas.role.validate(role);\r\n }\r\n\r\n await schemas.password.validate(password);\r\n\r\n const auth = await validateEmail(email, repository);\r\n if (!auth || !auth.password) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const isMatch = await bcrypt.compare(password, auth.password);\r\n if (!isMatch) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return auth;\r\n};\r\n\r\nexport const validateAdminSecret = async (\r\n secretPassword?: string\r\n): Promise<void> => {\r\n if (!secretPassword) {\r\n throw new ValidationError(\"Admin password is required\");\r\n }\r\n\r\n try {\r\n const config = await createConfigInstance();\r\n\r\n if (!config.adminSecretPassword) {\r\n throw new ValidationError(\"ADMIN_SECRET_PASSWORD not found in config\");\r\n }\r\n\r\n if (parseInt(secretPassword) !== parseInt(config.adminSecretPassword)) {\r\n throw new ValidationError(\"Invalid admin password\");\r\n }\r\n } catch (error) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"Error validating admin password\");\r\n }\r\n};\r\n","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateAdminSecret, validateLoginDTO } from \"../validators/authValidation\";\r\n\r\nexport class LoginAdminUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n\r\n constructor(\r\n repository: AuthRepository\r\n ) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO, adminPassword: string): Promise<string> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\n\r\nexport class LogoutUseCase implements IBaseService {\r\n private readonly repository: AuthRepository\r\n\r\n constructor(repository: AuthRepository) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(authId: string): Promise<void> {\r\n try {\r\n await this.repository.logout(authId);\r\n } catch (error) {\r\n new NotFoundError(\"Auth not found\");\r\n }\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { AdminEntity, AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private readonly SALT_ROUNDS = 10;\r\n\r\n constructor(private readonly repository: AuthRepository) {}\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo) => repo.getAll());\r\n }\r\n\r\n public async execute(\r\n email: string,\r\n name: string,\r\n password: string,\r\n role: UserRole = UserRole.GUEST,\r\n adminPassword?: string\r\n ): Promise<AuthEntity | undefined> {\r\n try {\r\n const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });\r\n\r\n const isAdminUser = await this._validateAdminRegistration(\r\n normalizedDTO.role,\r\n normalizedDTO.adminPassword\r\n );\r\n\r\n await validateRegisterDTO(normalizedDTO, this.repository);\r\n\r\n const hashedPassword = await this._hashPassword(normalizedDTO.password);\r\n const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);\r\n\r\n return this.repository.create(authEntity);\r\n } catch (error) {\r\n throw new RegistrationError(\r\n `Registration failed: ${error instanceof Error ? error.message : \"Unknown error\"}`\r\n );\r\n }\r\n }\r\n\r\n private _normalizeInput(dto: RegisterDTO): RegisterDTO {\r\n return {\r\n name: dto.name.trim(),\r\n email: dto.email.trim().toLowerCase(),\r\n password: dto.password.trim(),\r\n role: dto.role,\r\n adminPassword: dto.adminPassword?.trim()\r\n };\r\n }\r\n\r\n private async _hashPassword(password: string): Promise<string> {\r\n return bcrypt.hash(password, this.SALT_ROUNDS);\r\n }\r\n\r\n private async _validateAdminRegistration(\r\n role: UserRole,\r\n adminPassword?: string\r\n ): Promise<boolean> {\r\n if (role !== UserRole.ADMIN) return false;\r\n\r\n if (!adminPassword) {\r\n throw new UnauthorizedError(\"Admin password is required for admin registration\");\r\n }\r\n\r\n await validateAdminSecret(adminPassword);\r\n return true;\r\n }\r\n\r\n private _buildMappedAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): AuthEntity {\r\n const authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userOrAdminEntity = isAdmin\r\n ? mapper.map(dto, RegisterDTO, AdminEntity)\r\n : mapper.map(dto, RegisterDTO, UserEntity);\r\n\r\n userOrAdminEntity.updatedAt = undefined as unknown as Date;\r\n\r\n if (isAdmin) {\r\n authEntity.admin = userOrAdminEntity;\r\n } else {\r\n authEntity.user = userOrAdminEntity;\r\n }\r\n\r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n\r\n return authEntity;\r\n }\r\n}\r\n","import { createMapper } from '@automapper/core';\r\nimport { classes } from '@automapper/classes';\r\n\r\nimport { createUserMappings } from '../createUserMappings';\r\n\r\nexport const mapper = createMapper({\r\n strategyInitializer: classes(),\r\n});\r\n\r\ncreateUserMappings(mapper);\r\n","import { Mapper, createMap, forMember, mapFrom } from '@automapper/core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { RegisterDTO } from '../dtos/RegisterDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\n\r\nexport function createUserMappings(mapper: Mapper): void {\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AuthEntity,\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.password, mapFrom(src => src.password)),\r\n forMember(dest => dest.role, mapFrom(src => src.role)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n UserEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AdminEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n UserEntity,\r\n UserDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.profileImageUrl, mapFrom(src => getProfileImageUrl(src))));\r\n\r\n\r\n createMap(\r\n mapper,\r\n AdminEntity,\r\n AdminDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n const getProfileImageUrl = (src: UserEntity): string | undefined => {\r\n const image = src.images?.[0];\r\n if (!image) return undefined;\r\n return image.mdUrl ?? image.smUrl ?? image.lgUrl ?? image.thumbUrl ?? image.originalUrl ?? image.xlUrl;\r\n };\r\n}","import { UserRole } from \"cca-entities\";\r\n\r\nexport class RegisterDTO {\r\n email!: string;\r\n name!: string;\r\n password!: string;\r\n role!: UserRole;\r\n adminPassword?: string;\r\n}\r\n","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class UserDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n @AutoMap()\r\n profileImageUrl?: string;\r\n}","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class AdminDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n adminPassword!: string;\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { ITokenPair } from \"../../domain/interfaces/ITokenPair\";\r\n\r\nexport class RefreshTokenUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n private readonly service: JwtAuthService;\r\n\r\n constructor(repository: AuthRepository, service: JwtAuthService) {\r\n this.repository = repository;\r\n this.service = service;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n public async execute(refreshToken: string): Promise<ITokenPair | null> {\r\n try {\r\n const decoded = await this.service.verifyRefreshToken(refreshToken);\r\n\r\n if (!decoded.userId) {\r\n return null;\r\n }\r\n\r\n let authEntity = await this.repository.findByUseAdminId(decoded.userId);\r\n\r\n if (!authEntity) {\r\n authEntity = await this.repository.findByUseAdminId(decoded.userId, true);\r\n }\r\n\r\n if (!authEntity) {\r\n return null;\r\n }\r\n\r\n const user = authEntity.role === \"admin\" ? authEntity.admin : authEntity.user;\r\n\r\n const accessToken = this.service.generateAccessToken(user, authEntity.role);\r\n const newRefreshToken = this.service.generateRefreshToken(user);\r\n\r\n await this.repository.update(authEntity.id, {\r\n refreshToken: newRefreshToken\r\n });\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken\r\n };\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n}","import { IBaseService } from 'cca-core';\r\nimport { jwtDecode } from 'jwt-decode';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorSetupResponse } from '../../domain/interfaces/ITwoFactorSetupResponse';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { IJwtPayload } from '../../domain/interfaces/IJwtPayload';\r\n\r\nexport class TwoFactorSetupUseCase implements IBaseService {\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n await Promise.all([\r\n this.twoFactorService.initialize()\r\n ]);\r\n\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(token: string): Promise<ITwoFactorSetupResponse> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n const decoded = jwtDecode<IJwtPayload>(token);\r\n const user = await this.authRepository.findByUserId(decoded.userId);\r\n\r\n if (!user) {\r\n throw new TwoFactorError('User not found');\r\n }\r\n\r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n\r\n const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);\r\n const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);\r\n\r\n await this.authRepository.updateTwoFactorSecret(decoded.userId, secret);\r\n\r\n return { qrCodeUrl };\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorEnableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n \r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n \r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto;\r\n \r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret) {\r\n throw new TwoFactorError('Please set up two-factor authentication first');\r\n }\r\n \r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.enableTwoFactor(user);\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\nimport { ITwoFactorVerify } from '../../domain/interfaces/ITwoFactorVerify';\r\nimport { ITokenPair } from '../../domain/interfaces/ITokenPair';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { mapper } from '../mappers/utils/mapper';\r\n\r\nexport class TwoFactorVerifyUseCase implements IBaseService {\r\n private isInitialized = false;\r\n\r\n constructor(\r\n private readonly twoFactorService: TwoFactorService,\r\n private readonly authRepository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n this.jwtService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n this.isInitialized = true;\r\n }\r\n\r\n public async execute(dto: ITwoFactorVerify): Promise<{ token: string; refreshToken: string; data?: AdminDTO | UserDTO } | null> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const { userId, token } = dto;\r\n if (!userId || !token) {\r\n throw new TwoFactorError('User ID and token are required.');\r\n }\r\n\r\n const auth: AuthEntity | null = await this.authRepository.findByUserId(userId);\r\n if (!auth || !auth.twoFactorSecret || !auth.twoFactorEnabled) {\r\n throw new TwoFactorError('Invalid request.');\r\n }\r\n\r\n const isValid = this.twoFactorService.verifyToken(token, auth.twoFactorSecret);\r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code.');\r\n }\r\n\r\n const tokenPair: ITokenPair = this.generateTokens(auth);\r\n await this.updateUserStatus(auth);\r\n await this.updateUserRefreshToken(auth, tokenPair.refreshToken);\r\n\r\n if (auth.admin) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapAdminToDTO(auth.admin)\r\n };\r\n }\r\n\r\n if (auth.user) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapUserToDTO(auth.user)\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private mapAdminToDTO(admin: AdminEntity): AdminDTO {\r\n return mapper.map(admin, AdminEntity, AdminDTO);\r\n }\r\n\r\n private mapUserToDTO(user: UserEntity): UserDTO {\r\n return mapper.map(user, UserEntity, UserDTO);\r\n }\r\n\r\n private async updateUserStatus(auth: AuthEntity): Promise<void> {\r\n auth.user.lastLoginAt = new Date();\r\n auth.user.isActive = true;\r\n await this.authRepository.update(auth.id, auth);\r\n }\r\n\r\n private async updateUserRefreshToken(auth: AuthEntity, refreshToken: string): Promise<void> {\r\n auth.refreshToken = refreshToken;\r\n await this.authRepository.update(auth.id, { refreshToken });\r\n }\r\n\r\n private generateTokens(auth: AuthEntity): ITokenPair {\r\n return {\r\n accessToken: this.jwtService.generateAccessToken(auth.user, auth.role),\r\n refreshToken: this.jwtService.generateRefreshToken(auth.user)\r\n };\r\n }\r\n}\r\n","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorDisableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n4\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto; \r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret || !user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is not enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.disableTwoFactor(user);\r\n }\r\n}","import { NextFunction, Request, Response } from \"express\";\r\n\r\nimport { LoginDTO } from \"../../application/dtos/LoginDTO\";\r\nimport { RegisterDTO } from \"../../application/dtos/RegisterDTO\";\r\n\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { IRefreshTokenRequest } from \"../../domain/interfaces/IRefreshTokenRequest\";\r\nimport { ITwoFactorEnable } from \"../../domain/interfaces/ITwoFactorEnable\";\r\nimport { ITwoFactorVerify } from \"../../domain/interfaces/ITwoFactorVerify\";\r\nimport { ForbiddenError } from \"../../utils/Errors\";\r\n\r\nexport class AuthController {\r\n private readonly loginUseCase: LoginUseCase;\r\n private readonly adminLoginUseCase: LoginAdminUseCase;\r\n private readonly logoutUseCase: LogoutUseCase;\r\n private readonly registerUseCase: RegisterUseCase;\r\n private readonly refreshTokenUseCase: RefreshTokenUseCase;\r\n\r\n private twoFactorSetupUseCase: TwoFactorSetupUseCase;\r\n private twoFactorEnableUseCase: TwoFactorEnableUseCase;\r\n private twoFactorVerifyUseCase: TwoFactorVerifyUseCase;\r\n private twoFactorDisableUseCase: TwoFactorDisableUseCase;\r\n\r\n constructor(\r\n loginUseCase: LoginUseCase,\r\n adminLoginUseCase: LoginAdminUseCase,\r\n logoutUseCase: LogoutUseCase,\r\n registerUseCase: RegisterUseCase,\r\n refreshTokenUseCase: RefreshTokenUseCase,\r\n twoFactorSetupUseCase: TwoFactorSetupUseCase,\r\n twoFactorEnableUseCase: TwoFactorEnableUseCase,\r\n twoFactorVerifyUseCase: TwoFactorVerifyUseCase,\r\n twoFactorDisableUseCase: TwoFactorDisableUseCase\r\n ) {\r\n this.loginUseCase = loginUseCase;\r\n this.adminLoginUseCase = adminLoginUseCase;\r\n this.logoutUseCase = logoutUseCase;\r\n this.registerUseCase = registerUseCase;\r\n this.refreshTokenUseCase = refreshTokenUseCase;\r\n this.twoFactorSetupUseCase = twoFactorSetupUseCase;\r\n this.twoFactorEnableUseCase = twoFactorEnableUseCase;\r\n this.twoFactorVerifyUseCase = twoFactorVerifyUseCase;\r\n this.twoFactorDisableUseCase = twoFactorDisableUseCase;\r\n }\r\n\r\n login = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const loginDTO: LoginDTO = req.body;\r\n\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n if (result.enabled) {\r\n return res.status(201).json({\r\n status: \"pending\",\r\n message: \"Enter 2FA code\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n }\r\n\r\n res.status(200).json({\r\n status: \"success\",\r\n message: \"Login successful\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n adminLogin = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n if (!adminPassword) {\r\n throw new ForbiddenError(\"Admin password is required\");\r\n }\r\n const result = await this.adminLoginUseCase.execute(loginDTO, adminPassword);\r\n res.status(201).json(result);\r\n }\r\n catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n logout = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n await this.logoutUseCase.execute(req.body.id);\r\n res.status(200).json({ message: 'Logged out successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n register = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const { email, name, password, role, adminPassword }: RegisterDTO = req.body;\r\n\r\n await this.registerUseCase.execute(email, name, password, role, adminPassword);\r\n res.status(200).json({ status: \"success\" });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n refreshToken = async (req: Request, res: Response) => {\r\n const { refreshToken }: IRefreshTokenRequest = req.body;\r\n\r\n const result = await this.refreshTokenUseCase.execute(refreshToken);\r\n res.json(result);\r\n };\r\n\r\n setup2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n console.log(\" req.headers.authorization\", req.headers.authorization);\r\n\r\n const authHeader = req.headers.authorization;\r\n const token = authHeader?.split(' ')[1]?.replace(/^\"|\"$/g, '') as string;\r\n\r\n const result = await this.twoFactorSetupUseCase.execute(token);\r\n res.status(200).json(result);\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n enable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth?.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorEnableUseCase.execute(userId, dto);\r\n res.status(200).json({ message: 'Two-factor authentication has been enabled successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n verify2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorVerify = req.body;\r\n\r\n const result = await this.twoFactorVerifyUseCase.execute(dto);\r\n res.status(200).json({\r\n message: 'Two-factor authentication successful',\r\n ...result\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n disable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth!.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorDisableUseCase.execute(userId, dto);\r\n res.status(200).json({\r\n status: \"success\",\r\n message: 'Two-factor authentication has been disabled successfully'\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n","import { NextFunction, Request, Response } from 'express';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\n\r\nexport class RequireComplete2FA {\r\n private readonly jwtService: JwtAuthService;\r\n\r\n constructor(jwtService: JwtAuthService) {\r\n this.jwtService = jwtService;\r\n }\r\n\r\n public async execute(req: Request, res: Response, next: NextFunction) {\r\n try {\r\n const token = req.headers.authorization?.split(' ')[1];\r\n\r\n if (!token) {\r\n return res.status(401).json({ message: 'Authentication required' });\r\n }\r\n\r\n const decoded = await this.jwtService.verifyAccessToken(token);\r\n\r\n if (!decoded.twoFactorAuthenticated) {\r\n return res.status(403).json({\r\n message: 'Two-factor authentication required',\r\n code: 'REQUIRE_2FA',\r\n userId: decoded.id\r\n });\r\n }\r\n\r\n req.auth = { ...decoded, twoFactorAuthenticated: true };\r\n next();\r\n } catch (error) {\r\n return res.status(401).json({ message: 'Invalid or expired token' });\r\n }\r\n }\r\n}","import { BaseRepository, IExtendedBaseRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\nimport { Repository } from \"typeorm\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\nexport class AuthRepository\r\n extends BaseRepository<AuthEntity>\r\n implements IExtendedBaseRepository<AuthEntity> {\r\n constructor(repository: Repository<AuthEntity>) {\r\n super(repository);\r\n }\r\n\r\n async findByEmail(email: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.password\")\r\n .where(\"auth.email = :email\", { email });\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async create(entity: Omit<AuthEntity, \"createdAt\">): Promise<AuthEntity> {\r\n return super.create(entity);\r\n }\r\n\r\n async findByUserId(userId: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.twoFactorSecret\")\r\n .where(\"user.id = :userId\", { userId });\r\n\r\n return await query.getOne();;\r\n }\r\n\r\n async findByUseAdminId(userId: string, isAdmin: boolean = false): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .addSelect(\"auth.twoFactorSecret\");\r\n\r\n if (isAdmin) {\r\n query.leftJoinAndSelect(\"auth.admin\", \"admin\")\r\n .where(\"admin.id = :userId\", { userId });\r\n } else {\r\n query.leftJoinAndSelect(\"auth.user\", \"user\")\r\n .where(\"user.id = :userId\", { userId });\r\n }\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async logout(userId: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.refreshToken = \"\";\r\n auth.user.isActive = false;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async updateTwoFactorSecret(userId: string, secret: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.twoFactorSecret = secret;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async enableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = true;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async disableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = false;\r\n auth.twoFactorSecret = null;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async isTwoFactorEnabled(userId: string): Promise<boolean> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return !!auth.twoFactorEnabled;\r\n }\r\n\r\n async getTwoFactorSecret(userId: string): Promise<string | null> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return auth.twoFactorSecret;\r\n }\r\n}\r\n","import * as jwt from \"jsonwebtoken\";\r\nimport { Secret, SignOptions } from \"jsonwebtoken\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { IJwtConfig } from \"../../domain/interfaces/IJwtConfig\";\r\nimport { IAuthService } from \"../../domain/interfaces/IAuthService\";\r\nimport { IDecodedToken } from \"../../domain/interfaces/IDecodedToken\";\r\n\r\nimport {\r\n ForbiddenError,\r\n JwtError,\r\n NotFoundError,\r\n UnauthorizedError,\r\n} from \"../../utils/Errors\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\nimport { log } from \"console\";\r\n\r\nexport class JwtAuthService implements IBaseService, IAuthService {\r\n private jwtConfig: IJwtConfig | undefined;\r\n\r\n constructor(private readonly repository: AuthRepository, config?: IJwtConfig) {\r\n this.loadConfig(config);\r\n }\r\n\r\n private async loadConfig(config?: IJwtConfig) {\r\n const configData = await createConfigInstance();\r\n\r\n this.jwtConfig = {\r\n accessTokenSecret: configData.accessTokenSecret,\r\n refreshTokenSecret: configData.refreshTokenSecret,\r\n accessTokenExpiry: parseInt(configData.accessTokenExpiry, 10),\r\n refreshTokenExpiry: parseInt(configData.refreshTokenExpiry, 10),\r\n ...config,\r\n };\r\n\r\n this.validateConfiguration();\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n await validateRepository(this.repository, repo => repo.getAll());\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.jwtConfig?.accessTokenSecret || !this.jwtConfig?.refreshTokenSecret) {\r\n throw new JwtError(\"JWT secrets required in config\");\r\n }\r\n }\r\n\r\n async validateUser(email: string, password: string): Promise<AuthEntity | null> {\r\n const user = await this.repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const validPassword = await bcrypt.compare(password, user.password);\r\n if (!validPassword) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return user;\r\n }\r\n\r\n private verifyJwtConfig() {\r\n if (!this.jwtConfig) throw new JwtError(\"JWT config not loaded\");\r\n }\r\n\r\n generateAccessToken(user: UserEntity, role : UserRole): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id, email: user.email, role: role },\r\n this.jwtConfig!.accessTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.accessTokenExpiry }\r\n );\r\n }\r\n\r\n generateRefreshToken(user: UserEntity): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id },\r\n this.jwtConfig!.refreshTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.refreshTokenExpiry }\r\n );\r\n }\r\n\r\n async verifyToken(token: string, secret: string): Promise<IDecodedToken> {\r\n try {\r\n console.log(\"Verifying token:\", token);\r\n console.log(\"Using secret:\", secret);\r\n \r\n return jwt.verify(token, secret) as IDecodedToken;\r\n } catch(error) {\r\n console.error(\"Error verifying token:\", error);\r\n throw new UnauthorizedError();\r\n }\r\n }\r\n\r\n async verifyAccessToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.accessTokenSecret);\r\n }\r\n\r\n async verifyRefreshToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.refreshTokenSecret);\r\n }\r\n}\r\n","import * as speakeasy from 'speakeasy';\r\nimport * as QRCode from 'qrcode';\r\nimport { IBaseService } from 'cca-core';\r\n\r\nimport { IConfig } from '../../domain/interfaces/configTypes';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorService implements IBaseService {\r\n private readonly config: IConfig;\r\n private initialized: boolean = false;\r\n private readonly twoFactorConfig: {\r\n tokenWindow: number;\r\n secretLength: number;\r\n qrCodeOptions: QRCode.QRCodeToDataURLOptions;\r\n };\r\n\r\n constructor(config: IConfig) {\r\n this.config = config;\r\n \r\n this.twoFactorConfig = {\r\n tokenWindow: parseInt(config.tokenWindow) ?? 1,\r\n secretLength: parseInt(config.secretLength) ?? 20,\r\n qrCodeOptions: {\r\n errorCorrectionLevel: 'M',\r\n margin: 4,\r\n scale: 4,\r\n color: {\r\n dark: '#000000',\r\n light: '#ffffff'\r\n }\r\n }\r\n };\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n this.validateConfiguration();\r\n this.initialized = true;\r\n } catch (error) {\r\n console.error('TwoFactorService initialization failed:', error);\r\n throw new TwoFactorError('Failed to initialize TwoFactorService');\r\n }\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.config.app_name?.trim()) {\r\n throw new TwoFactorError('Application name (appName) is required in configuration');\r\n }\r\n\r\n if (this.twoFactorConfig.secretLength < 16) {\r\n throw new TwoFactorError('Secret length must be at least 16 characters');\r\n }\r\n\r\n if (this.twoFactorConfig.tokenWindow < 0 || this.twoFactorConfig.tokenWindow > 5) {\r\n throw new TwoFactorError('Token verification window must be between 0 and 5');\r\n }\r\n }\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new TwoFactorError('TwoFactorService must be initialized before use');\r\n }\r\n }\r\n\r\n public generateSecret(email: string): { secret: string; otpAuthUrl: string } {\r\n this.ensureInitialized();\r\n\r\n try {\r\n const secretObj = speakeasy.generateSecret({\r\n length: this.twoFactorConfig.secretLength,\r\n name: `${this.config.app_name}:${email}`,\r\n issuer: this.config.app_name\r\n });\r\n \r\n return {\r\n secret: secretObj.base32,\r\n otpAuthUrl: secretObj.otpauth_url || ''\r\n };\r\n } catch (error) {\r\n console.error('Error generating 2FA secret:', error);\r\n throw new TwoFactorError('Failed to generate 2FA secret');\r\n }\r\n }\r\n\r\n public async generateQRCode(otpAuthUrl: string): Promise<string> {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return await QRCode.toDataURL(otpAuthUrl, this.twoFactorConfig.qrCodeOptions);\r\n } catch (error) {\r\n console.error('QR code generation failed:', error);\r\n throw new TwoFactorError('Failed to generate QR code');\r\n }\r\n }\r\n\r\n public verifyToken(token: string, secret: string): boolean {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return speakeasy.totp.verify({\r\n secret,\r\n encoding: 'base32',\r\n token,\r\n window: this.twoFactorConfig.tokenWindow\r\n });\r\n } catch (error) {\r\n console.error('Token verification failed:', error);\r\n throw new TwoFactorError('Failed to verify 2FA token');\r\n }\r\n }\r\n}"],"mappings":"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","names":["AuthEntity","validateRepository","validateRepository","validateRepository","validateRepository","validateRepository","bcrypt","AdminEntity","AuthEntity","UserEntity","UserRole","AuthEntity","AutoMap","AutoMap","mapper","AuthEntity","validateRepository","UserRole","AuthEntity","AdminEntity","UserEntity","validateRepository","validateRepository","jwtDecode","jwtDecode","validateRepository","validateRepository","validateRepository","AdminEntity","UserEntity","validateRepository","AdminEntity","UserEntity","validateRepository","validateRepository","bcrypt","validateRepository","validateRepository","AuthEntity"]}
1
+ {"version":3,"sources":["../src/application/config/ConfigManager.ts","../src/utils/Errors.ts","../src/application/service/utils/configInstance.ts","../src/infrastructure/container/createAuthContainer.ts","../src/application/useCase/LoginUseCase.ts","../src/application/validators/authValidation.ts","../src/application/useCase/LoginAdminUseCase.ts","../src/application/useCase/LogoutUseCase.ts","../src/application/useCase/RegisterUseCase.ts","../src/application/mappers/utils/mapper.ts","../src/application/mappers/createUserMappings.ts","../src/application/dtos/RegisterDTO.ts","../src/application/dtos/UserDTO.ts","../src/application/dtos/AdminDTO.ts","../src/application/useCase/RefreshTokenUseCase.ts","../src/application/useCase/TwoFactorSetupUseCase.ts","../src/application/useCase/TwoFactorEnableUseCase.ts","../src/application/useCase/TwoFactorVerifyUseCase.ts","../src/application/useCase/TwoFactorDisableUseCase.ts","../src/presentation/controller/AuthController.ts","../src/presentation/middleware/RequireComplete2FA.ts","../src/infrastructure/repository/AuthRepository.ts","../src/infrastructure/services/JwtAuthService.ts","../src/infrastructure/services/TwoFactorService.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\r\nimport { IConfig, ConfigSource } from \"../../domain/interfaces/configTypes\";\r\nimport { ConfigNotFoundException } from \"../../utils/Errors\";\r\n\r\nexport class ConfigManager extends EventEmitter {\r\n private config?: IConfig;\r\n private configSource?: ConfigSource;\r\n\r\n setConfigSource(source: ConfigSource): void {\r\n this.configSource = source;\r\n }\r\n\r\n setConfig(cfg: IConfig): void {\r\n this.config = { ...cfg };\r\n this.emit(\"configAvailable\", this.config);\r\n }\r\n\r\n getConfig(): IConfig | undefined {\r\n return this.config;\r\n }\r\n\r\n async loadConfig(): Promise<IConfig> {\r\n if (!this.configSource) {\r\n throw new ConfigNotFoundException(\"Config source not set\");\r\n }\r\n try {\r\n const config = await this.configSource();\r\n this.setConfig(config);\r\n return config;\r\n } catch (error) {\r\n throw new ConfigNotFoundException(\"Error loading configuration\");\r\n }\r\n }\r\n}\r\n\r\nexport const configManager = new ConfigManager();\r\n","export class AppError extends Error {\r\n constructor(\r\n public message: string,\r\n public statusCode: number = 500,\r\n public name: string = \"AppError\"\r\n ) {\r\n super(message);\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n Error.captureStackTrace(this);\r\n }\r\n}\r\n\r\nexport class ValidationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"ValidationError\";\r\n }\r\n}\r\n\r\nexport class ConfigNotFoundException extends AppError {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = \"ConfigNotFoundException\";\r\n }\r\n}\r\n\r\nexport class NotFoundError extends AppError {\r\n constructor(message: string) {\r\n super(message, 404, \"UserNotFoundError\");\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends AppError {\r\n constructor(message: string = \"Forbidden access\") {\r\n super(message, 403);\r\n this.name = \"ForbiddenError\";\r\n }\r\n}\r\n\r\nexport class UnauthorizedError extends AppError {\r\n constructor(message: string = \"Unauthorized access\") {\r\n super(message, 401);\r\n this.name = \"UnauthorizedError\";\r\n }\r\n}\r\n\r\nexport class JwtError extends AppError {\r\n constructor(message: string) {\r\n super(message, 401);\r\n this.name = \"JwtError\";\r\n }\r\n}\r\n\r\nexport class RegistrationError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"RegistrationError\";\r\n }\r\n}\r\n\r\nexport class TwoFactorError extends AppError {\r\n constructor(message: string) {\r\n super(message, 400);\r\n this.name = \"TwoFactorERROR\";\r\n }\r\n}","import { configManager } from \"../../config/ConfigManager\";\r\nimport { IConfig, ConfigSource } from \"../../../domain/interfaces/configTypes\";\r\n\r\nexport const authConfig = (configSource: ConfigSource): void => {\r\n configManager.setConfigSource(configSource);\r\n};\r\n\r\nexport const createConfigInstance = async (): Promise<IConfig> => {\r\n return configManager.getConfig() ?? (await configManager.loadConfig());\r\n};\r\n","import { BaseContainer, BaseDatabase } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { AuthController } from \"../../presentation/controller/AuthController\";\r\nimport { RequireComplete2FA } from \"../../presentation/middleware/RequireComplete2FA\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { JwtAuthService } from \"../services/JwtAuthService\";\r\nimport { TwoFactorService } from \"../services/TwoFactorService\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\n\r\nasync function createAuthContainer(database: BaseDatabase) {\r\n const container = new BaseContainer({ database });\r\n\r\n const authRepository = new AuthRepository(\r\n database.getRepository(AuthEntity)\r\n );\r\n container.registerRepository<AuthEntity>(\"AuthRepository\", authRepository);\r\n\r\n const jwtAuthService = new JwtAuthService(authRepository);\r\n container.registerService(\"JwtAuthService\", jwtAuthService);\r\n\r\n const configData = await createConfigInstance();\r\n\r\n const twoFactorService = new TwoFactorService(configData);\r\n container.registerService(\"TwoFactorService\", twoFactorService);\r\n\r\n const requireComplete2FA = new RequireComplete2FA(jwtAuthService);\r\n\r\n const loginUseCase = new LoginUseCase(authRepository, jwtAuthService);\r\n const loginAdminUseCase = new LoginAdminUseCase(\r\n authRepository\r\n );\r\n const logoutUseCase = new LogoutUseCase(authRepository);\r\n const registerUseCase = new RegisterUseCase(authRepository);\r\n const refreshTokenUseCase = new RefreshTokenUseCase(\r\n authRepository,\r\n jwtAuthService\r\n );\r\n\r\n const twoFactorSetupUseCase = new TwoFactorSetupUseCase(twoFactorService, authRepository);\r\n const twoFactorEnableUseCase = new TwoFactorEnableUseCase(twoFactorService, authRepository);\r\n const twoFactorVerifyUseCase = new TwoFactorVerifyUseCase(\r\n twoFactorService,\r\n authRepository,\r\n jwtAuthService\r\n );\r\n const twoFactorDisableUseCase = new TwoFactorDisableUseCase(twoFactorService, authRepository);\r\n\r\n container.registerService(\"LoginUseCase\", loginUseCase);\r\n container.registerService(\"LoginAdminUseCase\", loginAdminUseCase);\r\n container.registerService(\"LogoutUseCase\", logoutUseCase);\r\n container.registerService(\"RegisterUseCase\", registerUseCase);\r\n container.registerService(\"RefreshTokenUseCase\", refreshTokenUseCase);\r\n container.registerService(\"TwoFactorSetupUseCase\", twoFactorSetupUseCase);\r\n container.registerService(\"TwoFactorEnableUseCase\", twoFactorEnableUseCase);\r\n container.registerService(\"TwoFactorVerifyUseCase\", twoFactorVerifyUseCase);\r\n container.registerService(\"TwoFactorDisableUseCase\", twoFactorDisableUseCase);\r\n\r\n const authController = new AuthController(\r\n loginUseCase,\r\n loginAdminUseCase,\r\n logoutUseCase,\r\n registerUseCase,\r\n refreshTokenUseCase,\r\n twoFactorSetupUseCase,\r\n twoFactorEnableUseCase,\r\n twoFactorVerifyUseCase,\r\n twoFactorDisableUseCase\r\n );\r\n\r\n return { container, authController, requireComplete2FA };\r\n}\r\n\r\nexport { createAuthContainer };","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { jwtDecode } from \"jwt-decode\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateLoginDTO } from \"../validators/authValidation\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { IJwtPayload } from \"../../domain/interfaces/IJwtPayload\";\r\n\r\n\r\nexport class LoginUseCase implements IBaseService {\r\n\r\n constructor(\r\n private readonly repository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO): Promise<{ id: string, accessToken: string, expiresAt: number , enabled?: boolean }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n \r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n const expiresAt = jwtDecode<IJwtPayload>(accessToken).exp;\r\n\r\n if (auth.twoFactorEnabled) {\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt, enabled: auth.twoFactorEnabled };\r\n }\r\n\r\n return { id: auth.user.id, accessToken: accessToken, expiresAt: expiresAt };\r\n }\r\n}","import * as yup from \"yup\";\r\nimport { AuthEntity, UserRole } from \"cca-entities\";\r\nimport bcrypt from \"bcrypt\";\r\n\r\nimport {\r\n ForbiddenError,\r\n NotFoundError,\r\n ValidationError,\r\n} from \"../../utils/Errors\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\n\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { createConfigInstance } from \"../service/utils/configInstance\";\r\n\r\nconst schemas = {\r\n id: yup.string().uuid(\"Invalid user ID format\"),\r\n email: yup\r\n .string()\r\n .email(\"Invalid email format\")\r\n .max(255, \"Email cannot exceed 255 characters\"),\r\n name: yup\r\n .string()\r\n .required(\"Name is required\")\r\n .min(2, \"Name must be at least 2 characters long\")\r\n .max(50, \"Name cannot exceed 50 characters\")\r\n .matches(/^[a-zA-Z\\s]+$/, \"Name must only contain letters and spaces\"),\r\n password: yup\r\n .string()\r\n .required(\"Password required\")\r\n .min(8, \"Password too short\")\r\n .max(100, \"Password too long\")\r\n .matches(\r\n /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]/,\r\n \"Password must contain uppercase, lowercase, number and special character\"\r\n ),\r\n role: yup\r\n .string()\r\n .oneOf(Object.values(UserRole), \"Invalid role specified\"),\r\n};\r\n\r\nexport const validateEmail = async (\r\n email: string,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n const user = await repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\r\n \"The email address or password is incorrect. Please retry\"\r\n );\r\n }\r\n return user;\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid email format\");\r\n }\r\n};\r\n\r\nexport const validatePassword = async (password?: string): Promise<void> => {\r\n if (password) {\r\n try {\r\n await schemas.password.validate(password);\r\n } catch (error: any) {\r\n throw new ValidationError(error.message || \"Invalid password format\");\r\n }\r\n }\r\n};\r\n\r\nexport const validateEmailUniqueness = async (\r\n repository: AuthRepository,\r\n email: string,\r\n excludeUserId?: string\r\n): Promise<void> => {\r\n try {\r\n await schemas.email.validate(email?.trim().toLowerCase());\r\n\r\n const existingUser = await repository.findByEmail(email);\r\n\r\n if (!existingUser) return;\r\n if (existingUser.id === excludeUserId) return;\r\n\r\n throw new ValidationError(`Email ${email} is already in use.`);\r\n } catch (error: any) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"user email validation failed\");\r\n }\r\n};\r\n\r\nexport const validateRegisterDTO = async (\r\n auth: RegisterDTO,\r\n repository: AuthRepository\r\n): Promise<void> => {\r\n const { name, email, role, password } = auth;\r\n\r\n await Promise.all([\r\n schemas.name.validate(name),\r\n schemas.role.validate(role),\r\n validateEmailUniqueness(repository, email),\r\n validatePassword(password),\r\n ]);\r\n};\r\n\r\nexport const validateLoginDTO = async (\r\n data: LoginDTO,\r\n repository: AuthRepository\r\n): Promise<AuthEntity> => {\r\n const { email, role, password } = data;\r\n\r\n if (role) {\r\n await schemas.role.validate(role);\r\n }\r\n\r\n await schemas.password.validate(password);\r\n\r\n const auth = await validateEmail(email, repository);\r\n if (!auth || !auth.password) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const isMatch = await bcrypt.compare(password, auth.password);\r\n if (!isMatch) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return auth;\r\n};\r\n\r\nexport const validateAdminSecret = async (\r\n secretPassword?: string\r\n): Promise<void> => {\r\n if (!secretPassword) {\r\n throw new ValidationError(\"Admin password is required\");\r\n }\r\n\r\n try {\r\n const config = await createConfigInstance();\r\n\r\n if (!config.adminSecretPassword) {\r\n throw new ValidationError(\"ADMIN_SECRET_PASSWORD not found in config\");\r\n }\r\n\r\n if (parseInt(secretPassword) !== parseInt(config.adminSecretPassword)) {\r\n throw new ValidationError(\"Invalid admin password\");\r\n }\r\n } catch (error) {\r\n if (error instanceof ValidationError) {\r\n throw error;\r\n }\r\n throw new ValidationError(\"Error validating admin password\");\r\n }\r\n};\r\n","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { LoginDTO } from \"../dtos/LoginDTO\";\r\nimport { validateAdminSecret, validateLoginDTO } from \"../validators/authValidation\";\r\n\r\nexport class LoginAdminUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n\r\n constructor(\r\n repository: AuthRepository\r\n ) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(loginDTO: LoginDTO, adminPassword: string): Promise<string> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\n\r\nexport class LogoutUseCase implements IBaseService {\r\n private readonly repository: AuthRepository\r\n\r\n constructor(repository: AuthRepository) {\r\n this.repository = repository;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n async execute(authId: string): Promise<void> {\r\n try {\r\n await this.repository.logout(authId);\r\n } catch (error) {\r\n new NotFoundError(\"Auth not found\");\r\n }\r\n }\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { AdminEntity, AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private readonly SALT_ROUNDS = 10;\r\n\r\n constructor(private readonly repository: AuthRepository) {}\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo) => repo.getAll());\r\n }\r\n\r\n public async execute(\r\n email: string,\r\n name: string,\r\n password: string,\r\n role: UserRole = UserRole.GUEST,\r\n adminPassword?: string\r\n ): Promise<AuthEntity | undefined> {\r\n try {\r\n const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });\r\n\r\n const isAdminUser = await this._validateAdminRegistration(\r\n normalizedDTO.role,\r\n normalizedDTO.adminPassword\r\n );\r\n\r\n await validateRegisterDTO(normalizedDTO, this.repository);\r\n\r\n const hashedPassword = await this._hashPassword(normalizedDTO.password);\r\n const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);\r\n\r\n return this.repository.create(authEntity);\r\n } catch (error) {\r\n throw new RegistrationError(\r\n `Registration failed: ${error instanceof Error ? error.message : \"Unknown error\"}`\r\n );\r\n }\r\n }\r\n\r\n private _normalizeInput(dto: RegisterDTO): RegisterDTO {\r\n return {\r\n name: dto.name.trim(),\r\n email: dto.email.trim().toLowerCase(),\r\n password: dto.password.trim(),\r\n role: dto.role,\r\n adminPassword: dto.adminPassword?.trim()\r\n };\r\n }\r\n\r\n private async _hashPassword(password: string): Promise<string> {\r\n return bcrypt.hash(password, this.SALT_ROUNDS);\r\n }\r\n\r\n private async _validateAdminRegistration(\r\n role: UserRole,\r\n adminPassword?: string\r\n ): Promise<boolean> {\r\n if (role !== UserRole.ADMIN) return false;\r\n\r\n if (!adminPassword) {\r\n throw new UnauthorizedError(\"Admin password is required for admin registration\");\r\n }\r\n\r\n await validateAdminSecret(adminPassword);\r\n return true;\r\n }\r\n\r\n private _buildMappedAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): AuthEntity {\r\n const authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userOrAdminEntity = isAdmin\r\n ? mapper.map(dto, RegisterDTO, AdminEntity)\r\n : mapper.map(dto, RegisterDTO, UserEntity);\r\n\r\n userOrAdminEntity.updatedAt = undefined as unknown as Date;\r\n\r\n if (isAdmin) {\r\n authEntity.admin = userOrAdminEntity;\r\n } else {\r\n authEntity.user = userOrAdminEntity;\r\n }\r\n\r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n\r\n return authEntity;\r\n }\r\n}\r\n","import { createMapper } from '@automapper/core';\r\nimport { classes } from '@automapper/classes';\r\n\r\nimport { createUserMappings } from '../createUserMappings';\r\n\r\nexport const mapper = createMapper({\r\n strategyInitializer: classes(),\r\n});\r\n\r\ncreateUserMappings(mapper);\r\n","import { Mapper, createMap, forMember, mapFrom } from '@automapper/core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { RegisterDTO } from '../dtos/RegisterDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\n\r\nexport function createUserMappings(mapper: Mapper): void {\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AuthEntity,\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.password, mapFrom(src => src.password)),\r\n forMember(dest => dest.role, mapFrom(src => src.role)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n UserEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n RegisterDTO,\r\n AdminEntity,\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n createMap(\r\n mapper,\r\n UserEntity,\r\n UserDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)),\r\n forMember(dest => dest.profileImageUrl, mapFrom(src => getProfileImageUrl(src))));\r\n\r\n\r\n createMap(\r\n mapper,\r\n AdminEntity,\r\n AdminDTO,\r\n forMember(dest => dest.id, mapFrom(src => src.id)),\r\n forMember(dest => dest.name, mapFrom(src => src.name)),\r\n forMember(dest => dest.email, mapFrom(src => src.email)));\r\n\r\n const getProfileImageUrl = (src: UserEntity): string | undefined => {\r\n const image = src.images?.[0];\r\n if (!image) return undefined;\r\n return image.mdUrl ?? image.smUrl ?? image.lgUrl ?? image.thumbUrl ?? image.originalUrl ?? image.xlUrl;\r\n };\r\n}","import { UserRole } from \"cca-entities\";\r\n\r\nexport class RegisterDTO {\r\n email!: string;\r\n name!: string;\r\n password!: string;\r\n role!: UserRole;\r\n adminPassword?: string;\r\n}\r\n","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class UserDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n @AutoMap()\r\n profileImageUrl?: string;\r\n}","import { AutoMap } from \"@automapper/classes\";\r\nimport { UserRole } from \"cca-entities\";\r\n\r\nexport class AdminDTO {\r\n @AutoMap()\r\n id!: string;\r\n\r\n @AutoMap()\r\n name!: string;\r\n\r\n @AutoMap()\r\n email!: string;\r\n\r\n @AutoMap()\r\n role!: UserRole;\r\n\r\n adminPassword!: string;\r\n}","import { IBaseService, validateRepository } from \"cca-core\";\r\nimport { JwtAuthService } from \"../../infrastructure/services/JwtAuthService\";\r\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { ITokenPair } from \"../../domain/interfaces/ITokenPair\";\r\n\r\nexport class RefreshTokenUseCase implements IBaseService {\r\n private readonly repository: AuthRepository;\r\n private readonly service: JwtAuthService;\r\n\r\n constructor(repository: AuthRepository, service: JwtAuthService) {\r\n this.repository = repository;\r\n this.service = service;\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n await validateRepository(this.repository, (repo: AuthRepository) => repo.getAll());\r\n }\r\n\r\n public async execute(refreshToken: string): Promise<ITokenPair | null> {\r\n try {\r\n const decoded = await this.service.verifyRefreshToken(refreshToken);\r\n\r\n if (!decoded.userId) {\r\n return null;\r\n }\r\n\r\n let authEntity = await this.repository.findByUseAdminId(decoded.userId);\r\n\r\n if (!authEntity) {\r\n authEntity = await this.repository.findByUseAdminId(decoded.userId, true);\r\n }\r\n\r\n if (!authEntity) {\r\n return null;\r\n }\r\n\r\n const user = authEntity.role === \"admin\" ? authEntity.admin : authEntity.user;\r\n\r\n const accessToken = this.service.generateAccessToken(user, authEntity.role);\r\n const newRefreshToken = this.service.generateRefreshToken(user);\r\n\r\n await this.repository.update(authEntity.id, {\r\n refreshToken: newRefreshToken\r\n });\r\n\r\n return {\r\n accessToken,\r\n refreshToken: newRefreshToken\r\n };\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n}","import { IBaseService } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorSetupResponse } from '../../domain/interfaces/ITwoFactorSetupResponse';\r\n\r\nimport { ForbiddenError, TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorSetupUseCase implements IBaseService {\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n\r\n await Promise.all([\r\n this.twoFactorService.initialize()\r\n ]);\r\n\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string): Promise<ITwoFactorSetupResponse> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const user = await this.authRepository.findByUserId(userId);\r\n\r\n if (!user) {\r\n throw new ForbiddenError('User not found');\r\n }\r\n\r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n\r\n const { secret, otpAuthUrl } = this.twoFactorService.generateSecret(user.email);\r\n const qrCodeUrl = await this.twoFactorService.generateQRCode(otpAuthUrl);\r\n\r\n await this.authRepository.updateTwoFactorSecret(userId, secret);\r\n\r\n return { qrCodeUrl };\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorEnableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n \r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n \r\n this.isInitialized = true;\r\n }\r\n\r\n async execute( dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token, userId } = dto;\r\n \r\n if (!token) {\r\n throw new TwoFactorError('Token is required');\r\n }\r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret) {\r\n throw new TwoFactorError('Please set up two-factor authentication first');\r\n }\r\n \r\n if (user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is already enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.enableTwoFactor(user);\r\n }\r\n}","import { IBaseService, validateRepository } from 'cca-core';\r\nimport { AdminEntity, AuthEntity, UserEntity } from 'cca-entities';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\nimport { ITwoFactorVerify } from '../../domain/interfaces/ITwoFactorVerify';\r\nimport { ITokenPair } from '../../domain/interfaces/ITokenPair';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\nimport { AdminDTO } from '../dtos/AdminDTO';\r\nimport { UserDTO } from '../dtos/UserDTO';\r\nimport { mapper } from '../mappers/utils/mapper';\r\n\r\nexport class TwoFactorVerifyUseCase implements IBaseService {\r\n private isInitialized = false;\r\n\r\n constructor(\r\n private readonly twoFactorService: TwoFactorService,\r\n private readonly authRepository: AuthRepository,\r\n private readonly jwtService: JwtAuthService\r\n ) { }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n this.jwtService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n this.isInitialized = true;\r\n }\r\n\r\n public async execute(dto: ITwoFactorVerify): Promise<{ token: string; refreshToken: string; data?: AdminDTO | UserDTO } | null> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n\r\n const { userId, token } = dto;\r\n if (!userId || !token) {\r\n throw new TwoFactorError('User ID and token are required.');\r\n }\r\n\r\n const auth: AuthEntity | null = await this.authRepository.findByUserId(userId);\r\n if (!auth || !auth.twoFactorSecret || !auth.twoFactorEnabled) {\r\n throw new TwoFactorError('Invalid request.');\r\n }\r\n\r\n const isValid = this.twoFactorService.verifyToken(token, auth.twoFactorSecret);\r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code.');\r\n }\r\n\r\n const tokenPair: ITokenPair = this.generateTokens(auth);\r\n await this.updateUserStatus(auth);\r\n await this.updateUserRefreshToken(auth, tokenPair.refreshToken);\r\n\r\n if (auth.admin) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapAdminToDTO(auth.admin)\r\n };\r\n }\r\n\r\n if (auth.user) {\r\n return {\r\n token: tokenPair.accessToken,\r\n refreshToken: tokenPair.refreshToken,\r\n data: this.mapUserToDTO(auth.user)\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private mapAdminToDTO(admin: AdminEntity): AdminDTO {\r\n return mapper.map(admin, AdminEntity, AdminDTO);\r\n }\r\n\r\n private mapUserToDTO(user: UserEntity): UserDTO {\r\n return mapper.map(user, UserEntity, UserDTO);\r\n }\r\n\r\n private async updateUserStatus(auth: AuthEntity): Promise<void> {\r\n auth.user.lastLoginAt = new Date();\r\n auth.user.isActive = true;\r\n await this.authRepository.update(auth.id, auth);\r\n }\r\n\r\n private async updateUserRefreshToken(auth: AuthEntity, refreshToken: string): Promise<void> {\r\n auth.refreshToken = refreshToken;\r\n await this.authRepository.update(auth.id, { refreshToken });\r\n }\r\n\r\n private generateTokens(auth: AuthEntity): ITokenPair {\r\n return {\r\n accessToken: this.jwtService.generateAccessToken(auth.user, auth.role),\r\n refreshToken: this.jwtService.generateRefreshToken(auth.user)\r\n };\r\n }\r\n}\r\n","import { IBaseService, validateRepository } from 'cca-core';\r\n\r\nimport { TwoFactorService } from '../../infrastructure/services/TwoFactorService';\r\nimport { AuthRepository } from '../../infrastructure/repository/AuthRepository';\r\nimport { ITwoFactorEnable } from '../../domain/interfaces/ITwoFactorEnable';\r\n\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorDisableUseCase implements IBaseService{\r\n private twoFactorService: TwoFactorService;\r\n private authRepository: AuthRepository;\r\n private isInitialized = false;\r\n\r\n constructor(twoFactorService: TwoFactorService, authRepository: AuthRepository) {\r\n this.twoFactorService = twoFactorService;\r\n this.authRepository = authRepository;\r\n }\r\n async initialize(): Promise<void> {\r\n if (this.isInitialized) return;\r\n \r\n await Promise.all([\r\n this.twoFactorService.initialize(),\r\n validateRepository(this.authRepository, repo => repo.getAll())\r\n ]);\r\n4\r\n this.isInitialized = true;\r\n }\r\n\r\n async execute(userId: string, dto: ITwoFactorEnable): Promise<void> {\r\n if (!this.isInitialized) {\r\n await this.initialize();\r\n }\r\n \r\n const { token } = dto; \r\n \r\n const user = await this.authRepository.findByUserId(userId); \r\n \r\n if (!user || !user.twoFactorSecret || !user.twoFactorEnabled) {\r\n throw new TwoFactorError('Two-factor authentication is not enabled');\r\n }\r\n \r\n const isValid = this.twoFactorService.verifyToken(token, user.twoFactorSecret);\r\n \r\n if (!isValid) {\r\n throw new TwoFactorError('Invalid verification code');\r\n }\r\n \r\n await this.authRepository.disableTwoFactor(user);\r\n }\r\n}","import { NextFunction, Request, Response } from \"express\";\r\n\r\nimport { LoginDTO } from \"../../application/dtos/LoginDTO\";\r\nimport { RegisterDTO } from \"../../application/dtos/RegisterDTO\";\r\n\r\nimport { RegisterUseCase } from \"../../application/useCase/RegisterUseCase\";\r\nimport { LoginUseCase } from \"../../application/useCase/LoginUseCase\";\r\nimport { LoginAdminUseCase } from \"../../application/useCase/LoginAdminUseCase\";\r\nimport { LogoutUseCase } from \"../../application/useCase/LogoutUseCase\";\r\nimport { RefreshTokenUseCase } from \"../../application/useCase/RefreshTokenUseCase\";\r\nimport { TwoFactorSetupUseCase } from \"../../application/useCase/TwoFactorSetupUseCase\";\r\nimport { TwoFactorEnableUseCase } from \"../../application/useCase/TwoFactorEnableUseCase\";\r\nimport { TwoFactorVerifyUseCase } from \"../../application/useCase/TwoFactorVerifyUseCase\";\r\nimport { TwoFactorDisableUseCase } from \"../../application/useCase/TwoFactorDisableUseCase\";\r\n\r\nimport { IRefreshTokenRequest } from \"../../domain/interfaces/IRefreshTokenRequest\";\r\nimport { ITwoFactorEnable } from \"../../domain/interfaces/ITwoFactorEnable\";\r\nimport { ITwoFactorVerify } from \"../../domain/interfaces/ITwoFactorVerify\";\r\nimport { ForbiddenError } from \"../../utils/Errors\";\r\n\r\nexport class AuthController {\r\n private readonly loginUseCase: LoginUseCase;\r\n private readonly adminLoginUseCase: LoginAdminUseCase;\r\n private readonly logoutUseCase: LogoutUseCase;\r\n private readonly registerUseCase: RegisterUseCase;\r\n private readonly refreshTokenUseCase: RefreshTokenUseCase;\r\n\r\n private twoFactorSetupUseCase: TwoFactorSetupUseCase;\r\n private twoFactorEnableUseCase: TwoFactorEnableUseCase;\r\n private twoFactorVerifyUseCase: TwoFactorVerifyUseCase;\r\n private twoFactorDisableUseCase: TwoFactorDisableUseCase;\r\n\r\n constructor(\r\n loginUseCase: LoginUseCase,\r\n adminLoginUseCase: LoginAdminUseCase,\r\n logoutUseCase: LogoutUseCase,\r\n registerUseCase: RegisterUseCase,\r\n refreshTokenUseCase: RefreshTokenUseCase,\r\n twoFactorSetupUseCase: TwoFactorSetupUseCase,\r\n twoFactorEnableUseCase: TwoFactorEnableUseCase,\r\n twoFactorVerifyUseCase: TwoFactorVerifyUseCase,\r\n twoFactorDisableUseCase: TwoFactorDisableUseCase\r\n ) {\r\n this.loginUseCase = loginUseCase;\r\n this.adminLoginUseCase = adminLoginUseCase;\r\n this.logoutUseCase = logoutUseCase;\r\n this.registerUseCase = registerUseCase;\r\n this.refreshTokenUseCase = refreshTokenUseCase;\r\n this.twoFactorSetupUseCase = twoFactorSetupUseCase;\r\n this.twoFactorEnableUseCase = twoFactorEnableUseCase;\r\n this.twoFactorVerifyUseCase = twoFactorVerifyUseCase;\r\n this.twoFactorDisableUseCase = twoFactorDisableUseCase;\r\n }\r\n\r\n login = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const loginDTO: LoginDTO = req.body;\r\n\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n if (result.enabled) {\r\n return res.status(201).json({\r\n status: \"pending\",\r\n message: \"Enter 2FA code\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n }\r\n\r\n res.status(200).json({\r\n status: \"success\",\r\n message: \"Login successful\",\r\n data: {\r\n accessToken: result.accessToken,\r\n userId: result.id,\r\n expiresAt: result.expiresAt\r\n }\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n adminLogin = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n if (!adminPassword) {\r\n throw new ForbiddenError(\"Admin password is required\");\r\n }\r\n const result = await this.adminLoginUseCase.execute(loginDTO, adminPassword);\r\n res.status(201).json(result);\r\n }\r\n catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n logout = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n await this.logoutUseCase.execute(req.body.id);\r\n res.status(200).json({ message: 'Logged out successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n register = async (\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> => {\r\n try {\r\n const { email, name, password, role, adminPassword }: RegisterDTO = req.body;\r\n\r\n await this.registerUseCase.execute(email, name, password, role, adminPassword);\r\n res.status(200).json({ status: \"success\" });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n refreshToken = async (req: Request, res: Response) => {\r\n const { refreshToken }: IRefreshTokenRequest = req.body;\r\n\r\n const result = await this.refreshTokenUseCase.execute(refreshToken);\r\n res.json(result);\r\n };\r\n\r\n setup2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n if (!req.auth || !req.auth.id) {\r\n throw new ForbiddenError(\"User authentication required\");\r\n }\r\n const result = await this.twoFactorSetupUseCase.execute(req.auth.id);\r\n res.status(200).json(result);\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n enable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorEnable = req.body;\r\n dto.userId = req.auth?.id;\r\n\r\n await this.twoFactorEnableUseCase.execute(dto);\r\n res.status(200).json({ message: 'Two-factor authentication has been enabled successfully' });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n verify2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const dto: ITwoFactorVerify = req.body;\r\n\r\n const result = await this.twoFactorVerifyUseCase.execute(dto);\r\n res.status(200).json({\r\n message: 'Two-factor authentication successful',\r\n ...result\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n\r\n disable2FA = async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const userId = req.auth!.id;\r\n const dto: ITwoFactorEnable = req.body;\r\n\r\n await this.twoFactorDisableUseCase.execute(userId, dto);\r\n res.status(200).json({\r\n status: \"success\",\r\n message: 'Two-factor authentication has been disabled successfully'\r\n });\r\n } catch (error) {\r\n next(error);\r\n }\r\n };\r\n}\r\n","import { NextFunction, Request, Response } from 'express';\r\nimport { JwtAuthService } from '../../infrastructure/services/JwtAuthService';\r\n\r\nexport class RequireComplete2FA {\r\n private readonly jwtService: JwtAuthService;\r\n\r\n constructor(jwtService: JwtAuthService) {\r\n this.jwtService = jwtService;\r\n }\r\n\r\n public async execute(req: Request, res: Response, next: NextFunction) {\r\n try {\r\n const token = req.headers.authorization?.split(' ')[1];\r\n\r\n if (!token) {\r\n return res.status(401).json({ message: 'Authentication required' });\r\n }\r\n\r\n const decoded = await this.jwtService.verifyAccessToken(token);\r\n\r\n if (!decoded.twoFactorAuthenticated) {\r\n return res.status(403).json({\r\n message: 'Two-factor authentication required',\r\n code: 'REQUIRE_2FA',\r\n userId: decoded.id\r\n });\r\n }\r\n\r\n req.auth = { ...decoded, twoFactorAuthenticated: true };\r\n next();\r\n } catch (error) {\r\n return res.status(401).json({ message: 'Invalid or expired token' });\r\n }\r\n }\r\n}","import { BaseRepository, IExtendedBaseRepository } from \"cca-core\";\r\nimport { AuthEntity } from \"cca-entities\";\r\nimport { Repository } from \"typeorm\";\r\nimport { NotFoundError } from \"../../utils/Errors\";\r\n\r\nexport class AuthRepository\r\n extends BaseRepository<AuthEntity>\r\n implements IExtendedBaseRepository<AuthEntity> {\r\n constructor(repository: Repository<AuthEntity>) {\r\n super(repository);\r\n }\r\n\r\n async findByEmail(email: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.password\")\r\n .where(\"auth.email = :email\", { email });\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async create(entity: Omit<AuthEntity, \"createdAt\">): Promise<AuthEntity> {\r\n return super.create(entity);\r\n }\r\n\r\n async findByUserId(userId: string): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .leftJoinAndSelect(\"auth.user\", \"user\")\r\n .addSelect(\"auth.twoFactorSecret\")\r\n .where(\"user.id = :userId\", { userId });\r\n\r\n return await query.getOne();;\r\n }\r\n\r\n async findByUseAdminId(userId: string, isAdmin: boolean = false): Promise<AuthEntity | null> {\r\n const query = this.repository\r\n .createQueryBuilder(\"auth\")\r\n .addSelect(\"auth.twoFactorSecret\");\r\n\r\n if (isAdmin) {\r\n query.leftJoinAndSelect(\"auth.admin\", \"admin\")\r\n .where(\"admin.id = :userId\", { userId });\r\n } else {\r\n query.leftJoinAndSelect(\"auth.user\", \"user\")\r\n .where(\"user.id = :userId\", { userId });\r\n }\r\n\r\n return await query.getOne();\r\n }\r\n\r\n async logout(userId: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.refreshToken = \"\";\r\n auth.user.isActive = false;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async updateTwoFactorSecret(userId: string, secret: string): Promise<void> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n auth.twoFactorSecret = secret;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async enableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = true;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async disableTwoFactor(auth: AuthEntity): Promise<void> {\r\n\r\n auth.twoFactorEnabled = false;\r\n auth.twoFactorSecret = null;\r\n\r\n await this.update(auth.id, auth);\r\n }\r\n\r\n async isTwoFactorEnabled(userId: string): Promise<boolean> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return !!auth.twoFactorEnabled;\r\n }\r\n\r\n async getTwoFactorSecret(userId: string): Promise<string | null> {\r\n const auth = await this.findByUserId(userId);\r\n if (!auth) {\r\n throw new NotFoundError(\"Auth not found\");\r\n }\r\n\r\n return auth.twoFactorSecret;\r\n }\r\n}\r\n","import * as jwt from \"jsonwebtoken\";\r\nimport { Secret, SignOptions } from \"jsonwebtoken\";\r\nimport * as bcrypt from \"bcrypt\";\r\nimport { IBaseService, validateRepository } from \"cca-core\";\r\nimport { AuthEntity, UserEntity, UserRole } from \"cca-entities\";\r\n\r\nimport { IJwtConfig } from \"../../domain/interfaces/IJwtConfig\";\r\nimport { IAuthService } from \"../../domain/interfaces/IAuthService\";\r\nimport { IDecodedToken } from \"../../domain/interfaces/IDecodedToken\";\r\n\r\nimport {\r\n ForbiddenError,\r\n JwtError,\r\n NotFoundError,\r\n UnauthorizedError,\r\n} from \"../../utils/Errors\";\r\n\r\nimport { AuthRepository } from \"../repository/AuthRepository\";\r\nimport { createConfigInstance } from \"../../application/service/utils/configInstance\";\r\nimport { log } from \"console\";\r\n\r\nexport class JwtAuthService implements IBaseService, IAuthService {\r\n private jwtConfig: IJwtConfig | undefined;\r\n\r\n constructor(private readonly repository: AuthRepository, config?: IJwtConfig) {\r\n this.loadConfig(config);\r\n }\r\n\r\n private async loadConfig(config?: IJwtConfig) {\r\n const configData = await createConfigInstance();\r\n\r\n this.jwtConfig = {\r\n accessTokenSecret: configData.accessTokenSecret,\r\n refreshTokenSecret: configData.refreshTokenSecret,\r\n accessTokenExpiry: parseInt(configData.accessTokenExpiry, 10),\r\n refreshTokenExpiry: parseInt(configData.refreshTokenExpiry, 10),\r\n ...config,\r\n };\r\n\r\n this.validateConfiguration();\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n await validateRepository(this.repository, repo => repo.getAll());\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.jwtConfig?.accessTokenSecret || !this.jwtConfig?.refreshTokenSecret) {\r\n throw new JwtError(\"JWT secrets required in config\");\r\n }\r\n }\r\n\r\n async validateUser(email: string, password: string): Promise<AuthEntity | null> {\r\n const user = await this.repository.findByEmail(email);\r\n if (!user) {\r\n throw new NotFoundError(\"Invalid credentials\");\r\n }\r\n\r\n const validPassword = await bcrypt.compare(password, user.password);\r\n if (!validPassword) {\r\n throw new ForbiddenError(\"Invalid credentials\");\r\n }\r\n\r\n return user;\r\n }\r\n\r\n private verifyJwtConfig() {\r\n if (!this.jwtConfig) throw new JwtError(\"JWT config not loaded\");\r\n }\r\n\r\n generateAccessToken(user: UserEntity, role : UserRole): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id, email: user.email, role: role },\r\n this.jwtConfig!.accessTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.accessTokenExpiry }\r\n );\r\n }\r\n\r\n generateRefreshToken(user: UserEntity): string {\r\n this.verifyJwtConfig();\r\n return jwt.sign(\r\n { userId: user.id },\r\n this.jwtConfig!.refreshTokenSecret as Secret,\r\n { expiresIn: this.jwtConfig!.refreshTokenExpiry }\r\n );\r\n }\r\n\r\n async verifyToken(token: string, secret: string): Promise<IDecodedToken> {\r\n try {\r\n console.log(\"Verifying token:\", token);\r\n console.log(\"Using secret:\", secret);\r\n \r\n return jwt.verify(token, secret) as IDecodedToken;\r\n } catch(error) {\r\n console.error(\"Error verifying token:\", error);\r\n throw new UnauthorizedError();\r\n }\r\n }\r\n\r\n async verifyAccessToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.accessTokenSecret);\r\n }\r\n\r\n async verifyRefreshToken(token: string): Promise<IDecodedToken> {\r\n this.verifyJwtConfig();\r\n return this.verifyToken(token, this.jwtConfig!.refreshTokenSecret);\r\n }\r\n}\r\n","import * as speakeasy from 'speakeasy';\r\nimport * as QRCode from 'qrcode';\r\nimport { IBaseService } from 'cca-core';\r\n\r\nimport { IConfig } from '../../domain/interfaces/configTypes';\r\nimport { TwoFactorError } from '../../utils/Errors';\r\n\r\nexport class TwoFactorService implements IBaseService {\r\n private readonly config: IConfig;\r\n private initialized: boolean = false;\r\n private readonly twoFactorConfig: {\r\n tokenWindow: number;\r\n secretLength: number;\r\n qrCodeOptions: QRCode.QRCodeToDataURLOptions;\r\n };\r\n\r\n constructor(config: IConfig) {\r\n this.config = config;\r\n \r\n this.twoFactorConfig = {\r\n tokenWindow: parseInt(config.tokenWindow) ?? 1,\r\n secretLength: parseInt(config.secretLength) ?? 20,\r\n qrCodeOptions: {\r\n errorCorrectionLevel: 'M',\r\n margin: 4,\r\n scale: 4,\r\n color: {\r\n dark: '#000000',\r\n light: '#ffffff'\r\n }\r\n }\r\n };\r\n }\r\n\r\n public async initialize(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n this.validateConfiguration();\r\n this.initialized = true;\r\n } catch (error) {\r\n console.error('TwoFactorService initialization failed:', error);\r\n throw new TwoFactorError('Failed to initialize TwoFactorService');\r\n }\r\n }\r\n\r\n private validateConfiguration(): void {\r\n if (!this.config.app_name?.trim()) {\r\n throw new TwoFactorError('Application name (appName) is required in configuration');\r\n }\r\n\r\n if (this.twoFactorConfig.secretLength < 16) {\r\n throw new TwoFactorError('Secret length must be at least 16 characters');\r\n }\r\n\r\n if (this.twoFactorConfig.tokenWindow < 0 || this.twoFactorConfig.tokenWindow > 5) {\r\n throw new TwoFactorError('Token verification window must be between 0 and 5');\r\n }\r\n }\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new TwoFactorError('TwoFactorService must be initialized before use');\r\n }\r\n }\r\n\r\n public generateSecret(email: string): { secret: string; otpAuthUrl: string } {\r\n this.ensureInitialized();\r\n\r\n try {\r\n const secretObj = speakeasy.generateSecret({\r\n length: this.twoFactorConfig.secretLength,\r\n name: `${this.config.app_name}:${email}`,\r\n issuer: this.config.app_name\r\n });\r\n \r\n return {\r\n secret: secretObj.base32,\r\n otpAuthUrl: secretObj.otpauth_url || ''\r\n };\r\n } catch (error) {\r\n console.error('Error generating 2FA secret:', error);\r\n throw new TwoFactorError('Failed to generate 2FA secret');\r\n }\r\n }\r\n\r\n public async generateQRCode(otpAuthUrl: string): Promise<string> {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return await QRCode.toDataURL(otpAuthUrl, this.twoFactorConfig.qrCodeOptions);\r\n } catch (error) {\r\n console.error('QR code generation failed:', error);\r\n throw new TwoFactorError('Failed to generate QR code');\r\n }\r\n }\r\n\r\n public verifyToken(token: string, secret: string): boolean {\r\n this.ensureInitialized();\r\n\r\n try {\r\n return speakeasy.totp.verify({\r\n secret,\r\n encoding: 'base32',\r\n token,\r\n window: this.twoFactorConfig.tokenWindow\r\n });\r\n } catch (error) {\r\n console.error('Token verification failed:', error);\r\n throw new TwoFactorError('Failed to verify 2FA token');\r\n }\r\n }\r\n}"],"mappings":"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","names":["AuthEntity","validateRepository","validateRepository","validateRepository","validateRepository","validateRepository","bcrypt","AdminEntity","AuthEntity","UserEntity","UserRole","AuthEntity","AutoMap","AutoMap","mapper","AuthEntity","validateRepository","UserRole","AuthEntity","AdminEntity","UserEntity","validateRepository","validateRepository","validateRepository","validateRepository","validateRepository","AdminEntity","UserEntity","validateRepository","AdminEntity","UserEntity","validateRepository","validateRepository","bcrypt","validateRepository","validateRepository","AuthEntity"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cca-auth-module",
3
- "version": "0.1.74",
3
+ "version": "0.1.76",
4
4
  "description": "A TypeScript project using pnpm as the package manager.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",