This commit is contained in:
David Arranz 2024-05-20 09:36:28 +02:00
parent 7cd155f331
commit 9d96c76fa4
6 changed files with 17 additions and 92 deletions

View File

@ -1,10 +1,9 @@
import bCrypt from "bcryptjs";
import { import {
AggregateRoot, AggregateRoot,
Email, Email,
IDomainError, IDomainError,
Name, Name,
Password,
Result, Result,
UniqueID, UniqueID,
} from "@shared/contexts"; } from "@shared/contexts";
@ -12,15 +11,14 @@ import {
export interface IAuthUserProps { export interface IAuthUserProps {
name: Name; name: Name;
email: Email; email: Email;
password?: string; password: Password;
hashed_password?: string;
} }
export interface IAuthUser { export interface IAuthUser {
id: UniqueID; id: UniqueID;
name: Name; name: Name;
email: Email; email: Email;
hashed_password: string; password: Password;
isUser: boolean; isUser: boolean;
isAdmin: boolean; isAdmin: boolean;
@ -35,28 +33,12 @@ export class AuthUser
props: IAuthUserProps, props: IAuthUserProps,
id?: UniqueID, id?: UniqueID,
): Result<AuthUser, IDomainError> { ): Result<AuthUser, IDomainError> {
//const isNew = !!id === false;
// Se hace en el constructor de la Entidad
/* if (isNew) {
id = UniqueEntityID.create();
}*/
const user = new AuthUser(props, id); const user = new AuthUser(props, id);
return Result.ok<AuthUser>(user); return Result.ok<AuthUser>(user);
} }
public static async hashPassword(password): Promise<string> { public static async hashPassword(password): Promise<string> {
return hashPassword(password, await genSalt()); return Password.hashPassword(password);
}
private _hashed_password: string;
private constructor(props: IAuthUserProps, id?: UniqueID) {
super({ ...props, password: "", hashed_password: "" }, id);
this._protectPassword(props);
} }
get name(): Name { get name(): Name {
@ -67,8 +49,8 @@ export class AuthUser
return this.props.email; return this.props.email;
} }
get hashed_password(): string { get password(): Password {
return this._hashed_password; return this.props.password;
} }
get isUser(): boolean { get isUser(): boolean {
@ -80,36 +62,6 @@ export class AuthUser
} }
public verifyPassword(candidatePassword: string): boolean { public verifyPassword(candidatePassword: string): boolean {
return bCrypt.compareSync(candidatePassword, this._hashed_password!); return this.props.password.verifyPassword(candidatePassword);
}
private async _protectPassword(props: IAuthUserProps) {
const { password, hashed_password } = props;
if (password) {
this._hashed_password = await AuthUser.hashPassword(password);
} else {
this._hashed_password = hashed_password!;
}
} }
} }
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);
});
});
}
AuthUser.hashPassword("123456").then((value) => console.log(value));

View File

@ -8,7 +8,7 @@ import { Email, ICollection, IQueryCriteria, UniqueID } from "@shared/contexts";
import { Transaction } from "sequelize"; import { Transaction } from "sequelize";
import { AuthUser } from "../domain/entities"; import { AuthUser } from "../domain/entities";
import { IAuthRepository } from "../domain/repository/AuthRepository.interface"; import { IAuthRepository } from "../domain/repository/AuthRepository.interface";
import { IUserMapper, createUserMapper } from "./mappers/user.mapper"; import { IUserMapper, createUserMapper } from "./mappers/authuser.mapper";
export type QueryParams = { export type QueryParams = {
pagination: Record<string, any>; pagination: Record<string, any>;

View File

@ -17,7 +17,7 @@ export interface IUserMapper
AuthUser AuthUser
> {} > {}
class UserMapper class AuthUserMapper
extends SequelizeMapper<AuthUser_Model, TCreationUser_Attributes, AuthUser> extends SequelizeMapper<AuthUser_Model, TCreationUser_Attributes, AuthUser>
implements IUserMapper implements IUserMapper
{ {
@ -29,7 +29,7 @@ class UserMapper
const props: IAuthUserProps = { const props: IAuthUserProps = {
name: this.mapsValue(source, "name", Name.create), name: this.mapsValue(source, "name", Name.create),
email: this.mapsValue(source, "email", Email.create), email: this.mapsValue(source, "email", Email.create),
hashed_password: this.mapsValue( password: this.mapsValue(
source, source,
"password", "password",
Password.createFromHashedText, Password.createFromHashedText,
@ -54,12 +54,12 @@ class UserMapper
id: source.id.toPrimitive(), id: source.id.toPrimitive(),
name: source.name.toPrimitive(), name: source.name.toPrimitive(),
email: source.email.toPrimitive(), email: source.email.toPrimitive(),
password: source.hashed_password, password: source.password.toPrimitive(),
}; };
} }
} }
export const createUserMapper = (context: IAuthContext): IUserMapper => export const createUserMapper = (context: IAuthContext): IUserMapper =>
new UserMapper({ new AuthUserMapper({
context, context,
}); });

View File

@ -1 +1 @@
export * from "./user.mapper"; export * from "./authuser.mapper";

View File

@ -1,5 +1,3 @@
import bCrypt from "bcryptjs";
import { import {
AggregateRoot, AggregateRoot,
Email, Email,
@ -24,10 +22,9 @@ export interface IUser {
id: UniqueID; id: UniqueID;
name: Name; name: Name;
email: Email; email: Email;
password: Password;
isUser: boolean; isUser: boolean;
isAdmin: boolean; isAdmin: boolean;
verifyPassword: (candidatePassword: string) => boolean;
} }
export class User extends AggregateRoot<IUserProps> implements IUser { export class User extends AggregateRoot<IUserProps> implements IUser {
@ -53,8 +50,6 @@ export class User extends AggregateRoot<IUserProps> implements IUser {
return Password.hashPassword(password); return Password.hashPassword(password);
} }
private _password: string;
get name(): Name { get name(): Name {
return this.props.name; return this.props.name;
} }
@ -63,8 +58,8 @@ export class User extends AggregateRoot<IUserProps> implements IUser {
return this.props.email; return this.props.email;
} }
get hashed_password(): string { get password(): Password {
return this._password; return this.props.password;
} }
get isUser(): boolean { get isUser(): boolean {
@ -74,26 +69,4 @@ export class User extends AggregateRoot<IUserProps> implements IUser {
get isAdmin(): boolean { get isAdmin(): boolean {
return true; return true;
} }
public verifyPassword(candidatePassword: string): boolean {
return bCrypt.compareSync(candidatePassword, this._password!);
}
}
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);
});
});
} }

View File

@ -47,7 +47,7 @@ class UserMapper
id: source.id.toPrimitive(), id: source.id.toPrimitive(),
name: source.name.toPrimitive(), name: source.name.toPrimitive(),
email: source.email.toPrimitive(), email: source.email.toPrimitive(),
password: "", password: source.password.toPrimitive(),
}; };
} }
} }