Presupuestador_web/server/src/contexts/auth/application/LoginUseCase.ts

95 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-05-15 19:56:22 +00:00
import {
IUseCase,
IUseCaseError,
UseCaseError,
handleUseCaseError,
} from "@/contexts/common/application";
import { IRepositoryManager } from "@/contexts/common/domain";
import { IInfrastructureError } from "@/contexts/common/infrastructure";
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
import {
Email,
ILogin_DTO,
Result,
ensureUserEmailIsValid,
} from "@shared/contexts";
import { User } from "../domain";
import { IAuthRepository } from "../domain/repository";
export type LoginResponseOrError =
| Result<never, IUseCaseError>
| Result<User, never>;
export class LoginUseCase
implements IUseCase<ILogin_DTO, Promise<LoginResponseOrError>>
{
private _adapter: ISequelizeAdapter;
private _repositoryManager: IRepositoryManager;
constructor(props: {
adapter: ISequelizeAdapter;
repositoryManager: IRepositoryManager;
}) {
this._adapter = props.adapter;
this._repositoryManager = props.repositoryManager;
}
private getRepositoryByName<T>(name: string) {
return this._repositoryManager.getRepository<T>(name);
}
async execute(request: ILogin_DTO): Promise<LoginResponseOrError> {
const { email, password } = request;
// Validaciones de datos
const emailOrError = ensureUserEmailIsValid(email);
if (emailOrError.isFailure) {
return Result.fail(
handleUseCaseError(
UseCaseError.INVALID_INPUT_DATA,
"Email or password is not valid",
emailOrError.error,
),
);
}
// Crear auth
try {
const user = await this.findUserEmail(emailOrError.object);
if (user === null || !user.verifyPassword(password)) {
return Result.fail(
handleUseCaseError(
UseCaseError.INVALID_INPUT_DATA,
"Email or password is not valid",
),
);
}
return Result.ok<User>(user);
} catch (error: unknown) {
const _error = error as IInfrastructureError;
return Result.fail(
handleUseCaseError(
UseCaseError.REPOSITORY_ERROR,
"Error al buscar el usuario",
_error,
),
);
}
}
private async findUserEmail(email: Email): Promise<User | null> {
const transaction = this._adapter.startTransaction();
const authRepoBuilder = this.getRepositoryByName<IAuthRepository>("Auth");
let user: User | null = null;
await transaction.complete(async (t) => {
const authRepo = authRepoBuilder({ transaction: t });
user = await authRepo.findByEmail(email);
});
return user;
}
}