import { Result, UniqueID } from "@common/domain"; import { ITransactionManager } from "@common/infrastructure/database"; import { EmailAddress, IAuthenticatedUserRepository, PasswordHash, Username, } from "@contexts/auth/domain"; import { IAuthService } from "./auth-service.interface"; export class AuthService implements IAuthService { private _respository!: IAuthenticatedUserRepository; private readonly _transactionManager!: ITransactionManager; constructor(repository: IAuthenticatedUserRepository, transactionManager: ITransactionManager) { this._respository = repository; this._transactionManager = transactionManager; } /** * 馃敼 `registerUser` * Registra un nuevo usuario en la base de datos bajo transacci贸n. */ async registerUser(params: { username: Username; email: EmailAddress; password: PasswordHash; }): Promise> { return await this._transactionManager.execute(async (transaction) => { const { username, email, password } = params; const userIdResult = UniqueID.generateNewID(); // Verificar si el usuario ya existe const userExists = await this._respository.userExists(email.toString(), transaction); if (userExists) { return Result.fail(new Error("Email is already registered")); } const user = await this._respository.createUser( { id: userIdResult, username: username, email: email, password: password, isActive: true, }, transaction ); return Result.ok({ userId: user.id }); }); } /** * 馃敼 `login` * Autentica un usuario y genera un token JWT bajo transacci贸n. */ static async login( email: string, password: string ): Promise> { return await authUserRepository.executeTransaction(async (transaction) => { const emailResult = EmailAddress.create(email); if (emailResult.isError()) { return Result.fail(emailResult.error); } const user = await authUserRepository.findByEmail(emailResult.data.getValue(), transaction); if (user.isError()) { return Result.fail(new Error("Invalid email or password")); } const isValidPassword = await user.data.validatePassword(password); if (!isValidPassword) { return Result.fail(new Error("Invalid email or password")); } const token = JwtHelper.generateToken({ userId: user.data.getUserID() }); return Result.ok({ token, userId: user.data.getUserID() }); }); } /** * 馃敼 `selectCompany` * Permite a un usuario seleccionar una empresa activa en la sesi贸n bajo transacci贸n. */ static async selectCompany( userId: string, companyId: string ): Promise> { return await authUserRepository.executeTransaction(async (transaction) => { const user = await authUserRepository.findById(userId, transaction); if (user.isError()) { return Result.fail(new Error("User not found")); } const isAssociated = await authUserRepository.isUserAssociatedWithCompany( userId, companyId, transaction ); if (!isAssociated) { return Result.fail(new Error("User does not have access to this company")); } return Result.ok({ message: "Company selected successfully" }); }); } /** * 馃敼 `logout` * Simula el cierre de sesi贸n de un usuario. No requiere transacci贸n. */ static logout(): Result<{ message: string }, never> { return Result.ok({ message: "Logged out successfully" }); } }