Skip to content

Commit

Permalink
Merge pull request #26 from SKHUMING/develop
Browse files Browse the repository at this point in the history
code refactor
  • Loading branch information
giwoong01 authored Sep 26, 2023
2 parents 4bd1231 + a1cd28d commit 1cca2ee
Show file tree
Hide file tree
Showing 39 changed files with 1,107 additions and 28 deletions.
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-mail'

// security, jwt
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// swagger사용 3.0.0버전 -> springboot 버전이 2.6.x이상이어서 3.0.0버전 사용
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'io.springfox:springfox-swagger-ui:3.0.0'

// intelliJ에서 db사용
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'

compileOnly 'org.projectlombok:lombok'
Expand All @@ -43,6 +49,6 @@ dependencies {
testImplementation 'com.h2database:h2'
}

tasks.named('test') {
test {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public AdminController(AdminService adminService) {
description = "어드민 공지 등록",
responses = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "201", description = "공지 추가 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 요청")
})
@PostMapping("/api/admin/notice/save")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ public class NoticeSaveReqDto {

private int mileageScore;

public NoticeSaveReqDto(String title, String schedule, String contents, int mileageScore) {
private String createDate;

private String links;

public NoticeSaveReqDto(String title, String schedule, String contents, int mileageScore, String createDate, String links) {
this.title = title;
this.schedule = schedule;
this.contents = contents;
this.mileageScore = mileageScore;
this.createDate = createDate;
this.links = links;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public void noticeSave(NoticeSaveReqDto noticeSaveReqDto) {
Notice notice = new Notice(noticeSaveReqDto.getTitle(),
noticeSaveReqDto.getSchedule(),
noticeSaveReqDto.getContents(),
noticeSaveReqDto.getMileageScore());
noticeSaveReqDto.getMileageScore(),
noticeSaveReqDto.getCreateDate(),
noticeSaveReqDto.getLinks());

noticeRepository.save(notice);
}
Expand All @@ -40,7 +42,9 @@ public void noticeUpdate(Long noticeId, NoticeSaveReqDto noticeSaveReqDto) {
notice.update(noticeSaveReqDto.getTitle(),
noticeSaveReqDto.getSchedule(),
noticeSaveReqDto.getContents(),
noticeSaveReqDto.getMileageScore());
noticeSaveReqDto.getMileageScore(),
noticeSaveReqDto.getCreateDate(),
noticeSaveReqDto.getLinks());
}

// 공지 삭제
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.itcontest.skhuming.email.api;

import com.itcontest.skhuming.email.api.request.EmailCheckReq;
import com.itcontest.skhuming.email.application.EmailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;

@RestController
public class EmailController {

private final EmailService emailService;

public EmailController(EmailService emailService) {
this.emailService = emailService;
}

@Operation(
summary = "이메일 인증",
description = "이메일 인증 코드 전송",
responses = {
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "400", description = "잘못된 요청")
})
@PostMapping("/api/email-check")
public ResponseEntity<String> emailCheck(@RequestBody EmailCheckReq emailCheckReq) throws MessagingException, UnsupportedEncodingException {
String authCode = emailService.sendEmail(emailCheckReq.getEmail());
return new ResponseEntity<>(authCode, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.itcontest.skhuming.email.api.request;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class EmailCheckReq {
private String email;

public EmailCheckReq(String email) {
this.email = email;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.itcontest.skhuming.email.application;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;

@Profile("local")
@Service
public class ConsoleEmailService implements EmailService {

@Override
public String sendEmail(String email) throws MessagingException, UnsupportedEncodingException {

// TODO(아무것도 안할거임!)

return "LOCAL_CODE";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.itcontest.skhuming.email.application;

import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;

public interface EmailService {

String sendEmail(String email) throws MessagingException, UnsupportedEncodingException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.itcontest.skhuming.email.application;

import com.itcontest.skhuming.email.exception.InvalidEmailAddressException;
import com.itcontest.skhuming.member.domain.repository.MemberRepository;
import com.itcontest.skhuming.member.exception.InvalidMemberException;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Profile;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

@Profile("prod")
@Transactional
@RequiredArgsConstructor
@Service
public class ProdEmailService implements EmailService {

private static final String EMAIL_FORMAT = "^[a-zA-Z0-9._%+-]+@office\\.skhu\\.ac\\.kr$";

private final JavaMailSender emailSender;
private String authNum; // 인증 번호

private final MemberRepository memberRepository;

// 인증번호 6자리 무작위 생성
private void createCode() {
SecureRandom random = new SecureRandom();
StringBuilder key = new StringBuilder();

String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int length = characters.length();

for (int i = 0; i < 6; i++) {
int idx = random.nextInt(length);
key.append(characters.charAt(idx));
}

authNum = key.toString();
}

// 메일 양식 작성
private MimeMessage createEmailForm(String email) throws MessagingException, UnsupportedEncodingException {
createCode();
String setFrom = "skhuming"; // 보내는 사람
String toEmail = email;
String title = "Skhuming 재학생 인증 메일";// 제목

validateDuplicateEmail(email);

boolean isMatch = toEmail.matches(EMAIL_FORMAT);
validateEmail(isMatch);

MimeMessage message = emailSender.createMimeMessage();
message.addRecipients(MimeMessage.RecipientType.TO, toEmail);
message.setSubject(title);

// 메일 내용
String msgOfEmail = mailContents();

message.setFrom(setFrom);
message.setText(msgOfEmail, "utf-8", "html");

return message;
}

private void validateDuplicateEmail(String email) {
if (memberRepository.existsByEmail(email)) {
throw new InvalidMemberException("이미 사용중인 이메일 입니다.");
}
}

private void validateEmail(boolean isMatch) {
if (!isMatch) {
throw new InvalidEmailAddressException();
}
}

private String mailContents() {
return "<div style='margin:20px;'>" +
"<h1> 👋🏻 Skhuming 재학생 인증 메일 </h1><br>" +
"<p>Skhuming은 성공회대학교 학생만 사용할 수 있는 서비스로, </p>" +
"<p>성공회대 office 365 메일로 재학생 인증 후 사용하실 수 있습니다. </p><br>" +
"<p>아래의 코드를 인증 코드란에 적고 재학생 인증을 마쳐주세요.<p><br>" +
"<div align='center' style='border:1px solid black; font-family:verdana';>" +
"<div style='font-size:130%'>" +
"<strong><br>" +
authNum +
"</strong><div><br/> " +
"</div>";
}

@Override
public String sendEmail(String email) throws MessagingException, UnsupportedEncodingException {

//메일전송에 필요한 정보 설정
MimeMessage emailForm = createEmailForm(email);
//실제 메일 전송
emailSender.send(emailForm);

return authNum; //인증 코드 반환
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.itcontest.skhuming.email.exception;

public class InvalidEmailAddressException extends RuntimeException{

public InvalidEmailAddressException(String message) {
super(message);
}

public InvalidEmailAddressException() {
this("이메일 형식이 올바르지 않습니다.");
}
}
Loading

0 comments on commit 1cca2ee

Please sign in to comment.