Presupuestador_web/server/src/contexts/users/domain/entities/User.ts

100 lines
2.1 KiB
TypeScript
Raw Normal View History

2024-05-15 19:56:22 +00:00
import bCrypt from "bcryptjs";
import {
AggregateRoot,
Email,
IDomainError,
2024-05-16 11:56:46 +00:00
Name,
2024-05-19 22:04:23 +00:00
Password,
2024-05-15 19:56:22 +00:00
Result,
UniqueID,
2024-05-19 22:04:23 +00:00
handleDomainError,
2024-05-15 19:56:22 +00:00
} from "@shared/contexts";
2024-05-19 22:04:23 +00:00
import { UserHasName } from "./User.specifications";
2024-05-15 19:56:22 +00:00
export interface IUserProps {
2024-05-16 11:56:46 +00:00
name: Name;
2024-05-15 19:56:22 +00:00
email: Email;
2024-05-19 22:04:23 +00:00
password: Password;
2024-05-15 19:56:22 +00:00
}
2024-05-19 22:04:23 +00:00
//type ISecuredUserProps = Omit<IUserProps, "password">;
2024-05-15 19:56:22 +00:00
export interface IUser {
id: UniqueID;
2024-05-16 11:56:46 +00:00
name: Name;
2024-05-15 19:56:22 +00:00
email: Email;
2024-05-16 18:16:00 +00:00
isUser: boolean;
isAdmin: boolean;
2024-05-15 19:56:22 +00:00
verifyPassword: (candidatePassword: string) => boolean;
}
export class User extends AggregateRoot<IUserProps> implements IUser {
2024-05-19 22:04:23 +00:00
static readonly ERROR_USER_WITHOUT_NAME = "ERROR_USER_WITHOUT_NAME";
2024-05-15 19:56:22 +00:00
public static create(
props: IUserProps,
id?: UniqueID,
): Result<User, IDomainError> {
2024-05-19 22:04:23 +00:00
const user = new User(props, id);
2024-05-15 19:56:22 +00:00
2024-05-19 22:04:23 +00:00
// Reglas de negocio / validaciones
const isValidUser = new UserHasName().isSatisfiedBy(user);
2024-05-15 19:56:22 +00:00
2024-05-19 22:04:23 +00:00
if (!isValidUser) {
return Result.fail(handleDomainError(User.ERROR_USER_WITHOUT_NAME));
}
2024-05-15 19:56:22 +00:00
return Result.ok<User>(user);
}
public static async hashPassword(password): Promise<string> {
2024-05-19 22:04:23 +00:00
return Password.hashPassword(password);
2024-05-15 19:56:22 +00:00
}
2024-05-19 22:04:23 +00:00
private _password: string;
2024-05-15 19:56:22 +00:00
2024-05-16 11:56:46 +00:00
get name(): Name {
return this.props.name;
}
2024-05-15 19:56:22 +00:00
get email(): Email {
return this.props.email;
}
get hashed_password(): string {
2024-05-19 22:04:23 +00:00
return this._password;
2024-05-15 19:56:22 +00:00
}
2024-05-16 18:16:00 +00:00
get isUser(): boolean {
return true;
}
get isAdmin(): boolean {
return true;
}
2024-05-15 19:56:22 +00:00
public verifyPassword(candidatePassword: string): boolean {
2024-05-19 22:04:23 +00:00
return bCrypt.compareSync(candidatePassword, this._password!);
2024-05-15 19:56:22 +00:00
}
}
async function genSalt(rounds = 10): Promise<string> {
return new Promise((resolve, reject) => {
bCrypt.genSalt(rounds, function (err, salt) {
if (err) return reject(err);
return resolve(salt);
});
});
}
async function hashPassword(password: string, salt: string): Promise<string> {
return new Promise((resolve, reject) => {
bCrypt.hash(password, salt, function (err, hash) {
if (err) return reject(err);
return resolve(hash);
});
});
}