import { AggregateRoot, AggregateID } from '@mobicoop/ddd-library'; import * as bcrypt from 'bcrypt'; import { AuthenticationProps, CreateAuthenticationProps, } from './authentication.types'; import { AuthenticationCreatedDomainEvent } from './events/authentication-created.domain-event'; import { AuthenticationDeletedDomainEvent } from './events/authentication-deleted.domain-event'; import { PasswordUpdatedDomainEvent } from './events/password-updated.domain-event'; export class AuthenticationEntity extends AggregateRoot { protected readonly _id: AggregateID; static create = async ( create: CreateAuthenticationProps, ): Promise => { const props: AuthenticationProps = { ...create }; const hash = await AuthenticationEntity.encryptPassword(props.password); const authentication = new AuthenticationEntity({ id: props.userId, props: { userId: props.userId, password: hash, usernames: props.usernames, }, }); authentication.addEvent( new AuthenticationCreatedDomainEvent({ aggregateId: props.userId }), ); return authentication; }; updatePassword = async (password: string): Promise => { this.props.password = await AuthenticationEntity.encryptPassword(password); this.addEvent( new PasswordUpdatedDomainEvent({ aggregateId: this.id, }), ); }; delete(): void { this.addEvent( new AuthenticationDeletedDomainEvent({ aggregateId: this.id, }), ); } authenticate = async (password: string): Promise => await bcrypt.compare(password, this.props.password); validate(): void { // entity business rules validation to protect it's invariant before saving entity to a database } private static encryptPassword = async (password: string): Promise => await bcrypt.hash(password, 10); }