11package grep .neogulcoder .domain .users .service ;
22
3- import grep .neogulcoder .domain .users .exception . EmailDuplicationException ;
3+ import grep .neogulcoder .domain .users .controller . dto . request . EmailVerifyRequest ;
44import grep .neogulcoder .domain .users .exception .MailSendException ;
5- import grep .neogulcoder .domain .users .exception .NotVerifiedEmailException ;
65import grep .neogulcoder .domain .users .exception .code .UserErrorCode ;
7- import grep .neogulcoder .domain .users .repository .UserRepository ;
86import jakarta .mail .MessagingException ;
97import jakarta .mail .internet .MimeMessage ;
108import lombok .RequiredArgsConstructor ;
1715import org .springframework .transaction .annotation .Transactional ;
1816
1917import java .time .LocalDateTime ;
20- import java .util .Optional ;
18+ import java .util .Objects ;
2119import java .util .Random ;
2220import java .util .Set ;
21+ import java .util .concurrent .CompletableFuture ;
2322import java .util .concurrent .ConcurrentHashMap ;
2423
2524@ Slf4j
2827@ RequiredArgsConstructor
2928public class MailService {
3029
31- private final ConcurrentHashMap <String , LocalDateTime > emailExpiredTimeMap = new ConcurrentHashMap <>();
30+ private final ConcurrentHashMap <EmailVerification , LocalDateTime > verificationExpiredTimeMap = new ConcurrentHashMap <>();
3231 private final Set <String > verifiedEmailSet = ConcurrentHashMap .newKeySet ();
3332 private final JavaMailSender mailSender ;
34- private final UserRepository userRepository ;
3533
3634 private static final int VERIFY_LIMIT_MINUTE = 5 ;
3735
3836 @ Scheduled (cron = "0 0 0 * * * " )
3937 public void clearStores () {
40- emailExpiredTimeMap .clear ();
38+ verificationExpiredTimeMap .clear ();
4139 verifiedEmailSet .clear ();
4240 log .info ("회원 인증 코드 저장 Map, Set Clear" );
4341 }
4442
4543 @ Async ("mailExecutor" )
46- public void sendCodeTo (String email , LocalDateTime currentDateTime ) {
44+ public CompletableFuture < String > sendCodeTo (String email , LocalDateTime currentDateTime ) {
4745 LocalDateTime expiredDateTime = currentDateTime .plusMinutes (VERIFY_LIMIT_MINUTE );
48- emailExpiredTimeMap .put (email , expiredDateTime );
49- sendCodeTo (email );
46+ String code = generateRandomIntCode ();
47+
48+ verificationExpiredTimeMap .put (new EmailVerification (email , code ), expiredDateTime );
49+ sendCodeTo (email , code );
50+ return CompletableFuture .completedFuture (code );
5051 }
5152
52- public boolean verifyEmailCode (String email , LocalDateTime currentDateTime ) {
53- LocalDateTime expiredTime = Optional .ofNullable (emailExpiredTimeMap .get (email ))
54- .orElseThrow (() -> new NotVerifiedEmailException (UserErrorCode .NOT_VERIFIED_EMAIL ));
53+ public boolean verifyEmailCode (EmailVerifyRequest request , LocalDateTime currentDateTime ) {
54+ String email = request .getEmail ();
55+ String code = request .getCode ();
56+ EmailVerification emailVerification = new EmailVerification (email , code );
57+
58+ LocalDateTime expiredTime = verificationExpiredTimeMap .get (emailVerification );
59+ if (expiredTime == null ) {
60+ return false ;
61+ }
5562
5663 boolean isVerify = currentDateTime .isBefore (expiredTime );
5764 if (isVerify ) {
58- verifiedEmailSet .add (email );
65+ verifiedEmailSet .add (request . getEmail () );
5966 }
6067 return isVerify ;
6168 }
@@ -64,15 +71,9 @@ public boolean confirmNotVerifiedEmail(String email) {
6471 return !verifiedEmailSet .contains (email );
6572 }
6673
67- private boolean isDuplicateEmail (String email ) {
68- return userRepository .findByEmail (email ).isPresent ();
69- }
70-
71- private void sendCodeTo (String email ) {
72- String code = generateRandomIntCode ();
73- MimeMessage mimeMessage = mailSender .createMimeMessage ();
74-
74+ private void sendCodeTo (String email , String code ) {
7575 try {
76+ MimeMessage mimeMessage = mailSender .createMimeMessage ();
7677 MimeMessageHelper helper = new MimeMessageHelper (mimeMessage , true , "UTF-8" );
7778 helper .setTo (email );
7879 helper .setSubject ("[wibby] 이메일 인증 코드" );
@@ -105,4 +106,26 @@ private String getContent(String code) {
105106 + " <p style='font-size:12px;color:#888;'>이 코드는 5분간 유효합니다.</p>"
106107 + "</div>" ;
107108 }
109+
110+ private static class EmailVerification {
111+ private String email ;
112+ private String code ;
113+
114+ private EmailVerification (String email , String code ) {
115+ this .email = email ;
116+ this .code = code ;
117+ }
118+
119+ @ Override
120+ public boolean equals (Object o ) {
121+ if (o == null || getClass () != o .getClass ()) return false ;
122+ EmailVerification that = (EmailVerification ) o ;
123+ return Objects .equals (email , that .email ) && Objects .equals (code , that .code );
124+ }
125+
126+ @ Override
127+ public int hashCode () {
128+ return Objects .hash (email , code );
129+ }
130+ }
108131}
0 commit comments