-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat-44] : 인증 메일 전송 및 검증 기능 구현 #45
Open
KSLEE19
wants to merge
6
commits into
develop
Choose a base branch
from
feature/44
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f98bbfd
feat: 이메일 인증 기능 필요 의존성 추가
KSLEE19 7d898d0
feat: 이메일 관련 에러코드 추가
KSLEE19 5e42083
feat: 인증메일 전송 기능 구현
KSLEE19 893fca9
feat: Redis, Auditing을 위한 어노테이션 추가
KSLEE19 44da1b3
feat: 인증 번호를 확인하는 기능 구현
KSLEE19 b86915d
fix: 메일을 전송하는 주요 로직을 서비스단에서 모두 처리할 수 있도록 역할 분리
KSLEE19 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
src/main/java/icurriculum/global/verification/controller/MailController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package icurriculum.global.verification.controller; | ||
|
||
|
||
import icurriculum.global.response.ApiResponse; | ||
import icurriculum.global.response.status.ErrorStatus; | ||
import icurriculum.global.verification.dto.request.MailRequestDTO; | ||
import icurriculum.global.verification.dto.response.MailResponseDTO; | ||
import icurriculum.global.verification.service.EmailService; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import static icurriculum.global.verification.dto.response.MailResponseDTO.*; | ||
|
||
@RestController | ||
@RequestMapping("/mail") | ||
@RequiredArgsConstructor | ||
public class MailController { | ||
|
||
private final EmailService emailService; | ||
|
||
@PostMapping("/send") | ||
public ApiResponse<MailSend> mailSend(@RequestBody MailRequestDTO.MailSend request) { | ||
MailSend mailSend = emailService.integratedProcee(request.getEmail()); | ||
if (!mailSend.getStatus()) { | ||
return ApiResponse.onFailure(ErrorStatus.MAIL_NOT_SEND, mailSend); | ||
} | ||
return ApiResponse.onSuccess(mailSend); | ||
} | ||
|
||
@PostMapping("/verify") | ||
public ApiResponse<MailVerify> mailVerify(@RequestBody @Valid MailRequestDTO.MailVerify request) { | ||
MailVerify mailVerify = emailService.verifyCode(request.getEmail(), request.getCode()); | ||
return ApiResponse.onSuccess(mailVerify); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/icurriculum/global/verification/converter/EmailConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package icurriculum.global.verification.converter; | ||
|
||
import icurriculum.global.verification.dto.response.MailResponseDTO; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
import static icurriculum.global.verification.dto.response.MailResponseDTO.*; | ||
|
||
@Component | ||
public class EmailConverter { | ||
|
||
public MailSend toMailSendResponse(String comment, Boolean status) { | ||
return MailSend.builder() | ||
.responseComment(comment) | ||
.status(status) | ||
.timeStamp(LocalDateTime.now()) | ||
.build(); | ||
} | ||
|
||
public MailVerify toMailVerifyResponse(Boolean check, String email) { | ||
return MailVerify.builder() | ||
.check(check) | ||
.email(email) | ||
.build(); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/icurriculum/global/verification/dto/request/MailRequestDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package icurriculum.global.verification.dto.request; | ||
|
||
import jakarta.validation.constraints.Email; | ||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
public abstract class MailRequestDTO { | ||
|
||
@Builder | ||
@Getter | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class MailSend { | ||
@NotBlank | ||
private String email; | ||
} | ||
|
||
@Builder | ||
@Getter | ||
@AllArgsConstructor | ||
public static class MailVerify { | ||
@NotBlank | ||
private String email; | ||
@NotBlank | ||
private String code; | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/icurriculum/global/verification/dto/response/MailResponseDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package icurriculum.global.verification.dto.response; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
public abstract class MailResponseDTO { | ||
|
||
@Builder | ||
@Getter | ||
@AllArgsConstructor | ||
public static class MailSend{ | ||
private String responseComment; | ||
private Boolean status; | ||
private LocalDateTime timeStamp; | ||
} | ||
|
||
|
||
@Builder | ||
@Getter | ||
@AllArgsConstructor | ||
public static class MailVerify{ | ||
private Boolean check; | ||
private String email; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/icurriculum/global/verification/entity/EmailVerification.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package icurriculum.global.verification.entity; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.redis.core.RedisHash; | ||
|
||
import java.io.Serializable; | ||
|
||
|
||
@RedisHash(value = "Email", timeToLive = 600) //Redis 저장 엔티티, 제한시간 10분 | ||
@AllArgsConstructor | ||
@Getter | ||
@Setter | ||
public class EmailVerification implements Serializable { | ||
@Id | ||
private String email; | ||
private String verificationCode; | ||
} | ||
|
9 changes: 9 additions & 0 deletions
9
src/main/java/icurriculum/global/verification/repository/EmailVerificationRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package icurriculum.global.verification.repository; | ||
|
||
import icurriculum.global.verification.entity.EmailVerification; | ||
import org.springframework.data.repository.CrudRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface EmailVerificationRepository extends CrudRepository<EmailVerification, String> { | ||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/icurriculum/global/verification/service/EmailService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package icurriculum.global.verification.service; | ||
|
||
import icurriculum.global.verification.converter.EmailConverter; | ||
import icurriculum.global.verification.dto.response.MailResponseDTO; | ||
import icurriculum.global.verification.entity.EmailVerification; | ||
import icurriculum.global.verification.repository.EmailVerificationRepository; | ||
import jakarta.mail.MessagingException; | ||
import jakarta.mail.internet.MimeMessage; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.mail.javamail.JavaMailSender; | ||
import org.springframework.mail.javamail.MimeMessageHelper; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.Optional; | ||
import java.util.Random; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import static icurriculum.global.verification.dto.response.MailResponseDTO.*; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class EmailService { | ||
|
||
private final JavaMailSender mailSender; | ||
private final EmailConverter emailConverter; | ||
private final EmailVerificationRepository emailVerificationRepository; | ||
private final RedisTemplate<String, Object> redisTemplate; | ||
|
||
private final String SUBJECT = "[ICURRICULUM] 인하대학교 학생 인증 메일입니다."; | ||
|
||
public String makeVerificationCode() { | ||
Random random = new Random(); | ||
return String.format("%06d", random.nextInt(999999)); | ||
} | ||
public String getRedisKey(String email) { | ||
return "Email:" + email; | ||
} | ||
|
||
@Transactional | ||
public MailSend sendVerificationEmail(String email, String code) { | ||
try { | ||
EmailVerification verification = new EmailVerification(email, code); | ||
|
||
MimeMessage message = mailSender.createMimeMessage(); | ||
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true); | ||
|
||
messageHelper.setTo(email); | ||
messageHelper.setSubject(SUBJECT); | ||
String htmlContent = getVerificationMessage(code); | ||
messageHelper.setText(htmlContent, true); | ||
|
||
if (emailVerificationRepository.existsById(getRedisKey(email))) { //redis에 email이 있으면 삭제 | ||
emailVerificationRepository.deleteById(getRedisKey(email)); | ||
} | ||
emailVerificationRepository.save(verification); //Redis에 인증 코드 저장 | ||
mailSender.send(message); | ||
|
||
} catch (MessagingException e) { | ||
e.printStackTrace(); | ||
return emailConverter.toMailSendResponse("메일 전송에 실패했습니다.", false); | ||
} | ||
return emailConverter.toMailSendResponse("메일 전송에 성공했습니다.", true); | ||
} | ||
|
||
@Transactional | ||
public MailSend integratedProcee(String email) { | ||
String code = makeVerificationCode(); | ||
return sendVerificationEmail(email, code); | ||
} | ||
|
||
public String getVerificationMessage(String verificationCode) { | ||
StringBuffer verificationMessage = new StringBuffer(); | ||
verificationMessage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에 근로생중 누군가 메일 폼 만들어 줄겁니다. 나중되면 그걸로 수정합시다 |
||
.append("<h1 style = 'text-align: center;'>[ICURRICULUM] 인증메일</h1>"); | ||
verificationMessage | ||
.append("<h3 style ='text-align: center;'>인증코드 : <strong style='font-size: 32px; letter-spacing: 8px;'>") | ||
.append(verificationCode) | ||
.append("</strong></h3>"); | ||
return verificationMessage.toString(); | ||
} | ||
|
||
public MailVerify verifyCode(String email, String code) { | ||
Optional<EmailVerification> verificationObject = emailVerificationRepository.findById(email); | ||
boolean check = false; | ||
if (verificationObject.isPresent()) { | ||
EmailVerification verification = verificationObject.get(); | ||
if (verification.getVerificationCode().equals(code)) { | ||
emailVerificationRepository.deleteById(email); | ||
check = true; | ||
} | ||
} | ||
return emailConverter.toMailVerifyResponse(check, email); | ||
} | ||
|
||
public Long getTTL(String key) { | ||
return redisTemplate.getExpire(key, TimeUnit.SECONDS); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
service단에서 모두 처리할 수 있도록 새로 추가한 '메일 전송 과정을 통합해서 실행'하는 메소드 입니다.