cca-auth-module 0.1.66 → 0.1.67

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.
@@ -6,5 +6,4 @@ export declare class LoginAdminUseCase implements IBaseService {
6
6
  constructor(repository: AuthRepository);
7
7
  initialize(): Promise<void>;
8
8
  execute(loginDTO: LoginDTO, adminPassword: string): Promise<string>;
9
- private validateLogin;
10
9
  }
@@ -11,5 +11,4 @@ export declare class LoginUseCase implements IBaseService {
11
11
  id: string;
12
12
  accessToken: string;
13
13
  }>;
14
- private validateLogin;
15
14
  }
@@ -3,12 +3,12 @@ import { AuthEntity, UserRole } from "cca-entities";
3
3
  import { AuthRepository } from "../../infrastructure/repository/AuthRepository";
4
4
  export declare class RegisterUseCase implements IBaseService {
5
5
  private readonly repository;
6
- private static readonly SALT_ROUNDS;
6
+ private readonly SALT_ROUNDS;
7
7
  constructor(repository: AuthRepository);
8
8
  initialize(): Promise<void>;
9
9
  execute(email: string, name: string, password: string, role?: UserRole, adminPassword?: string): Promise<AuthEntity | undefined>;
10
10
  private _normalizeInput;
11
11
  private _hashPassword;
12
12
  private _validateAdminRegistration;
13
- private _buildAuthEntity;
13
+ private _buildMappedAuthEntity;
14
14
  }
package/dist/index.d.mts CHANGED
@@ -35,14 +35,14 @@ declare class AuthRepository extends BaseRepository<AuthEntity> implements IExte
35
35
 
36
36
  declare class RegisterUseCase implements IBaseService {
37
37
  private readonly repository;
38
- private static readonly SALT_ROUNDS;
38
+ private readonly SALT_ROUNDS;
39
39
  constructor(repository: AuthRepository);
40
40
  initialize(): Promise<void>;
41
41
  execute(email: string, name: string, password: string, role?: UserRole, adminPassword?: string): Promise<AuthEntity | undefined>;
42
42
  private _normalizeInput;
43
43
  private _hashPassword;
44
44
  private _validateAdminRegistration;
45
- private _buildAuthEntity;
45
+ private _buildMappedAuthEntity;
46
46
  }
47
47
 
48
48
  declare class LoginDTO {
@@ -98,7 +98,6 @@ declare class LoginUseCase implements IBaseService {
98
98
  id: string;
99
99
  accessToken: string;
100
100
  }>;
101
- private validateLogin;
102
101
  }
103
102
 
104
103
  declare class LoginAdminUseCase implements IBaseService {
@@ -106,7 +105,6 @@ declare class LoginAdminUseCase implements IBaseService {
106
105
  constructor(repository: AuthRepository);
107
106
  initialize(): Promise<void>;
108
107
  execute(loginDTO: LoginDTO, adminPassword: string): Promise<string>;
109
- private validateLogin;
110
108
  }
111
109
 
112
110
  declare class LogoutUseCase implements IBaseService {
package/dist/index.d.ts CHANGED
@@ -35,14 +35,14 @@ declare class AuthRepository extends BaseRepository<AuthEntity> implements IExte
35
35
 
36
36
  declare class RegisterUseCase implements IBaseService {
37
37
  private readonly repository;
38
- private static readonly SALT_ROUNDS;
38
+ private readonly SALT_ROUNDS;
39
39
  constructor(repository: AuthRepository);
40
40
  initialize(): Promise<void>;
41
41
  execute(email: string, name: string, password: string, role?: UserRole, adminPassword?: string): Promise<AuthEntity | undefined>;
42
42
  private _normalizeInput;
43
43
  private _hashPassword;
44
44
  private _validateAdminRegistration;
45
- private _buildAuthEntity;
45
+ private _buildMappedAuthEntity;
46
46
  }
47
47
 
48
48
  declare class LoginDTO {
@@ -98,7 +98,6 @@ declare class LoginUseCase implements IBaseService {
98
98
  id: string;
99
99
  accessToken: string;
100
100
  }>;
101
- private validateLogin;
102
101
  }
103
102
 
104
103
  declare class LoginAdminUseCase implements IBaseService {
@@ -106,7 +105,6 @@ declare class LoginAdminUseCase implements IBaseService {
106
105
  constructor(repository: AuthRepository);
107
106
  initialize(): Promise<void>;
108
107
  execute(loginDTO: LoginDTO, adminPassword: string): Promise<string>;
109
- private validateLogin;
110
108
  }
111
109
 
112
110
  declare class LogoutUseCase implements IBaseService {
package/dist/index.js CHANGED
@@ -181,7 +181,7 @@ var schemas = {
181
181
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
182
182
  "Password must contain uppercase, lowercase, number and special character"
183
183
  ),
184
- role: yup.string().required("Role is required").oneOf(Object.values(import_cca_entities.UserRole), "Invalid role specified")
184
+ role: yup.string().oneOf(Object.values(import_cca_entities.UserRole), "Invalid role specified")
185
185
  };
186
186
  var validateEmail = /* @__PURE__ */ __name(async (email, repository) => {
187
187
  try {
@@ -231,7 +231,10 @@ var validateRegisterDTO = /* @__PURE__ */ __name(async (auth, repository) => {
231
231
  }, "validateRegisterDTO");
232
232
  var validateLoginDTO = /* @__PURE__ */ __name(async (data, repository) => {
233
233
  const { email, role, password } = data;
234
- await Promise.all([schemas.role.validate(role), schemas.password.validate(password)]);
234
+ if (role) {
235
+ await schemas.role.validate(role);
236
+ }
237
+ await schemas.password.validate(password);
235
238
  const auth = await validateEmail(email, repository);
236
239
  if (!auth || !auth.password) {
237
240
  throw new NotFoundError("Invalid credentials");
@@ -272,14 +275,10 @@ var _LoginUseCase = class _LoginUseCase {
272
275
  await (0, import_cca_core.validateRepository)(this.repository, (repo) => repo.getAll());
273
276
  }
274
277
  async execute(loginDTO) {
275
- const auth = await this.validateLogin(loginDTO);
278
+ const auth = await validateLoginDTO(loginDTO, this.repository);
276
279
  const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);
277
280
  return { id: auth.user.id, accessToken };
278
281
  }
279
- async validateLogin(loginDTO) {
280
- const auth = await validateLoginDTO(loginDTO, this.repository);
281
- return auth;
282
- }
283
282
  };
284
283
  __name(_LoginUseCase, "LoginUseCase");
285
284
  var LoginUseCase = _LoginUseCase;
@@ -294,13 +293,9 @@ var _LoginAdminUseCase = class _LoginAdminUseCase {
294
293
  await (0, import_cca_core2.validateRepository)(this.repository, (repo) => repo.getAll());
295
294
  }
296
295
  async execute(loginDTO, adminPassword) {
297
- const auth = await this.validateLogin(loginDTO, adminPassword);
298
- return auth.user.id;
299
- }
300
- async validateLogin(loginDTO, adminPassword) {
301
296
  const auth = await validateLoginDTO(loginDTO, this.repository);
302
297
  await validateAdminSecret(adminPassword);
303
- return auth;
298
+ return auth.user.id;
304
299
  }
305
300
  };
306
301
  __name(_LoginAdminUseCase, "LoginAdminUseCase");
@@ -436,26 +431,21 @@ createUserMappings(mapper);
436
431
  var _RegisterUseCase = class _RegisterUseCase {
437
432
  constructor(repository) {
438
433
  this.repository = repository;
434
+ this.SALT_ROUNDS = 10;
439
435
  }
440
436
  async initialize() {
441
437
  await (0, import_cca_core4.validateRepository)(this.repository, (repo) => repo.getAll());
442
438
  }
443
439
  async execute(email, name, password, role = import_cca_entities3.UserRole.GUEST, adminPassword) {
444
440
  try {
445
- const normalizedDTO = this._normalizeInput({
446
- email,
447
- name,
448
- password,
449
- role,
450
- adminPassword
451
- });
441
+ const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });
452
442
  const isAdminUser = await this._validateAdminRegistration(
453
443
  normalizedDTO.role,
454
444
  normalizedDTO.adminPassword
455
445
  );
456
446
  await validateRegisterDTO(normalizedDTO, this.repository);
457
447
  const hashedPassword = await this._hashPassword(normalizedDTO.password);
458
- const authEntity = await this._buildAuthEntity(normalizedDTO, hashedPassword, isAdminUser);
448
+ const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);
459
449
  return this.repository.create(authEntity);
460
450
  } catch (error) {
461
451
  throw new RegistrationError(
@@ -467,36 +457,30 @@ var _RegisterUseCase = class _RegisterUseCase {
467
457
  return {
468
458
  name: dto.name.trim(),
469
459
  email: dto.email.trim().toLowerCase(),
470
- role: dto.role,
471
460
  password: dto.password.trim(),
461
+ role: dto.role,
472
462
  adminPassword: dto.adminPassword?.trim()
473
463
  };
474
464
  }
475
465
  async _hashPassword(password) {
476
- return bcrypt2.hash(password, _RegisterUseCase.SALT_ROUNDS);
466
+ return bcrypt2.hash(password, this.SALT_ROUNDS);
477
467
  }
478
468
  async _validateAdminRegistration(role, adminPassword) {
479
- if (role !== import_cca_entities3.UserRole.ADMIN) {
480
- return false;
481
- }
469
+ if (role !== import_cca_entities3.UserRole.ADMIN) return false;
482
470
  if (!adminPassword) {
483
471
  throw new UnauthorizedError("Admin password is required for admin registration");
484
472
  }
485
473
  await validateAdminSecret(adminPassword);
486
474
  return true;
487
475
  }
488
- async _buildAuthEntity(dto, hashedPassword, isAdmin) {
489
- let authEntity;
476
+ _buildMappedAuthEntity(dto, hashedPassword, isAdmin) {
477
+ const authEntity = mapper.map(dto, RegisterDTO, import_cca_entities3.AuthEntity);
478
+ const userOrAdminEntity = isAdmin ? mapper.map(dto, RegisterDTO, import_cca_entities3.AdminEntity) : mapper.map(dto, RegisterDTO, import_cca_entities3.UserEntity);
479
+ userOrAdminEntity.updatedAt = void 0;
490
480
  if (isAdmin) {
491
- authEntity = mapper.map(dto, RegisterDTO, import_cca_entities3.AuthEntity);
492
- const adminEntity = mapper.map(dto, RegisterDTO, import_cca_entities3.AdminEntity);
493
- adminEntity.updatedAt = void 0;
494
- authEntity.admin = adminEntity;
481
+ authEntity.admin = userOrAdminEntity;
495
482
  } else {
496
- authEntity = mapper.map(dto, RegisterDTO, import_cca_entities3.AuthEntity);
497
- const userEntity = mapper.map(dto, RegisterDTO, import_cca_entities3.UserEntity);
498
- userEntity.updatedAt = void 0;
499
- authEntity.user = userEntity;
483
+ authEntity.user = userOrAdminEntity;
500
484
  }
501
485
  authEntity.password = hashedPassword;
502
486
  authEntity.refreshToken = "";
@@ -504,7 +488,6 @@ var _RegisterUseCase = class _RegisterUseCase {
504
488
  }
505
489
  };
506
490
  __name(_RegisterUseCase, "RegisterUseCase");
507
- _RegisterUseCase.SALT_ROUNDS = 10;
508
491
  var RegisterUseCase = _RegisterUseCase;
509
492
 
510
493
  // src/application/useCase/RefreshTokenUseCase.ts
@@ -743,7 +726,7 @@ var _AuthController = class _AuthController {
743
726
  constructor(loginUseCase, adminLoginUseCase, logoutUseCase, registerUseCase, refreshTokenUseCase, twoFactorSetupUseCase, twoFactorEnableUseCase, twoFactorVerifyUseCase, twoFactorDisableUseCase) {
744
727
  this.login = /* @__PURE__ */ __name(async (req, res, next) => {
745
728
  try {
746
- const { adminPassword, ...loginDTO } = req.body;
729
+ const loginDTO = req.body;
747
730
  const result = await this.loginUseCase.execute(loginDTO);
748
731
  res.status(201).json(
749
732
  {
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 { AuthEntity } from \"cca-entities\";\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\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 }> {\r\n const auth = await this.validateLogin(loginDTO);\r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n\r\n return { id: auth.user.id, accessToken: accessToken };\r\n }\r\n\r\n private async validateLogin(\r\n loginDTO: LoginDTO\r\n ): Promise<AuthEntity> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n return auth;\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 .required(\"Role is required\")\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 await Promise.all([schemas.role.validate(role), 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 this.validateLogin(loginDTO, adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n\r\n private async validateLogin(\r\n loginDTO: LoginDTO,\r\n adminPassword?: string\r\n ): Promise<AuthEntity> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth;\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\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private static 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: AuthRepository) => 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({\r\n email,\r\n name,\r\n password,\r\n role,\r\n adminPassword\r\n });\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 = await this._buildAuthEntity(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 role: dto.role,\r\n password: dto.password.trim(),\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, RegisterUseCase.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) {\r\n return false;\r\n }\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 async _buildAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): Promise<AuthEntity> {\r\n let authEntity: AuthEntity;\r\n \r\n if (isAdmin) {\r\n authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const adminEntity = mapper.map(dto, RegisterDTO, AdminEntity);\r\n adminEntity.updatedAt = undefined as unknown as Date;\r\n authEntity.admin = adminEntity;\r\n } else {\r\n authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userEntity = mapper.map(dto, RegisterDTO, UserEntity);\r\n userEntity.updatedAt = undefined as unknown as Date;\r\n authEntity.user = userEntity;\r\n }\r\n \r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n \r\n return authEntity;\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\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}","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}","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 { TokenPair } from \"../../domain/interfaces/TokenPair\";\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<TokenPair | 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 { 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 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(userId, secret);\r\n \r\n return { secret, otpAuthUrl, 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 { TokenPair } from '../../domain/interfaces/TokenPair';\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: TokenPair = 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): TokenPair {\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 { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n 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 }\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 const userId = req.auth!.id;\r\n const result = await this.twoFactorSetupUseCase.execute(userId);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA6B;;;ACAtB,IAAM,YAAN,MAAM,kBAAiB,MAAM;AAAA,EAClC,YACS,SACA,aAAqB,KACrB,OAAe,YACtB;AACA,UAAM,OAAO;AAJN;AACA;AACA;AAGP,WAAO,eAAe,MAAM,WAAW,SAAS;AAChD,UAAM,kBAAkB,IAAI;AAAA,EAC9B;AACF;AAVoC;AAA7B,IAAM,WAAN;AAYA,IAAM,mBAAN,MAAM,yBAAwB,SAAS;AAAA,EAC5C,YAAY,SAAiB;AAC3B,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AAL8C;AAAvC,IAAM,kBAAN;AAOA,IAAM,2BAAN,MAAM,iCAAgC,SAAS;AAAA,EACpD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AALsD;AAA/C,IAAM,0BAAN;AAOA,IAAM,iBAAN,MAAM,uBAAsB,SAAS;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM,SAAS,KAAK,mBAAmB;AAAA,EACzC;AACF;AAJ4C;AAArC,IAAM,gBAAN;AAMA,IAAM,kBAAN,MAAM,wBAAuB,SAAS;AAAA,EAC3C,YAAY,UAAkB,oBAAoB;AAChD,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AAL6C;AAAtC,IAAM,iBAAN;AAOA,IAAM,qBAAN,MAAM,2BAA0B,SAAS;AAAA,EAC9C,YAAY,UAAkB,uBAAuB;AACnD,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AALgD;AAAzC,IAAM,oBAAN;AAOA,IAAM,YAAN,MAAM,kBAAiB,SAAS;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AALuC;AAAhC,IAAM,WAAN;AAOA,IAAM,qBAAN,MAAM,2BAA0B,SAAS;AAAA,EAC9C,YAAY,SAAiB;AAC3B,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AALgD;AAAzC,IAAM,oBAAN;AAOA,IAAM,kBAAN,MAAM,wBAAuB,SAAS;AAAA,EAC3C,YAAY,SAAiB;AAC3B,UAAM,SAAS,GAAG;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AAL6C;AAAtC,IAAM,iBAAN;;;ADxDA,IAAM,iBAAN,MAAM,uBAAsB,2BAAa;AAAA,EAI5C,gBAAgB,QAA4B;AACxC,SAAK,eAAe;AAAA,EACxB;AAAA,EAEA,UAAU,KAAoB;AAC1B,SAAK,SAAS,EAAE,GAAG,IAAI;AACvB,SAAK,KAAK,mBAAmB,KAAK,MAAM;AAAA,EAC5C;AAAA,EAEA,YAAiC;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,aAA+B;AACjC,QAAI,CAAC,KAAK,cAAc;AACpB,YAAM,IAAI,wBAAwB,uBAAuB;AAAA,IAC7D;AACA,QAAI;AACA,YAAM,SAAS,MAAM,KAAK,aAAa;AACvC,WAAK,UAAU,MAAM;AACrB,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,YAAM,IAAI,wBAAwB,6BAA6B;AAAA,IACnE;AAAA,EACJ;AACJ;AA7BgD;AAAzC,IAAM,gBAAN;AA+BA,IAAM,gBAAgB,IAAI,cAAc;;;AEhCxC,IAAM,aAAa,wBAAC,iBAAqC;AAC9D,gBAAc,gBAAgB,YAAY;AAC5C,GAF0B;AAInB,IAAM,uBAAuB,mCAA8B;AAChE,SAAO,cAAc,UAAU,KAAM,MAAM,cAAc,WAAW;AACtE,GAFoC;;;ACPpC,IAAAA,oBAA4C;AAC5C,IAAAC,uBAA2B;;;ACD3B,sBAAiD;;;ACAjD,UAAqB;AACrB,0BAAqC;AACrC,oBAAmB;AAanB,IAAM,UAAU;AAAA,EACd,IAAQ,WAAO,EAAE,KAAK,wBAAwB;AAAA,EAC9C,OACG,WAAO,EACP,MAAM,sBAAsB,EAC5B,IAAI,KAAK,oCAAoC;AAAA,EAChD,MACG,WAAO,EACP,SAAS,kBAAkB,EAC3B,IAAI,GAAG,yCAAyC,EAChD,IAAI,IAAI,kCAAkC,EAC1C,QAAQ,iBAAiB,2CAA2C;AAAA,EACvE,UACG,WAAO,EACP,SAAS,mBAAmB,EAC5B,IAAI,GAAG,oBAAoB,EAC3B,IAAI,KAAK,mBAAmB,EAC5B;AAAA,IACC;AAAA,IACA;AAAA,EACF;AAAA,EACF,MACG,WAAO,EACP,SAAS,kBAAkB,EAC3B,MAAM,OAAO,OAAO,4BAAQ,GAAG,wBAAwB;AAC5D;AAEO,IAAM,gBAAgB,8BAC3B,OACA,eACwB;AACxB,MAAI;AACF,UAAM,QAAQ,MAAM,SAAS,OAAO,KAAK,EAAE,YAAY,CAAC;AACxD,UAAM,OAAO,MAAM,WAAW,YAAY,KAAK;AAC/C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,SAAS,OAAY;AACnB,UAAM,IAAI,gBAAgB,MAAM,WAAW,sBAAsB;AAAA,EACnE;AACF,GAhB6B;AAkBtB,IAAM,mBAAmB,8BAAO,aAAqC;AAC1E,MAAI,UAAU;AACZ,QAAI;AACF,YAAM,QAAQ,SAAS,SAAS,QAAQ;AAAA,IAC1C,SAAS,OAAY;AACnB,YAAM,IAAI,gBAAgB,MAAM,WAAW,yBAAyB;AAAA,IACtE;AAAA,EACF;AACF,GARgC;AAUzB,IAAM,0BAA0B,8BACrC,YACA,OACA,kBACkB;AAClB,MAAI;AACF,UAAM,QAAQ,MAAM,SAAS,OAAO,KAAK,EAAE,YAAY,CAAC;AAExD,UAAM,eAAe,MAAM,WAAW,YAAY,KAAK;AAEvD,QAAI,CAAC,aAAc;AACnB,QAAI,aAAa,OAAO,cAAe;AAEvC,UAAM,IAAI,gBAAgB,SAAS,KAAK,qBAAqB;AAAA,EAC/D,SAAS,OAAY;AACnB,QAAI,iBAAiB,iBAAiB;AACpC,YAAM;AAAA,IACR;AACA,UAAM,IAAI,gBAAgB,8BAA8B;AAAA,EAC1D;AACF,GApBuC;AAsBhC,IAAM,sBAAsB,8BACjC,MACA,eACkB;AAClB,QAAM,EAAE,MAAM,OAAO,MAAM,SAAS,IAAI;AAExC,QAAM,QAAQ,IAAI;AAAA,IAChB,QAAQ,KAAK,SAAS,IAAI;AAAA,IAC1B,QAAQ,KAAK,SAAS,IAAI;AAAA,IAC1B,wBAAwB,YAAY,KAAK;AAAA,IACzC,iBAAiB,QAAQ;AAAA,EAC3B,CAAC;AACH,GAZmC;AAc5B,IAAM,mBAAmB,8BAC9B,MACA,eACwB;AACxB,QAAM,EAAE,OAAO,MAAM,SAAS,IAAI;AAElC,QAAM,QAAQ,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,QAAQ,SAAS,SAAS,QAAQ,CAAC,CAAC;AAEpF,QAAM,OAAO,MAAM,cAAc,OAAO,UAAU;AAClD,MAAI,CAAC,QAAQ,CAAC,KAAK,UAAU;AAC3B,UAAM,IAAI,cAAc,qBAAqB;AAAA,EAC/C;AAEA,QAAM,UAAU,MAAM,cAAAC,QAAO,QAAQ,UAAU,KAAK,QAAQ;AAC5D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,eAAe,qBAAqB;AAAA,EAChD;AAEA,SAAO;AACT,GAnBgC;AAqBzB,IAAM,sBAAsB,8BACjC,mBACkB;AAClB,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI,gBAAgB,4BAA4B;AAAA,EACxD;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,qBAAqB;AAE1C,QAAI,CAAC,OAAO,qBAAqB;AAC/B,YAAM,IAAI,gBAAgB,2CAA2C;AAAA,IACvE;AAEA,QAAI,SAAS,cAAc,MAAM,SAAS,OAAO,mBAAmB,GAAG;AACrE,YAAM,IAAI,gBAAgB,wBAAwB;AAAA,IACpD;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAiB;AACpC,YAAM;AAAA,IACR;AACA,UAAM,IAAI,gBAAgB,iCAAiC;AAAA,EAC7D;AACF,GAvBmC;;;ADvH5B,IAAM,gBAAN,MAAM,cAAqC;AAAA,EAEhD,YACmB,YACA,YACjB;AAFiB;AACA;AAAA,EACf;AAAA,EAEJ,MAAa,aAA4B;AACvC,cAAM,oCAAmB,KAAK,YAAY,CAAC,SAAyB,KAAK,OAAO,CAAC;AAAA,EACnF;AAAA,EAEA,MAAM,QAAQ,UAAkE;AAC9E,UAAM,OAAO,MAAM,KAAK,cAAc,QAAQ;AAC9C,UAAM,cAAc,KAAK,WAAW,oBAAoB,KAAK,MAAM,KAAK,IAAI;AAE5E,WAAO,EAAE,IAAI,KAAK,KAAK,IAAI,YAAyB;AAAA,EACtD;AAAA,EAEA,MAAc,cACZ,UACqB;AACrB,UAAM,OAAO,MAAM,iBAAiB,UAAU,KAAK,UAAU;AAE7D,WAAO;AAAA,EACT;AACF;AAzBkD;AAA3C,IAAM,eAAN;;;AERP,IAAAC,mBAAiD;AAO1C,IAAM,qBAAN,MAAM,mBAA0C;AAAA,EAGrD,YACE,YACA;AACA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAa,aAA4B;AACvC,cAAM,qCAAmB,KAAK,YAAY,CAAC,SAAyB,KAAK,OAAO,CAAC;AAAA,EACnF;AAAA,EAEA,MAAM,QAAQ,UAAoB,eAAwC;AACxE,UAAM,OAAO,MAAM,KAAK,cAAc,UAAU,aAAa;AAE7D,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,MAAc,cACZ,UACA,eACqB;AACrB,UAAM,OAAO,MAAM,iBAAiB,UAAU,KAAK,UAAU;AAE7D,UAAM,oBAAoB,aAAa;AAEvC,WAAO;AAAA,EACT;AACF;AA7BuD;AAAhD,IAAM,oBAAN;;;ACPP,IAAAC,mBAAiD;AAM1C,IAAM,iBAAN,MAAM,eAAsC;AAAA,EAG/C,YAAY,YAA4B;AACpC,SAAK,aAAa;AAAA,EACtB;AAAA,EAEA,MAAa,aAA4B;AACrC,cAAM,qCAAmB,KAAK,YAAY,CAAC,SAAyB,KAAK,OAAO,CAAC;AAAA,EACrF;AAAA,EAEA,MAAM,QAAQ,QAA+B;AACzC,QAAI;AACA,YAAM,KAAK,WAAW,OAAO,MAAM;AAAA,IACvC,SAAS,OAAO;AACZ,UAAI,cAAc,gBAAgB;AAAA,IACtC;AAAA,EACJ;AACJ;AAlBmD;AAA5C,IAAM,gBAAN;;;ACNP,IAAAC,mBAAiD;AACjD,IAAAC,UAAwB;AACxB,IAAAC,uBAA8D;;;ACF9D,IAAAC,eAA6B;AAC7B,IAAAC,kBAAwB;;;ACDxB,kBAAsD;AACtD,IAAAC,uBAAoD;;;ACC7C,IAAM,eAAN,MAAM,aAAY;AAMzB;AANyB;AAAlB,IAAM,cAAN;;;ACFP,qBAAwB;AAGjB,IAAM,WAAN,MAAM,SAAQ;AAYrB;AAZqB;AAEnB;AAAA,MADC,wBAAQ;AAAA,GADE,SAEX;AAGA;AAAA,MADC,wBAAQ;AAAA,GAJE,SAKX;AAGA;AAAA,MADC,wBAAQ;AAAA,GAPE,SAQX;AAGA;AAAA,MADC,wBAAQ;AAAA,GAVE,SAWX;AAXK,IAAM,UAAN;;;ACHP,IAAAC,kBAAwB;AAGjB,IAAM,YAAN,MAAM,UAAS;AActB;AAdsB;AAEpB;AAAA,MADC,yBAAQ;AAAA,GADE,UAEX;AAGA;AAAA,MADC,yBAAQ;AAAA,GAJE,UAKX;AAGA;AAAA,MADC,yBAAQ;AAAA,GAPE,UAQX;AAGA;AAAA,MADC,yBAAQ;AAAA,GAVE,UAWX;AAXK,IAAM,WAAN;;;AHIA,SAAS,mBAAmBC,SAAsB;AACrD;AAAA,IACIA;AAAA,IACA;AAAA,IACA;AAAA,QACA,uBAAU,UAAQ,KAAK,WAAO,qBAAQ,SAAO,IAAI,KAAK,CAAC;AAAA,QACvD,uBAAU,UAAQ,KAAK,cAAU,qBAAQ,SAAO,IAAI,QAAQ,CAAC;AAAA,QAC7D,uBAAU,UAAQ,KAAK,UAAM,qBAAQ,SAAO,IAAI,IAAI,CAAC;AAAA,EAAC;AAE1D;AAAA,IACIA;AAAA,IACA;AAAA,IACA;AAAA,QACA,uBAAU,UAAQ,KAAK,UAAM,qBAAQ,SAAO,IAAI,IAAI,CAAC;AAAA,QACrD,uBAAU,UAAQ,KAAK,WAAO,qBAAQ,SAAO,IAAI,KAAK,CAAC;AAAA,EAAC;AAE5D;AAAA,IACIA;AAAA,IACA;AAAA,IACA;AAAA,QACA,uBAAU,UAAQ,KAAK,UAAM,qBAAQ,SAAO,IAAI,IAAI,CAAC;AAAA,QACrD,uBAAU,UAAQ,KAAK,WAAO,qBAAQ,SAAO,IAAI,KAAK,CAAC;AAAA,EAAC;AAE5D;AAAA,IACIA;AAAA,IACA;AAAA,IACA;AAAA,QACA,uBAAU,UAAQ,KAAK,QAAI,qBAAQ,SAAO,IAAI,EAAE,CAAC;AAAA,QACjD,uBAAU,UAAQ,KAAK,UAAM,qBAAQ,SAAO,IAAI,IAAI,CAAC;AAAA,QACrD,uBAAU,UAAQ,KAAK,WAAO,qBAAQ,SAAO,IAAI,KAAK,CAAC;AAAA,EAAC;AAE5D;AAAA,IACIA;AAAA,IACA;AAAA,IACA;AAAA,QACA,uBAAU,UAAQ,KAAK,QAAI,qBAAQ,SAAO,IAAI,EAAE,CAAC;AAAA,QACjD,uBAAU,UAAQ,KAAK,UAAM,qBAAQ,SAAO,IAAI,IAAI,CAAC;AAAA,QACrD,uBAAU,UAAQ,KAAK,WAAO,qBAAQ,SAAO,IAAI,KAAK,CAAC;AAAA,EAAC;AAChE;AAtCgB;;;ADFT,IAAM,aAAS,2BAAa;AAAA,EACjC,yBAAqB,yBAAQ;AAC/B,CAAC;AAED,mBAAmB,MAAM;;;ADAlB,IAAM,mBAAN,MAAM,iBAAwC;AAAA,EAGnD,YAA6B,YAA4B;AAA5B;AAAA,EAA6B;AAAA,EAE1D,MAAa,aAA4B;AACvC,cAAM,qCAAmB,KAAK,YAAY,CAAC,SAAyB,KAAK,OAAO,CAAC;AAAA,EACnF;AAAA,EAEA,MAAa,QACX,OACA,MACA,UACA,OAAiB,8BAAS,OAC1B,eACiC;AACjC,QAAI;AACF,YAAM,gBAAgB,KAAK,gBAAgB;AAAA,QACzC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,YAAM,cAAc,MAAM,KAAK;AAAA,QAC7B,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAEA,YAAM,oBAAoB,eAAe,KAAK,UAAU;AAExD,YAAM,iBAAiB,MAAM,KAAK,cAAc,cAAc,QAAQ;AACtE,YAAM,aAAa,MAAM,KAAK,iBAAiB,eAAe,gBAAgB,WAAW;AAEzF,aAAO,KAAK,WAAW,OAAO,UAAU;AAAA,IAC1C,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,wBAAwB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,gBAAgB,KAA+B;AACrD,WAAO;AAAA,MACL,MAAM,IAAI,KAAK,KAAK;AAAA,MACpB,OAAO,IAAI,MAAM,KAAK,EAAE,YAAY;AAAA,MACpC,MAAM,IAAI;AAAA,MACV,UAAU,IAAI,SAAS,KAAK;AAAA,MAC5B,eAAe,IAAI,eAAe,KAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,UAAmC;AAC7D,WAAc,aAAK,UAAU,iBAAgB,WAAW;AAAA,EAC1D;AAAA,EAEA,MAAc,2BACZ,MACA,eACkB;AAClB,QAAI,SAAS,8BAAS,OAAO;AAC3B,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,kBAAkB,mDAAmD;AAAA,IACjF;AAEA,UAAM,oBAAoB,aAAa;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,iBACZ,KACA,gBACA,SACqB;AACrB,QAAI;AAEJ,QAAI,SAAS;AACX,mBAAa,OAAO,IAAI,KAAK,aAAa,+BAAU;AACpD,YAAM,cAAc,OAAO,IAAI,KAAK,aAAa,gCAAW;AAC5D,kBAAY,YAAY;AACxB,iBAAW,QAAQ;AAAA,IACrB,OAAO;AACL,mBAAa,OAAO,IAAI,KAAK,aAAa,+BAAU;AACpD,YAAM,aAAa,OAAO,IAAI,KAAK,aAAa,+BAAU;AAC1D,iBAAW,YAAY;AACvB,iBAAW,OAAO;AAAA,IACpB;AAEA,eAAW,WAAW;AACtB,eAAW,eAAe;AAE1B,WAAO;AAAA,EACT;AACF;AAjGqD;AAAxC,iBACa,cAAc;AADjC,IAAM,kBAAN;;;AMTP,IAAAC,mBAAiD;AAK1C,IAAM,uBAAN,MAAM,qBAA4C;AAAA,EAIvD,YAAY,YAA4B,SAAyB;AAC/D,SAAK,aAAa;AAClB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAa,aAA4B;AACvC,cAAM,qCAAmB,KAAK,YAAY,CAAC,SAAyB,KAAK,OAAO,CAAC;AAAA,EACnF;AAAA,EAEA,MAAa,QAAQ,cAAiD;AACpE,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,QAAQ,mBAAmB,YAAY;AAElE,UAAI,CAAC,QAAQ,QAAQ;AACnB,eAAO;AAAA,MACT;AAEA,UAAI,aAAa,MAAM,KAAK,WAAW,iBAAiB,QAAQ,MAAM;AAEtE,UAAI,CAAC,YAAY;AACf,qBAAa,MAAM,KAAK,WAAW,iBAAiB,QAAQ,QAAQ,IAAI;AAAA,MAC1E;AAEA,UAAI,CAAC,YAAY;AACf,eAAO;AAAA,MACT;AAEA,YAAM,OAAO,WAAW,SAAS,UAAU,WAAW,QAAQ,WAAW;AAEzE,YAAM,cAAc,KAAK,QAAQ,oBAAoB,MAAM,WAAW,IAAI;AAC1E,YAAM,kBAAkB,KAAK,QAAQ,qBAAqB,IAAI;AAE9D,YAAM,KAAK,WAAW,OAAO,WAAW,IAAI;AAAA,QAC1C,cAAc;AAAA,MAChB,CAAC;AAED,aAAO;AAAA,QACL;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAhDyD;AAAlD,IAAM,sBAAN;;;ACGA,IAAM,yBAAN,MAAM,uBAA6C;AAAA,EAKxD,YAAY,kBAAoC,gBAAgC;AAFhF,SAAQ,gBAAgB;AAGtB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AAAA,EACxB;AAAA,EACA,MAAM,aAA4B;AAChC,QAAI,KAAK,cAAe;AAExB,UAAM,QAAQ,IAAI;AAAA,MAChB,KAAK,iBAAiB,WAAW;AAAA,IACnC,CAAC;AAED,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,MAAM,QAAQ,QAAkD;AAC9D,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,OAAO,MAAM,KAAK,eAAe,aAAa,MAAM;AAE1D,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,eAAe,gBAAgB;AAAA,IAC3C;AAEA,QAAI,KAAK,kBAAkB;AACzB,YAAM,IAAI,eAAe,8CAA8C;AAAA,IACzE;AAEA,UAAM,EAAE,QAAQ,WAAW,IAAI,KAAK,iBAAiB,eAAe,KAAK,KAAK;AAC9E,UAAM,YAAY,MAAM,KAAK,iBAAiB,eAAe,UAAU;AAEvE,UAAM,KAAK,eAAe,sBAAsB,QAAQ,MAAM;AAE9D,WAAO,EAAE,QAAQ,YAAY,UAAU;AAAA,EACzC;AACF;AAzC0D;AAAnD,IAAM,wBAAN;;;ACRP,IAAAC,mBAAiD;AAO1C,IAAM,0BAAN,MAAM,wBAA8C;AAAA,EAKzD,YAAY,kBAAoC,gBAAgC;AAFhF,SAAQ,gBAAgB;AAGtB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AAAA,EAExB;AAAA,EACA,MAAM,aAA4B;AAC9B,QAAI,KAAK,cAAe;AAExB,UAAM,QAAQ,IAAI;AAAA,MACd,KAAK,iBAAiB,WAAW;AAAA,UACjC,qCAAmB,KAAK,gBAAgB,UAAQ,KAAK,OAAO,CAAC;AAAA,IACjE,CAAC;AAED,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEF,MAAM,QAAQ,QAAgB,KAAsC;AAClE,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,EAAE,MAAM,IAAI;AAElB,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,eAAe,mBAAmB;AAAA,IAC9C;AAEA,UAAM,OAAO,MAAM,KAAK,eAAe,aAAa,MAAM;AAE1D,QAAI,CAAC,QAAQ,CAAC,KAAK,iBAAiB;AAClC,YAAM,IAAI,eAAe,+CAA+C;AAAA,IAC1E;AAEA,QAAI,KAAK,kBAAkB;AACzB,YAAM,IAAI,eAAe,8CAA8C;AAAA,IACzE;AAEA,UAAM,UAAU,KAAK,iBAAiB,YAAY,OAAO,KAAK,eAAe;AAE7E,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,eAAe,2BAA2B;AAAA,IACtD;AAEA,UAAM,KAAK,eAAe,gBAAgB,IAAI;AAAA,EAChD;AACF;AAlD2D;AAApD,IAAM,yBAAN;;;ACPP,IAAAC,mBAAiD;AACjD,IAAAC,uBAAoD;AAY7C,IAAM,0BAAN,MAAM,wBAA+C;AAAA,EAGxD,YACqB,kBACA,gBACA,YACnB;AAHmB;AACA;AACA;AALrB,SAAQ,gBAAgB;AAAA,EAMpB;AAAA,EAEJ,MAAa,aAA4B;AACrC,QAAI,KAAK,cAAe;AACxB,UAAM,QAAQ,IAAI;AAAA,MACd,KAAK,iBAAiB,WAAW;AAAA,MACjC,KAAK,WAAW,WAAW;AAAA,UAC3B,qCAAmB,KAAK,gBAAgB,UAAQ,KAAK,OAAO,CAAC;AAAA,IACjE,CAAC;AACD,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEA,MAAa,QAAQ,KAA2G;AAC5H,QAAI,CAAC,KAAK,eAAe;AACrB,YAAM,KAAK,WAAW;AAAA,IAC1B;AAEA,UAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,QAAI,CAAC,UAAU,CAAC,OAAO;AACnB,YAAM,IAAI,eAAe,iCAAiC;AAAA,IAC9D;AAEA,UAAM,OAA0B,MAAM,KAAK,eAAe,aAAa,MAAM;AAC7E,QAAI,CAAC,QAAQ,CAAC,KAAK,mBAAmB,CAAC,KAAK,kBAAkB;AAC1D,YAAM,IAAI,eAAe,kBAAkB;AAAA,IAC/C;AAEA,UAAM,UAAU,KAAK,iBAAiB,YAAY,OAAO,KAAK,eAAe;AAC7E,QAAI,CAAC,SAAS;AACV,YAAM,IAAI,eAAe,4BAA4B;AAAA,IACzD;AAEA,UAAM,YAAuB,KAAK,eAAe,IAAI;AACrD,UAAM,KAAK,iBAAiB,IAAI;AAChC,UAAM,KAAK,uBAAuB,MAAM,UAAU,YAAY;AAE9D,QAAI,KAAK,OAAO;AACZ,aAAO;AAAA,QACH,OAAO,UAAU;AAAA,QACjB,cAAc,UAAU;AAAA,QACxB,MAAM,KAAK,cAAc,KAAK,KAAK;AAAA,MACvC;AAAA,IACJ;AAEA,QAAI,KAAK,MAAM;AACX,aAAO;AAAA,QACH,OAAO,UAAU;AAAA,QACjB,cAAc,UAAU;AAAA,QACxB,MAAM,KAAK,aAAa,KAAK,IAAI;AAAA,MACrC;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEQ,cAAc,OAA8B;AAChD,WAAO,OAAO,IAAI,OAAO,kCAAa,QAAQ;AAAA,EAClD;AAAA,EAEQ,aAAa,MAA2B;AAC5C,WAAO,OAAO,IAAI,MAAM,iCAAY,OAAO;AAAA,EAC/C;AAAA,EAEA,MAAc,iBAAiB,MAAiC;AAC5D,SAAK,KAAK,cAAc,oBAAI,KAAK;AACjC,SAAK,KAAK,WAAW;AACrB,UAAM,KAAK,eAAe,OAAO,KAAK,IAAI,IAAI;AAAA,EAClD;AAAA,EAEA,MAAc,uBAAuB,MAAkB,cAAqC;AACxF,SAAK,eAAe;AACpB,UAAM,KAAK,eAAe,OAAO,KAAK,IAAI,EAAE,aAAa,CAAC;AAAA,EAC9D;AAAA,EAEQ,eAAe,MAA6B;AAChD,WAAO;AAAA,MACH,aAAa,KAAK,WAAW,oBAAoB,KAAK,MAAM,KAAK,IAAI;AAAA,MACrE,cAAc,KAAK,WAAW,qBAAqB,KAAK,IAAI;AAAA,IAChE;AAAA,EACJ;AACJ;AAvF4D;AAArD,IAAM,yBAAN;;;ACbP,IAAAC,mBAAiD;AAQ1C,IAAM,2BAAN,MAAM,yBAA+C;AAAA,EAK1D,YAAY,kBAAoC,gBAAgC;AAFhF,SAAQ,gBAAgB;AAGtB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AAAA,EACxB;AAAA,EACA,MAAM,aAA4B;AAChC,QAAI,KAAK,cAAe;AAExB,UAAM,QAAQ,IAAI;AAAA,MACd,KAAK,iBAAiB,WAAW;AAAA,UACjC,qCAAmB,KAAK,gBAAgB,UAAQ,KAAK,OAAO,CAAC;AAAA,IACjE,CAAC;AACL;AACI,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,MAAM,QAAQ,QAAgB,KAAsC;AAClE,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,EAAE,MAAM,IAAI;AAElB,UAAM,OAAO,MAAM,KAAK,eAAe,aAAa,MAAM;AAE1D,QAAI,CAAC,QAAQ,CAAC,KAAK,mBAAmB,CAAC,KAAK,kBAAkB;AAC5D,YAAM,IAAI,eAAe,0CAA0C;AAAA,IACrE;AAEA,UAAM,UAAU,KAAK,iBAAiB,YAAY,OAAO,KAAK,eAAe;AAE7E,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,eAAe,2BAA2B;AAAA,IACtD;AAEA,UAAM,KAAK,eAAe,iBAAiB,IAAI;AAAA,EACjD;AACF;AAzC4D;AAArD,IAAM,0BAAN;;;ACYA,IAAM,kBAAN,MAAM,gBAAe;AAAA,EAY1B,YACE,cACA,mBACA,eACA,iBACA,qBACA,uBACA,wBACA,wBACA,yBACA;AAYF,iBAAQ,8BAAO,KAAc,KAAe,SAAuB;AACjE,UAAI;AACF,cAAM,EAAE,eAAe,GAAG,SAAS,IAAc,IAAI;AACrD,cAAM,SAAS,MAAM,KAAK,aAAa,QAAQ,QAAQ;AACvD,YAAI,OAAO,GAAG,EAAE;AAAA,UAAK;AAAA,YACnB,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,MAAM;AAAA,cACJ,aAAa,OAAO;AAAA,cACpB,QAAQ,OAAO;AAAA,YACjB;AAAA,UACF;AAAA,QACA;AAAA,MACF,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAhBQ;AAkBR,sBAAa,8BAAO,KAAc,KAAe,SAAuB;AACtE,UAAI;AACF,cAAM,EAAE,eAAe,GAAG,SAAS,IAAc,IAAI;AACrD,YAAI,CAAC,eAAe;AAClB,gBAAM,IAAI,eAAe,4BAA4B;AAAA,QACvD;AACA,cAAM,SAAS,MAAM,KAAK,kBAAkB,QAAQ,UAAU,aAAa;AAC3E,YAAI,OAAO,GAAG,EAAE,KAAK,MAAM;AAAA,MAC7B,SACO,OAAO;AACZ,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAZa;AAcb,kBAAS,8BACP,KACA,KACA,SACkB;AAClB,UAAI;AACF,cAAM,KAAK,cAAc,QAAQ,IAAI,KAAK,EAAE;AAC5C,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,0BAAyB,CAAC;AAAA,MAC5D,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAXS;AAaT,oBAAW,8BACT,KACA,KACA,SACkB;AAClB,UAAI;AACF,cAAM,EAAE,OAAO,MAAM,UAAU,MAAM,cAAc,IAAiB,IAAI;AAExE,cAAM,KAAK,gBAAgB,QAAQ,OAAO,MAAM,UAAU,MAAM,aAAa;AAC7E,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,QAAQ,UAAU,CAAC;AAAA,MAC5C,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAbW;AAeX,wBAAe,8BAAO,KAAc,QAAkB;AACpD,YAAM,EAAE,aAAa,IAA0B,IAAI;AAEnD,YAAM,SAAS,MAAM,KAAK,oBAAoB,QAAQ,YAAY;AAClE,UAAI,KAAK,MAAM;AAAA,IACjB,GALe;AAOf,oBAAW,8BAAO,KAAc,KAAe,SAAuB;AACpE,UAAI;AACF,cAAM,SAAS,IAAI,KAAM;AACzB,cAAM,SAAS,MAAM,KAAK,sBAAsB,QAAQ,MAAM;AAC9D,YAAI,OAAO,GAAG,EAAE,KAAK,MAAM;AAAA,MAC7B,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GARW;AAUX,qBAAY,8BAAO,KAAc,KAAe,SAAuB;AACrE,UAAI;AACF,cAAM,SAAS,IAAI,MAAM;AACzB,cAAM,MAAwB,IAAI;AAElC,cAAM,KAAK,uBAAuB,QAAQ,QAAQ,GAAG;AACrD,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,0DAA0D,CAAC;AAAA,MAC7F,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAVY;AAYZ,qBAAY,8BAAO,KAAc,KAAe,SAAuB;AACrE,UAAI;AACF,cAAM,MAAwB,IAAI;AAElC,cAAM,SAAS,MAAM,KAAK,uBAAuB,QAAQ,GAAG;AAC5D,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,GAAG;AAAA,QACL,CAAC;AAAA,MACH,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAZY;AAcZ,sBAAa,8BAAO,KAAc,KAAe,SAAuB;AACtE,UAAI;AACF,cAAM,SAAS,IAAI,KAAM;AACzB,cAAM,MAAwB,IAAI;AAElC,cAAM,KAAK,wBAAwB,QAAQ,QAAQ,GAAG;AACtD,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,QAAQ;AAAA,UACR,SAAS;AAAA,QACX,CAAC;AAAA,MACH,SAAS,OAAO;AACd,aAAK,KAAK;AAAA,MACZ;AAAA,IACF,GAba;AAlHX,SAAK,eAAe;AACpB,SAAK,oBAAoB;AACzB,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AACvB,SAAK,sBAAsB;AAC3B,SAAK,wBAAwB;AAC7B,SAAK,yBAAyB;AAC9B,SAAK,yBAAyB;AAC9B,SAAK,0BAA0B;AAAA,EACjC;AAuHF;AAvJ4B;AAArB,IAAM,iBAAN;;;ACjBA,IAAM,sBAAN,MAAM,oBAAmB;AAAA,EAG9B,YAAY,YAA4B;AACtC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAa,QAAQ,KAAc,KAAe,MAAoB;AACpE,QAAI;AACF,YAAM,QAAQ,IAAI,QAAQ,eAAe,MAAM,GAAG,EAAE,CAAC;AAErD,UAAI,CAAC,OAAO;AACV,eAAO,IAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,0BAA0B,CAAC;AAAA,MACpE;AAEA,YAAM,UAAU,MAAM,KAAK,WAAW,kBAAkB,KAAK;AAE7D,UAAI,CAAC,QAAQ,wBAAwB;AACnC,eAAO,IAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UAC1B,SAAS;AAAA,UACT,MAAM;AAAA,UACN,QAAQ,QAAQ;AAAA,QAClB,CAAC;AAAA,MACH;AAEA,UAAI,OAAO,EAAE,GAAG,SAAS,wBAAwB,KAAK;AACtD,WAAK;AAAA,IACP,SAAS,OAAO;AACd,aAAO,IAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,2BAA2B,CAAC;AAAA,IACrE;AAAA,EACF;AACF;AA/BgC;AAAzB,IAAM,qBAAN;;;ACHP,IAAAC,mBAAwD;AAKjD,IAAM,kBAAN,MAAM,wBACH,gCACuC;AAAA,EAC/C,YAAY,YAAoC;AAC9C,UAAM,UAAU;AAAA,EAClB;AAAA,EAEA,MAAM,YAAY,OAA2C;AAC3D,UAAM,QAAQ,KAAK,WAChB,mBAAmB,MAAM,EACzB,kBAAkB,aAAa,MAAM,EACrC,UAAU,eAAe,EACzB,MAAM,uBAAuB,EAAE,MAAM,CAAC;AAEzC,WAAO,MAAM,MAAM,OAAO;AAAA,EAC5B;AAAA,EAEA,MAAM,OAAO,QAA4D;AACvE,WAAO,MAAM,OAAO,MAAM;AAAA,EAC5B;AAAA,EAEA,MAAM,aAAa,QAA4C;AAC7D,UAAM,QAAQ,KAAK,WAChB,mBAAmB,MAAM,EACzB,kBAAkB,aAAa,MAAM,EACrC,UAAU,sBAAsB,EAChC,MAAM,qBAAqB,EAAE,OAAO,CAAC;AAExC,WAAO,MAAM,MAAM,OAAO;AAAE;AAAA,EAC9B;AAAA,EAEA,MAAM,iBAAiB,QAAgB,UAAmB,OAAmC;AAC3F,UAAM,QAAQ,KAAK,WAChB,mBAAmB,MAAM,EACzB,UAAU,sBAAsB;AAEnC,QAAI,SAAS;AACX,YAAM,kBAAkB,cAAc,OAAO,EAC1C,MAAM,sBAAsB,EAAE,OAAO,CAAC;AAAA,IAC3C,OAAO;AACL,YAAM,kBAAkB,aAAa,MAAM,EACxC,MAAM,qBAAqB,EAAE,OAAO,CAAC;AAAA,IAC1C;AAEA,WAAO,MAAM,MAAM,OAAO;AAAA,EAC5B;AAAA,EAEA,MAAM,OAAO,QAA+B;AAC1C,UAAM,OAAO,MAAM,KAAK,aAAa,MAAM;AAC3C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,gBAAgB;AAAA,IAC1C;AAEA,SAAK,eAAe;AACpB,SAAK,KAAK,WAAW;AAErB,UAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,sBAAsB,QAAgB,QAA+B;AACzE,UAAM,OAAO,MAAM,KAAK,aAAa,MAAM;AAC3C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,gBAAgB;AAAA,IAC1C;AAEA,SAAK,kBAAkB;AAEvB,UAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,gBAAgB,MAAiC;AAErD,SAAK,mBAAmB;AAExB,UAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,iBAAiB,MAAiC;AAEtD,SAAK,mBAAmB;AACxB,SAAK,kBAAkB;AAEvB,UAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,mBAAmB,QAAkC;AACzD,UAAM,OAAO,MAAM,KAAK,aAAa,MAAM;AAC3C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,gBAAgB;AAAA,IAC1C;AAEA,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,mBAAmB,QAAwC;AAC/D,UAAM,OAAO,MAAM,KAAK,aAAa,MAAM;AAC3C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,gBAAgB;AAAA,IAC1C;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AApGiD;AAF1C,IAAM,iBAAN;;;ACLP,UAAqB;AAErB,IAAAC,UAAwB;AACxB,IAAAC,oBAAiD;AAkB1C,IAAM,kBAAN,MAAM,gBAAqD;AAAA,EAGhE,YAA6B,YAA4B,QAAqB;AAAjD;AAC3B,SAAK,WAAW,MAAM;AAAA,EACxB;AAAA,EAEA,MAAc,WAAW,QAAqB;AAC5C,UAAM,aAAa,MAAM,qBAAqB;AAE9C,SAAK,YAAY;AAAA,MACf,mBAAmB,WAAW;AAAA,MAC9B,oBAAoB,WAAW;AAAA,MAC/B,mBAAoB,SAAS,WAAW,mBAAmB,EAAE;AAAA,MAC7D,oBAAoB,SAAS,WAAW,oBAAoB,EAAE;AAAA,MAC9D,GAAG;AAAA,IACL;AAEA,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEA,MAAM,aAA4B;AAChC,cAAM,sCAAmB,KAAK,YAAY,UAAQ,KAAK,OAAO,CAAC;AAAA,EACjE;AAAA,EAEQ,wBAA8B;AACpC,QAAI,CAAC,KAAK,WAAW,qBAAqB,CAAC,KAAK,WAAW,oBAAoB;AAC7E,YAAM,IAAI,SAAS,gCAAgC;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,OAAe,UAA8C;AAC9E,UAAM,OAAO,MAAM,KAAK,WAAW,YAAY,KAAK;AACpD,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,qBAAqB;AAAA,IAC/C;AAEA,UAAM,gBAAgB,MAAa,gBAAQ,UAAU,KAAK,QAAQ;AAClE,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,eAAe,qBAAqB;AAAA,IAChD;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB;AACxB,QAAI,CAAC,KAAK,UAAW,OAAM,IAAI,SAAS,uBAAuB;AAAA,EACjE;AAAA,EAEA,oBAAoB,MAAkB,MAAyB;AAC7D,SAAK,gBAAgB;AACrB,WAAW;AAAA,MACT,EAAE,QAAQ,KAAK,IAAI,OAAO,KAAK,OAAO,KAAW;AAAA,MACjD,KAAK,UAAW;AAAA,MAChB,EAAE,WAAW,KAAK,UAAW,kBAAkB;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,qBAAqB,MAA0B;AAC7C,SAAK,gBAAgB;AACrB,WAAW;AAAA,MACT,EAAE,QAAQ,KAAK,GAAG;AAAA,MAClB,KAAK,UAAW;AAAA,MAChB,EAAE,WAAW,KAAK,UAAW,mBAAmB;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,OAAe,QAAwC;AACvE,QAAI;AACF,cAAQ,IAAI,oBAAoB,KAAK;AACrC,cAAQ,IAAI,iBAAiB,MAAM;AAEnC,aAAW,WAAO,OAAO,MAAM;AAAA,IACjC,SAAQ,OAAO;AACb,cAAQ,MAAM,0BAA0B,KAAK;AAC7C,YAAM,IAAI,kBAAkB;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,OAAuC;AAC7D,SAAK,gBAAgB;AACrB,WAAO,KAAK,YAAY,OAAO,KAAK,UAAW,iBAAiB;AAAA,EAClE;AAAA,EAEA,MAAM,mBAAmB,OAAuC;AAC9D,SAAK,gBAAgB;AACrB,WAAO,KAAK,YAAY,OAAO,KAAK,UAAW,kBAAkB;AAAA,EACnE;AACF;AAxFkE;AAA3D,IAAM,iBAAN;;;ACrBP,gBAA2B;AAC3B,aAAwB;AAMjB,IAAM,oBAAN,MAAM,kBAAyC;AAAA,EASpD,YAAY,QAAiB;AAP7B,SAAQ,cAAuB;AAQ7B,SAAK,SAAS;AAEd,SAAK,kBAAkB;AAAA,MACrB,aAAa,SAAS,OAAO,WAAW,KAAK;AAAA,MAC7C,cAAc,SAAS,OAAO,YAAY,KAAK;AAAA,MAC/C,eAAe;AAAA,QACb,sBAAsB;AAAA,QACtB,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,OAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,aAA4B;AACvC,QAAI,KAAK,YAAa;AAEtB,QAAI;AACF,WAAK,sBAAsB;AAC3B,WAAK,cAAc;AAAA,IACrB,SAAS,OAAO;AACd,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,YAAM,IAAI,eAAe,uCAAuC;AAAA,IAClE;AAAA,EACF;AAAA,EAEQ,wBAA8B;AACpC,QAAI,CAAC,KAAK,OAAO,UAAU,KAAK,GAAG;AACjC,YAAM,IAAI,eAAe,yDAAyD;AAAA,IACpF;AAEA,QAAI,KAAK,gBAAgB,eAAe,IAAI;AAC1C,YAAM,IAAI,eAAe,8CAA8C;AAAA,IACzE;AAEA,QAAI,KAAK,gBAAgB,cAAc,KAAK,KAAK,gBAAgB,cAAc,GAAG;AAChF,YAAM,IAAI,eAAe,mDAAmD;AAAA,IAC9E;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,eAAe,iDAAiD;AAAA,IAC5E;AAAA,EACF;AAAA,EAEO,eAAe,OAAuD;AAC3E,SAAK,kBAAkB;AAEvB,QAAI;AACF,YAAM,YAAsB,yBAAe;AAAA,QACzC,QAAQ,KAAK,gBAAgB;AAAA,QAC7B,MAAM,GAAG,KAAK,OAAO,QAAQ,IAAI,KAAK;AAAA,QACtC,QAAQ,KAAK,OAAO;AAAA,MACtB,CAAC;AAED,aAAO;AAAA,QACL,QAAQ,UAAU;AAAA,QAClB,YAAY,UAAU,eAAe;AAAA,MACvC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,gCAAgC,KAAK;AACnD,YAAM,IAAI,eAAe,+BAA+B;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,MAAa,eAAe,YAAqC;AAC/D,SAAK,kBAAkB;AAEvB,QAAI;AACF,aAAO,MAAa,iBAAU,YAAY,KAAK,gBAAgB,aAAa;AAAA,IAC9E,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AACjD,YAAM,IAAI,eAAe,4BAA4B;AAAA,IACvD;AAAA,EACF;AAAA,EAEO,YAAY,OAAe,QAAyB;AACzD,SAAK,kBAAkB;AAEvB,QAAI;AACF,aAAiB,eAAK,OAAO;AAAA,QAC3B;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA,QAAQ,KAAK,gBAAgB;AAAA,MAC/B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AACjD,YAAM,IAAI,eAAe,4BAA4B;AAAA,IACvD;AAAA,EACF;AACF;AAzGsD;AAA/C,IAAM,mBAAN;;;ApBcP,eAAe,oBAAoB,UAAwB;AACzD,QAAM,YAAY,IAAI,gCAAc,EAAE,SAAS,CAAC;AAEhD,QAAM,iBAAiB,IAAI;AAAA,IACzB,SAAS,cAAc,+BAAU;AAAA,EACnC;AACA,YAAU,mBAA+B,kBAAkB,cAAc;AAEzE,QAAM,iBAAiB,IAAI,eAAe,cAAc;AACxD,YAAU,gBAAgB,kBAAkB,cAAc;AAE1D,QAAM,aAAa,MAAM,qBAAqB;AAE9C,QAAM,mBAAmB,IAAI,iBAAiB,UAAU;AACxD,YAAU,gBAAgB,oBAAoB,gBAAgB;AAE9D,QAAM,qBAAqB,IAAI,mBAAmB,cAAc;AAEhE,QAAM,eAAe,IAAI,aAAa,gBAAgB,cAAc;AACpE,QAAM,oBAAoB,IAAI;AAAA,IAC5B;AAAA,EACF;AACA,QAAM,gBAAgB,IAAI,cAAc,cAAc;AACtD,QAAM,kBAAkB,IAAI,gBAAgB,cAAc;AAC1D,QAAM,sBAAsB,IAAI;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAEA,QAAM,wBAAwB,IAAI,sBAAsB,kBAAkB,cAAc;AACxF,QAAM,yBAAyB,IAAI,uBAAuB,kBAAkB,cAAc;AAC1F,QAAM,yBAAyB,IAAI;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,0BAA0B,IAAI,wBAAwB,kBAAkB,cAAc;AAE5F,YAAU,gBAAgB,gBAAgB,YAAY;AACtD,YAAU,gBAAgB,qBAAqB,iBAAiB;AAChE,YAAU,gBAAgB,iBAAiB,aAAa;AACxD,YAAU,gBAAgB,mBAAmB,eAAe;AAC5D,YAAU,gBAAgB,uBAAuB,mBAAmB;AACpE,YAAU,gBAAgB,yBAAyB,qBAAqB;AACxE,YAAU,gBAAgB,0BAA0B,sBAAsB;AAC1E,YAAU,gBAAgB,0BAA0B,sBAAsB;AAC1E,YAAU,gBAAgB,2BAA2B,uBAAuB;AAE5E,QAAM,iBAAiB,IAAI;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,gBAAgB,mBAAmB;AACzD;AA7De;","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"]}
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 { AuthEntity } from \"cca-entities\";\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\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 }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n\r\n return { id: auth.user.id, accessToken: accessToken };\r\n }\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\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}","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}","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 { TokenPair } from \"../../domain/interfaces/TokenPair\";\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<TokenPair | 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 { 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 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(userId, secret);\r\n \r\n return { secret, otpAuthUrl, 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 { TokenPair } from '../../domain/interfaces/TokenPair';\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: TokenPair = 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): TokenPair {\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 const result = await this.loginUseCase.execute(loginDTO);\r\n 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 }\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 const userId = req.auth!.id;\r\n const result = await this.twoFactorSetupUseCase.execute(userId);\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_cca_core","import_cca_core","import_cca_entities","import_cca_core","import_cca_core","bcrypt","import_cca_core"]}
package/dist/index.mjs CHANGED
@@ -146,7 +146,7 @@ var schemas = {
146
146
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/,
147
147
  "Password must contain uppercase, lowercase, number and special character"
148
148
  ),
149
- role: yup.string().required("Role is required").oneOf(Object.values(UserRole), "Invalid role specified")
149
+ role: yup.string().oneOf(Object.values(UserRole), "Invalid role specified")
150
150
  };
151
151
  var validateEmail = /* @__PURE__ */ __name(async (email, repository) => {
152
152
  try {
@@ -196,7 +196,10 @@ var validateRegisterDTO = /* @__PURE__ */ __name(async (auth, repository) => {
196
196
  }, "validateRegisterDTO");
197
197
  var validateLoginDTO = /* @__PURE__ */ __name(async (data, repository) => {
198
198
  const { email, role, password } = data;
199
- await Promise.all([schemas.role.validate(role), schemas.password.validate(password)]);
199
+ if (role) {
200
+ await schemas.role.validate(role);
201
+ }
202
+ await schemas.password.validate(password);
200
203
  const auth = await validateEmail(email, repository);
201
204
  if (!auth || !auth.password) {
202
205
  throw new NotFoundError("Invalid credentials");
@@ -237,14 +240,10 @@ var _LoginUseCase = class _LoginUseCase {
237
240
  await validateRepository(this.repository, (repo) => repo.getAll());
238
241
  }
239
242
  async execute(loginDTO) {
240
- const auth = await this.validateLogin(loginDTO);
243
+ const auth = await validateLoginDTO(loginDTO, this.repository);
241
244
  const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);
242
245
  return { id: auth.user.id, accessToken };
243
246
  }
244
- async validateLogin(loginDTO) {
245
- const auth = await validateLoginDTO(loginDTO, this.repository);
246
- return auth;
247
- }
248
247
  };
249
248
  __name(_LoginUseCase, "LoginUseCase");
250
249
  var LoginUseCase = _LoginUseCase;
@@ -259,13 +258,9 @@ var _LoginAdminUseCase = class _LoginAdminUseCase {
259
258
  await validateRepository2(this.repository, (repo) => repo.getAll());
260
259
  }
261
260
  async execute(loginDTO, adminPassword) {
262
- const auth = await this.validateLogin(loginDTO, adminPassword);
263
- return auth.user.id;
264
- }
265
- async validateLogin(loginDTO, adminPassword) {
266
261
  const auth = await validateLoginDTO(loginDTO, this.repository);
267
262
  await validateAdminSecret(adminPassword);
268
- return auth;
263
+ return auth.user.id;
269
264
  }
270
265
  };
271
266
  __name(_LoginAdminUseCase, "LoginAdminUseCase");
@@ -401,26 +396,21 @@ createUserMappings(mapper);
401
396
  var _RegisterUseCase = class _RegisterUseCase {
402
397
  constructor(repository) {
403
398
  this.repository = repository;
399
+ this.SALT_ROUNDS = 10;
404
400
  }
405
401
  async initialize() {
406
402
  await validateRepository4(this.repository, (repo) => repo.getAll());
407
403
  }
408
404
  async execute(email, name, password, role = UserRole2.GUEST, adminPassword) {
409
405
  try {
410
- const normalizedDTO = this._normalizeInput({
411
- email,
412
- name,
413
- password,
414
- role,
415
- adminPassword
416
- });
406
+ const normalizedDTO = this._normalizeInput({ email, name, password, role, adminPassword });
417
407
  const isAdminUser = await this._validateAdminRegistration(
418
408
  normalizedDTO.role,
419
409
  normalizedDTO.adminPassword
420
410
  );
421
411
  await validateRegisterDTO(normalizedDTO, this.repository);
422
412
  const hashedPassword = await this._hashPassword(normalizedDTO.password);
423
- const authEntity = await this._buildAuthEntity(normalizedDTO, hashedPassword, isAdminUser);
413
+ const authEntity = this._buildMappedAuthEntity(normalizedDTO, hashedPassword, isAdminUser);
424
414
  return this.repository.create(authEntity);
425
415
  } catch (error) {
426
416
  throw new RegistrationError(
@@ -432,36 +422,30 @@ var _RegisterUseCase = class _RegisterUseCase {
432
422
  return {
433
423
  name: dto.name.trim(),
434
424
  email: dto.email.trim().toLowerCase(),
435
- role: dto.role,
436
425
  password: dto.password.trim(),
426
+ role: dto.role,
437
427
  adminPassword: dto.adminPassword?.trim()
438
428
  };
439
429
  }
440
430
  async _hashPassword(password) {
441
- return bcrypt2.hash(password, _RegisterUseCase.SALT_ROUNDS);
431
+ return bcrypt2.hash(password, this.SALT_ROUNDS);
442
432
  }
443
433
  async _validateAdminRegistration(role, adminPassword) {
444
- if (role !== UserRole2.ADMIN) {
445
- return false;
446
- }
434
+ if (role !== UserRole2.ADMIN) return false;
447
435
  if (!adminPassword) {
448
436
  throw new UnauthorizedError("Admin password is required for admin registration");
449
437
  }
450
438
  await validateAdminSecret(adminPassword);
451
439
  return true;
452
440
  }
453
- async _buildAuthEntity(dto, hashedPassword, isAdmin) {
454
- let authEntity;
441
+ _buildMappedAuthEntity(dto, hashedPassword, isAdmin) {
442
+ const authEntity = mapper.map(dto, RegisterDTO, AuthEntity3);
443
+ const userOrAdminEntity = isAdmin ? mapper.map(dto, RegisterDTO, AdminEntity2) : mapper.map(dto, RegisterDTO, UserEntity2);
444
+ userOrAdminEntity.updatedAt = void 0;
455
445
  if (isAdmin) {
456
- authEntity = mapper.map(dto, RegisterDTO, AuthEntity3);
457
- const adminEntity = mapper.map(dto, RegisterDTO, AdminEntity2);
458
- adminEntity.updatedAt = void 0;
459
- authEntity.admin = adminEntity;
446
+ authEntity.admin = userOrAdminEntity;
460
447
  } else {
461
- authEntity = mapper.map(dto, RegisterDTO, AuthEntity3);
462
- const userEntity = mapper.map(dto, RegisterDTO, UserEntity2);
463
- userEntity.updatedAt = void 0;
464
- authEntity.user = userEntity;
448
+ authEntity.user = userOrAdminEntity;
465
449
  }
466
450
  authEntity.password = hashedPassword;
467
451
  authEntity.refreshToken = "";
@@ -469,7 +453,6 @@ var _RegisterUseCase = class _RegisterUseCase {
469
453
  }
470
454
  };
471
455
  __name(_RegisterUseCase, "RegisterUseCase");
472
- _RegisterUseCase.SALT_ROUNDS = 10;
473
456
  var RegisterUseCase = _RegisterUseCase;
474
457
 
475
458
  // src/application/useCase/RefreshTokenUseCase.ts
@@ -708,7 +691,7 @@ var _AuthController = class _AuthController {
708
691
  constructor(loginUseCase, adminLoginUseCase, logoutUseCase, registerUseCase, refreshTokenUseCase, twoFactorSetupUseCase, twoFactorEnableUseCase, twoFactorVerifyUseCase, twoFactorDisableUseCase) {
709
692
  this.login = /* @__PURE__ */ __name(async (req, res, next) => {
710
693
  try {
711
- const { adminPassword, ...loginDTO } = req.body;
694
+ const loginDTO = req.body;
712
695
  const result = await this.loginUseCase.execute(loginDTO);
713
696
  res.status(201).json(
714
697
  {
@@ -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 { AuthEntity } from \"cca-entities\";\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\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 }> {\r\n const auth = await this.validateLogin(loginDTO);\r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n\r\n return { id: auth.user.id, accessToken: accessToken };\r\n }\r\n\r\n private async validateLogin(\r\n loginDTO: LoginDTO\r\n ): Promise<AuthEntity> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n return auth;\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 .required(\"Role is required\")\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 await Promise.all([schemas.role.validate(role), 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 this.validateLogin(loginDTO, adminPassword);\r\n\r\n return auth.user.id;\r\n }\r\n\r\n private async validateLogin(\r\n loginDTO: LoginDTO,\r\n adminPassword?: string\r\n ): Promise<AuthEntity> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n\r\n await validateAdminSecret(adminPassword);\r\n\r\n return auth;\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\nimport { AuthRepository } from \"../../infrastructure/repository/AuthRepository\";\r\nimport { mapper } from \"../mappers/utils/mapper\";\r\nimport { RegisterDTO } from \"../dtos/RegisterDTO\";\r\nimport { validateAdminSecret, validateRegisterDTO } from \"../validators/authValidation\";\r\nimport { RegistrationError, UnauthorizedError } from \"../../utils/Errors\";\r\n\r\nexport class RegisterUseCase implements IBaseService {\r\n private static 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: AuthRepository) => 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({\r\n email,\r\n name,\r\n password,\r\n role,\r\n adminPassword\r\n });\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 = await this._buildAuthEntity(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 role: dto.role,\r\n password: dto.password.trim(),\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, RegisterUseCase.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) {\r\n return false;\r\n }\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 async _buildAuthEntity(\r\n dto: RegisterDTO,\r\n hashedPassword: string,\r\n isAdmin: boolean\r\n ): Promise<AuthEntity> {\r\n let authEntity: AuthEntity;\r\n \r\n if (isAdmin) {\r\n authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const adminEntity = mapper.map(dto, RegisterDTO, AdminEntity);\r\n adminEntity.updatedAt = undefined as unknown as Date;\r\n authEntity.admin = adminEntity;\r\n } else {\r\n authEntity = mapper.map(dto, RegisterDTO, AuthEntity);\r\n const userEntity = mapper.map(dto, RegisterDTO, UserEntity);\r\n userEntity.updatedAt = undefined as unknown as Date;\r\n authEntity.user = userEntity;\r\n }\r\n \r\n authEntity.password = hashedPassword;\r\n authEntity.refreshToken = \"\";\r\n \r\n return authEntity;\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\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}","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}","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 { TokenPair } from \"../../domain/interfaces/TokenPair\";\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<TokenPair | 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 { 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 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(userId, secret);\r\n \r\n return { secret, otpAuthUrl, 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 { TokenPair } from '../../domain/interfaces/TokenPair';\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: TokenPair = 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): TokenPair {\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 { adminPassword, ...loginDTO }: LoginDTO = req.body;\r\n const result = await this.loginUseCase.execute(loginDTO);\r\n 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 }\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 const userId = req.auth!.id;\r\n const result = await this.twoFactorSetupUseCase.execute(userId);\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","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 { AuthEntity } from \"cca-entities\";\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\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 }> {\r\n const auth = await validateLoginDTO(loginDTO, this.repository);\r\n const accessToken = this.jwtService.generateAccessToken(auth.user, auth.role);\r\n\r\n return { id: auth.user.id, accessToken: accessToken };\r\n }\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\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}","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}","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 { TokenPair } from \"../../domain/interfaces/TokenPair\";\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<TokenPair | 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 { 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 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(userId, secret);\r\n \r\n return { secret, otpAuthUrl, 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 { TokenPair } from '../../domain/interfaces/TokenPair';\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: TokenPair = 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): TokenPair {\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 const result = await this.loginUseCase.execute(loginDTO);\r\n 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 }\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 const userId = req.auth!.id;\r\n const result = await this.twoFactorSetupUseCase.execute(userId);\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","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.66",
3
+ "version": "0.1.67",
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",