using Microsoft.EntityFrameworkCore; using bitforum.Constants; using bitforum.Models.Account; namespace bitforum.Repository { public interface IEmailVerifyNumberRepository { /// /// 새 인증번호 생성 및 저장 /// public Task GenerateCodeAsync(string email, VerificationType type); /// /// 인증번호 검증 및 사용 처리 /// public Task ValidateCodeAsync(string email, string code, VerificationType type); /// /// 만료된 인증번호 삭제 /// public Task CleanupExpiredCodesAsync(); } public class EmailVerifyNumberRepository : IEmailVerifyNumberRepository { private readonly DefaultDbContext _db; private readonly int _codeExpirationMinutes = 2; public EmailVerifyNumberRepository(DefaultDbContext db) { _db = db; } public async Task GenerateCodeAsync(string email, VerificationType type) { _db.EmailVerifyNumber.RemoveRange( _db.EmailVerifyNumber.Where(x => x.Email == email && x.Type == type) ); var code = Random.Shared.Next(100000, 999999).ToString(); // 6자리 숫자 인증번호 생성 var expiration = DateTime.UtcNow.AddMinutes(_codeExpirationMinutes); _db.EmailVerifyNumber.Add(new EmailVerifyNumber { Type = type, Email = email, Code = code, Expiration = expiration }); await _db.SaveChangesAsync(); return code; } public async Task ValidateCodeAsync(string email, string code, VerificationType type) { var data = await _db.EmailVerifyNumber.FirstOrDefaultAsync(x => x.Email == email && x.Code == code && x.Type == type && !x.IsVerified && x.Expiration > DateTime.UtcNow); if (data == null) { return false; } data.IsVerified = true; // 사용 처리 await _db.SaveChangesAsync(); return true; } public async Task CleanupExpiredCodesAsync() { _db.EmailVerifyNumber.RemoveRange( _db.EmailVerifyNumber.Where(x => x.Expiration < DateTime.UtcNow) ); await _db.SaveChangesAsync(); } } }