87 lines
1.9 KiB
TypeScript
87 lines
1.9 KiB
TypeScript
/**
|
|
* Verification Code Domain Entity
|
|
* Pure domain object without infrastructure dependencies
|
|
*/
|
|
export class VerificationCodeEntity {
|
|
readonly id: string;
|
|
readonly phone: string;
|
|
readonly code: string;
|
|
readonly expiresAt: Date;
|
|
isUsed: boolean;
|
|
readonly createdAt: Date;
|
|
|
|
private constructor(props: {
|
|
id: string;
|
|
phone: string;
|
|
code: string;
|
|
expiresAt: Date;
|
|
isUsed: boolean;
|
|
createdAt: Date;
|
|
}) {
|
|
this.id = props.id;
|
|
this.phone = props.phone;
|
|
this.code = props.code;
|
|
this.expiresAt = props.expiresAt;
|
|
this.isUsed = props.isUsed;
|
|
this.createdAt = props.createdAt;
|
|
}
|
|
|
|
/**
|
|
* Create a new verification code
|
|
* Code expires in 5 minutes by default
|
|
*/
|
|
static create(phone: string, expirationMinutes: number = 5): VerificationCodeEntity {
|
|
const now = new Date();
|
|
return new VerificationCodeEntity({
|
|
id: crypto.randomUUID(),
|
|
phone,
|
|
code: VerificationCodeEntity.generateCode(),
|
|
expiresAt: new Date(now.getTime() + expirationMinutes * 60 * 1000),
|
|
isUsed: false,
|
|
createdAt: now,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reconstruct from persistence
|
|
*/
|
|
static fromPersistence(props: {
|
|
id: string;
|
|
phone: string;
|
|
code: string;
|
|
expiresAt: Date;
|
|
isUsed: boolean;
|
|
createdAt: Date;
|
|
}): VerificationCodeEntity {
|
|
return new VerificationCodeEntity(props);
|
|
}
|
|
|
|
/**
|
|
* Generate 6-digit verification code
|
|
*/
|
|
private static generateCode(): string {
|
|
return Math.floor(100000 + Math.random() * 900000).toString();
|
|
}
|
|
|
|
/**
|
|
* Check if the code is valid (not used and not expired)
|
|
*/
|
|
isValid(): boolean {
|
|
return !this.isUsed && this.expiresAt > new Date();
|
|
}
|
|
|
|
/**
|
|
* Mark the code as used
|
|
*/
|
|
markAsUsed(): void {
|
|
this.isUsed = true;
|
|
}
|
|
|
|
/**
|
|
* Check if this code matches the provided code
|
|
*/
|
|
matches(code: string): boolean {
|
|
return this.code === code;
|
|
}
|
|
}
|