auth/src/modules/authentication/core/domain/authentication.entity.ts

60 lines
1.9 KiB
TypeScript

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<AuthenticationProps> {
protected readonly _id: AggregateID;
static create = async (
create: CreateAuthenticationProps,
): Promise<AuthenticationEntity> => {
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<void> => {
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<boolean> =>
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<string> =>
await bcrypt.hash(password, 10);
}