66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository, MoreThan, IsNull } from 'typeorm';
|
|
import { EmailVerification, EmailVerificationType } from '../../domain/entities/email-verification.entity';
|
|
import { IEmailVerificationRepository } from '../../domain/repositories/email-verification.repository.interface';
|
|
|
|
@Injectable()
|
|
export class EmailVerificationRepository implements IEmailVerificationRepository {
|
|
constructor(
|
|
@InjectRepository(EmailVerification)
|
|
private readonly repo: Repository<EmailVerification>,
|
|
) {}
|
|
|
|
async create(data: {
|
|
email: string;
|
|
code: string;
|
|
type: EmailVerificationType;
|
|
expiresAt: Date;
|
|
}): Promise<EmailVerification> {
|
|
const entity = this.repo.create(data);
|
|
return this.repo.save(entity);
|
|
}
|
|
|
|
async findLatestValid(
|
|
email: string,
|
|
type: EmailVerificationType,
|
|
): Promise<EmailVerification | null> {
|
|
return this.repo.findOne({
|
|
where: {
|
|
email,
|
|
type,
|
|
expiresAt: MoreThan(new Date()),
|
|
verifiedAt: IsNull(),
|
|
},
|
|
order: { createdAt: 'DESC' },
|
|
});
|
|
}
|
|
|
|
async save(verification: EmailVerification): Promise<EmailVerification> {
|
|
return this.repo.save(verification);
|
|
}
|
|
|
|
async getDailySendCount(email: string): Promise<number> {
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
return this.repo.count({
|
|
where: {
|
|
email,
|
|
createdAt: MoreThan(today),
|
|
},
|
|
});
|
|
}
|
|
|
|
async deleteExpired(): Promise<number> {
|
|
const result = await this.repo
|
|
.createQueryBuilder()
|
|
.delete()
|
|
.where('expires_at < :now', { now: new Date() })
|
|
.andWhere('verified_at IS NOT NULL OR expires_at < :cutoff', {
|
|
cutoff: new Date(Date.now() - 24 * 60 * 60 * 1000),
|
|
})
|
|
.execute();
|
|
return result.affected || 0;
|
|
}
|
|
}
|