Skip to content

Commit

Permalink
[MERGE/#91] #91 - 문자 발송 서비스 리팩토링
Browse files Browse the repository at this point in the history
[Refactor] #91 - 문자 발송 서비스 리팩토링
  • Loading branch information
seokbeom00 authored Jul 15, 2024
2 parents bd8f6c8 + 72e973b commit 0617fce
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.sopt.seonyakServer.domain.member.dto.SendCodeRequest;
import org.sopt.seonyakServer.domain.member.dto.VerifyCodeRequest;
import org.sopt.seonyakServer.domain.member.service.MemberService;
import org.sopt.seonyakServer.domain.member.service.MessageService;
import org.sopt.seonyakServer.global.common.external.client.dto.MemberLoginRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -25,7 +24,6 @@
public class MemberController {

private final MemberService memberService;
private final MessageService messageService;

@PostMapping("/auth/login")
public ResponseEntity<LoginSuccessResponse> login(
Expand Down Expand Up @@ -55,7 +53,7 @@ public ResponseEntity<Void> validNickname(
public ResponseEntity<Void> sendCode(
@Valid @RequestBody final SendCodeRequest sendCodeRequest
) {
messageService.sendMessage(sendCodeRequest);
memberService.sendMessage(sendCodeRequest);

return ResponseEntity.ok().build();
}
Expand All @@ -64,8 +62,7 @@ public ResponseEntity<Void> sendCode(
public ResponseEntity<Void> verifyCode(
@Valid @RequestBody final VerifyCodeRequest verifyCodeRequest
) {
messageService.verifyCode(verifyCodeRequest);
messageService.validPhoneNumberDuplication(verifyCodeRequest);
memberService.verifyCode(verifyCodeRequest);

return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
package org.sopt.seonyakServer.domain.member.service;

import jakarta.annotation.PostConstruct;
import java.util.Random;
import lombok.RequiredArgsConstructor;
import net.nurigo.sdk.NurigoApp;
import net.nurigo.sdk.message.model.Message;
import net.nurigo.sdk.message.request.SingleMessageSendingRequest;
import net.nurigo.sdk.message.service.DefaultMessageService;
import org.sopt.seonyakServer.domain.member.dto.LoginSuccessResponse;
import org.sopt.seonyakServer.domain.member.dto.MemberJoinRequest;
import org.sopt.seonyakServer.domain.member.dto.MemberJoinResponse;
import org.sopt.seonyakServer.domain.member.dto.NicknameRequest;
import org.sopt.seonyakServer.domain.member.dto.SendCodeRequest;
import org.sopt.seonyakServer.domain.member.dto.VerifyCodeRequest;
import org.sopt.seonyakServer.domain.member.model.Member;
import org.sopt.seonyakServer.domain.member.model.SocialType;
import org.sopt.seonyakServer.domain.member.repository.MemberRepository;
import org.sopt.seonyakServer.domain.senior.service.SeniorService;
import org.sopt.seonyakServer.global.auth.MemberAuthentication;
import org.sopt.seonyakServer.global.auth.PrincipalHandler;
import org.sopt.seonyakServer.global.auth.jwt.JwtTokenProvider;
import org.sopt.seonyakServer.global.auth.redis.service.CodeService;
import org.sopt.seonyakServer.global.common.external.client.dto.MemberInfoResponse;
import org.sopt.seonyakServer.global.common.external.client.dto.MemberLoginRequest;
import org.sopt.seonyakServer.global.common.external.client.service.GoogleSocialService;
import org.sopt.seonyakServer.global.exception.enums.ErrorType;
import org.sopt.seonyakServer.global.exception.model.CustomException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -31,8 +41,25 @@ public class MemberService {
private final GoogleSocialService googleSocialService;
private final MemberManagementService memberManagementService;
private final SeniorService seniorService;
private DefaultMessageService defaultMessageService;
private final CodeService codeService;

@Value("${coolsms.api.key}")
private String apiKey;

@Value("${coolsms.api.secret}")
private String apiSecret;

@Value("${coolsms.fromNumber}")
private String fromNumber;

private static final String NICKNAME_PATTERN = "^[a-zA-Z0-9가-힣]{2,8}$";
private static final String PHONE_NUMBER_PATTERN = "^010\\d{8}$";

@PostConstruct
public void init() {
this.defaultMessageService = NurigoApp.INSTANCE.initialize(apiKey, apiSecret, "https://api.coolsms.co.kr");
}

// JWT Access Token 생성
public LoginSuccessResponse create(
Expand Down Expand Up @@ -131,4 +158,53 @@ public MemberJoinResponse patchMemberJoin(MemberJoinRequest memberJoinRequest) {

return MemberJoinResponse.of(memberJoinRequest.role());
}

public void sendMessage(SendCodeRequest sendCodeRequest) {
Message message = new Message();

// 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 함.
String toNumber = sendCodeRequest.phoneNumber().replaceAll("-", "");

if (!toNumber.matches(PHONE_NUMBER_PATTERN)) {
throw new CustomException(ErrorType.INVALID_PHONE_NUMBER_ERROR);
}

message.setFrom(fromNumber);
message.setTo(toNumber);

String verificationCode = generateRandomNumber(4);
message.setText("[선약] 인증번호는 [" + verificationCode + "] 입니다.");

this.defaultMessageService.sendOne(new SingleMessageSendingRequest(message));
codeService.saveVerificationCode(toNumber, verificationCode);
}

// 인증번호를 위한 랜덤 숫자 생성
private String generateRandomNumber(int digitCount) {
Random random = new Random();
int min = (int) Math.pow(10, digitCount - 1);
int max = (int) Math.pow(10, digitCount) - 1;

return String.valueOf(random.nextInt((max - min) + 1) + min);
}

// 인증번호 일치 여부 확인
public void verifyCode(VerifyCodeRequest verifyCodeRequest) {
String number = verifyCodeRequest.phoneNumber().replaceAll("-", "");
if (verifyCodeRequest.verificationCode().equals(
codeService.findCodeByPhoneNumber(number))) {
codeService.deleteVerificationCode(number);

// 휴대전화 중복 체크
validPhoneNumberDuplication(number);
} else {
throw new CustomException(ErrorType.INVALID_VERIFICATION_CODE_ERROR);
}
}

private void validPhoneNumberDuplication(String phoneNumber) {
if (memberRepository.existsByPhoneNumber(phoneNumber)) {
throw new CustomException(ErrorType.PHONE_NUMBER_DUP_ERROR);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.sopt.seonyakServer.global.exception.enums.ErrorType;
import org.sopt.seonyakServer.global.exception.model.CustomException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

Expand All @@ -18,4 +19,14 @@ public ResponseEntity<ErrorType> handleBusinessException(CustomException e) {
.status(e.getErrorType().getHttpStatus())
.body(e.getErrorType());
}


// valid에서 발생한 예외
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorType> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error("GlobalExceptionHandler catch MethodArgumentNotValidException : {}", e.getMessage());
return ResponseEntity
.status(e.getStatusCode())
.body(ErrorType.INVALID_HTTP_REQUEST_ERROR);
}
}

0 comments on commit 0617fce

Please sign in to comment.