From 0ec1cd5d53d3e3f513e3e58d707de2e6fe0c04ab Mon Sep 17 00:00:00 2001 From: qnfn120 <101265039+genius00hwan@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:20:57 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[COZY-440]=20feat=20:=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=EC=97=90=EA=B2=8C=20=EB=A9=94=EC=9D=BC=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mail/controller/MailController.java | 12 +++++ .../domain/mail/service/MailService.java | 49 ++++++++++++++----- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/cozymate/cozymate_server/domain/mail/controller/MailController.java b/src/main/java/com/cozymate/cozymate_server/domain/mail/controller/MailController.java index afacf955..6bd29889 100644 --- a/src/main/java/com/cozymate/cozymate_server/domain/mail/controller/MailController.java +++ b/src/main/java/com/cozymate/cozymate_server/domain/mail/controller/MailController.java @@ -9,6 +9,7 @@ import com.cozymate.cozymate_server.global.response.ApiResponse; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; @@ -20,6 +21,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/members/mail") +@Slf4j public class MailController { private final MailService mailService; @@ -62,4 +64,14 @@ public ResponseEntity> isVerified( ApiResponse.onSuccess(mailService.isVerified(memberDetails.member()))); } + @PostMapping("/test") + @Operation(summary = "[말즈] 관리자 메일 테스트", description = "관리자에게 메일 보내기 테스트") + @Deprecated + public ResponseEntity> testMail( + ) { + log.info("controller 진입 성공"); + mailService.sendCustomMailToAdmin("제목", "내용"); + return ResponseEntity.ok(ApiResponse.onSuccess(true)); + } + } diff --git a/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java b/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java index 8fa184f8..ddf141cf 100644 --- a/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java +++ b/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java @@ -2,6 +2,7 @@ import com.cozymate.cozymate_server.domain.auth.dto.TokenResponseDTO; +import com.cozymate.cozymate_server.domain.auth.service.AuthService; import com.cozymate.cozymate_server.domain.auth.userdetails.MemberDetails; import com.cozymate.cozymate_server.domain.mail.MailAuthentication; import com.cozymate.cozymate_server.domain.mail.converter.MailConverter; @@ -10,7 +11,7 @@ import com.cozymate.cozymate_server.domain.mail.dto.response.VerifyResponseDTO; import com.cozymate.cozymate_server.domain.mail.repository.MailRepository; import com.cozymate.cozymate_server.domain.member.Member; -import com.cozymate.cozymate_server.domain.member.service.MemberCommandService; +import com.cozymate.cozymate_server.domain.member.repository.MemberRepository; import com.cozymate.cozymate_server.domain.university.University; import com.cozymate.cozymate_server.domain.university.repository.UniversityRepository; import com.cozymate.cozymate_server.global.response.code.status.ErrorStatus; @@ -26,6 +27,7 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; @@ -40,8 +42,15 @@ public class MailService { private static final Integer MAIL_AUTHENTICATION_EXPIRED_TIME = 30; private final JavaMailSender mailSender; private final MailRepository mailRepository; - private final MemberCommandService memberCommandService; + private final MemberRepository memberRepository; private final UniversityRepository universityRepository; + private final AuthService authService; + + @Value("${spring.mail.username}") + private static final String ADMIN_MAIL_USERNAME = "qnfn120"; + + private static final String ADMIN_MAIL_DOMAIN = "@gmail.com"; // 관리자 이메일 주소 + @Transactional public void sendUniversityAuthenticationCode(MemberDetails memberDetails, @@ -61,26 +70,41 @@ public void sendUniversityAuthenticationCode(MemberDetails memberDetails, @Transactional public VerifyResponseDTO verifyMemberUniversity(MemberDetails memberDetails, VerifyRequestDTO verifyDTO) { - Member member = memberDetails.member(); + University memberUniversity = universityRepository.findById(verifyDTO.universityId()) + .orElseThrow(() -> new GeneralException(ErrorStatus._UNIVERSITY_NOT_FOUND)); - verifyAuthenticationCode(member, verifyDTO.code()); + memberDetails.member().verifyMemberUniversity(memberUniversity, verifyDTO.majorName()); + memberRepository.save(memberDetails.member()); - TokenResponseDTO tokenResponseDTO = memberCommandService.verifyMemberUniversity( - memberDetails, - verifyDTO.universityId(), - verifyDTO.majorName()); + TokenResponseDTO tokenResponseDTO = authService.generateMemberTokenDTO(memberDetails); return MailConverter.toVerifyResponseDTO(tokenResponseDTO); } public String isVerified(Member member) { Optional mailAuthentication = mailRepository.findById(member.getId()); - if (mailAuthentication.isPresent() && Boolean.TRUE.equals(mailAuthentication.get().getIsVerified())) { + if (mailAuthentication.isPresent() && Boolean.TRUE.equals( + mailAuthentication.get().getIsVerified())) { return mailAuthentication.get().getMailAddress(); } return ""; } + public void sendCustomMailToAdmin(String subject, String content) { + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setTo(ADMIN_MAIL_USERNAME + ADMIN_MAIL_DOMAIN); + helper.setSubject(subject); + helper.setText(content, true); // 전달받은 content를 그대로 전송 + mailSender.send(message); + + } catch (MessagingException e) { + throw new GeneralException(ErrorStatus._MAIL_SEND_FAIL); + } + } + private void verifyAuthenticationCode(Member member, String requestCode) { MailAuthentication mailAuthentication = mailRepository.findById(member.getId()) @@ -101,13 +125,14 @@ private void verifyAuthenticationCode(Member member, String requestCode) { mailAuthentication.verify(); } - private MailAuthentication createAndSendMail(Long memberId, String mailAddress, String universityName) { + private MailAuthentication createAndSendMail(Long memberId, String mailAddress, + String universityName) { String authenticationCode = Base64.getEncoder() .encodeToString(UUID.randomUUID().toString().getBytes()) .substring(0, 6); - String emailBody = makeMailBody(authenticationCode,universityName); + String emailBody = makeMailBody(authenticationCode, universityName); try { MimeMessage message = mailSender.createMimeMessage(); @@ -120,7 +145,7 @@ private MailAuthentication createAndSendMail(Long memberId, String mailAddress, return MailConverter.toMailAuthenticationWithParams(memberId, mailAddress, authenticationCode, false); - }catch (MessagingException e){ + } catch (MessagingException e) { throw new GeneralException(ErrorStatus._MAIL_SEND_FAIL); } } From ffb5c15d0621123dd45bc1b30d6eb05fbf6b08f4 Mon Sep 17 00:00:00 2001 From: qnfn120 <101265039+genius00hwan@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:21:19 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[COZY-440]=20feat=20:=20=ED=83=88=ED=87=B4?= =?UTF-8?q?=20Request=20dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 6 ++++-- .../domain/member/dto/request/WithdrawRequestDTO.java | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/cozymate/cozymate_server/domain/member/dto/request/WithdrawRequestDTO.java diff --git a/src/main/java/com/cozymate/cozymate_server/domain/member/controller/MemberController.java b/src/main/java/com/cozymate/cozymate_server/domain/member/controller/MemberController.java index 6b53ccba..1c276c95 100644 --- a/src/main/java/com/cozymate/cozymate_server/domain/member/controller/MemberController.java +++ b/src/main/java/com/cozymate/cozymate_server/domain/member/controller/MemberController.java @@ -3,6 +3,7 @@ import com.cozymate.cozymate_server.domain.auth.userdetails.MemberDetails; import com.cozymate.cozymate_server.domain.member.dto.request.SignInRequestDTO; import com.cozymate.cozymate_server.domain.member.dto.request.SignUpRequestDTO; +import com.cozymate.cozymate_server.domain.member.dto.request.WithdrawRequestDTO; import com.cozymate.cozymate_server.domain.member.dto.response.MemberDetailResponseDTO; import com.cozymate.cozymate_server.domain.member.dto.response.SignInResponseDTO; import com.cozymate.cozymate_server.domain.member.service.MemberCommandService; @@ -171,8 +172,9 @@ ResponseEntity> updateMajorName( @Operation(summary = "[말즈] 회원 탈퇴 API", description = "현재 로그인한 사용자를 탈퇴시킵니다.") @DeleteMapping("/withdraw") public ResponseEntity> withdraw( - @AuthenticationPrincipal MemberDetails memberDetails) { - memberCommandService.withdraw(memberDetails); + @AuthenticationPrincipal MemberDetails memberDetails, + @Valid WithdrawRequestDTO withdrawRequestDTO) { + memberCommandService.withdraw(withdrawRequestDTO,memberDetails); return ResponseEntity.ok(ApiResponse.onSuccess("회원 탈퇴가 완료되었습니다.")); } diff --git a/src/main/java/com/cozymate/cozymate_server/domain/member/dto/request/WithdrawRequestDTO.java b/src/main/java/com/cozymate/cozymate_server/domain/member/dto/request/WithdrawRequestDTO.java new file mode 100644 index 00000000..1fcd3d5a --- /dev/null +++ b/src/main/java/com/cozymate/cozymate_server/domain/member/dto/request/WithdrawRequestDTO.java @@ -0,0 +1,9 @@ +package com.cozymate.cozymate_server.domain.member.dto.request; + +import org.hibernate.validator.constraints.Length; + +public record WithdrawRequestDTO( + @Length(max = 100, message = "탈퇴 사유는 최대 100자") + String withdrawReason +) { +} From 94e2ebeb0fc2a6e4e0641e7633618a7cfe304bee Mon Sep 17 00:00:00 2001 From: qnfn120 <101265039+genius00hwan@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:21:50 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[COZY-440]=20feat=20:=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=ED=86=A0=ED=81=B0=20=EB=B0=9C=EA=B8=89=EC=8B=9C=20?= =?UTF-8?q?https=20=EC=B6=94=EA=B0=80=20cors=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cozymate/cozymate_server/global/utils/SwaggerFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/cozymate/cozymate_server/global/utils/SwaggerFilter.java b/src/main/java/com/cozymate/cozymate_server/global/utils/SwaggerFilter.java index a3706e34..c2481f88 100644 --- a/src/main/java/com/cozymate/cozymate_server/global/utils/SwaggerFilter.java +++ b/src/main/java/com/cozymate/cozymate_server/global/utils/SwaggerFilter.java @@ -39,6 +39,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } Cookie cookie = new Cookie("JWT", jwtUtil.generateAdminToken()); // 쿠키 이름 및 값 설정 cookie.setHttpOnly(true); // 클라이언트 측 스크립트에서 쿠키를 접근하지 못하게 함 + cookie.setSecure(true); cookie.setPath("/"); // 쿠키의 유효 범위 설정 cookie.setMaxAge(3600); // 쿠키의 만료 시간 설정 (예: 1시간) httpResponse.addCookie(cookie); // 응답에 쿠키 추가 From 71d9c9a78cdb89e010a790aa34a3b917df74fae6 Mon Sep 17 00:00:00 2001 From: qnfn120 <101265039+genius00hwan@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:22:26 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[COZY-440]=20fix=20:=20=ED=83=88=ED=87=B4?= =?UTF-8?q?=20=EC=8B=9C=20=ED=83=88=ED=87=B4=EC=82=AC=EC=9C=A0=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=B4=EB=82=B4=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/service/MemberCommandService.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/cozymate/cozymate_server/domain/member/service/MemberCommandService.java b/src/main/java/com/cozymate/cozymate_server/domain/member/service/MemberCommandService.java index c80efb42..4253d523 100644 --- a/src/main/java/com/cozymate/cozymate_server/domain/member/service/MemberCommandService.java +++ b/src/main/java/com/cozymate/cozymate_server/domain/member/service/MemberCommandService.java @@ -4,10 +4,12 @@ import com.cozymate.cozymate_server.domain.auth.service.AuthService; import com.cozymate.cozymate_server.domain.auth.userdetails.MemberDetails; import com.cozymate.cozymate_server.domain.auth.utils.ClientIdMaker; +import com.cozymate.cozymate_server.domain.mail.service.MailService; import com.cozymate.cozymate_server.domain.member.Member; import com.cozymate.cozymate_server.domain.member.converter.MemberConverter; import com.cozymate.cozymate_server.domain.member.dto.request.SignInRequestDTO; import com.cozymate.cozymate_server.domain.member.dto.request.SignUpRequestDTO; +import com.cozymate.cozymate_server.domain.member.dto.request.WithdrawRequestDTO; import com.cozymate.cozymate_server.domain.member.dto.response.MemberDetailResponseDTO; import com.cozymate.cozymate_server.domain.member.dto.response.SignInResponseDTO; import com.cozymate.cozymate_server.domain.member.enums.SocialType; @@ -36,6 +38,8 @@ public class MemberCommandService { private final MemberWithdrawService memberWithdrawService; + private final MailService mailService; + /** * 닉네임 유효성 검사 메서드 * @@ -111,17 +115,6 @@ public MemberDetailResponseDTO getMemberDetailInfo(MemberDetails memberDetails) return MemberConverter.toMemberDetailResponseDTOFromEntity(memberDetails.member()); } - @Transactional - public TokenResponseDTO verifyMemberUniversity(MemberDetails memberDetails, Long universityId, - String majorName) { - University memberUniversity = universityRepository.findById(universityId) - .orElseThrow(() -> new GeneralException(ErrorStatus._UNIVERSITY_NOT_FOUND)); - - memberDetails.member().verifyMemberUniversity(memberUniversity, majorName); - memberRepository.save(memberDetails.member()); - - return authService.generateMemberTokenDTO(memberDetails); - } @Transactional public void updateNickname(Member member, String nickname) { @@ -160,7 +153,11 @@ public void updateMajor(Member member, String majorName) { * * @param memberDetails 사용자 세부 정보 */ - public void withdraw(MemberDetails memberDetails) { + public void withdraw(WithdrawRequestDTO withdrawRequestDTO, MemberDetails memberDetails) { + String withdrawReason = withdrawRequestDTO.withdrawReason(); + String mailSubject = memberDetails.member().getNickname() + "탈퇴 사유"; + + mailService.sendCustomMailToAdmin(mailSubject, withdrawReason); memberWithdrawService.withdraw(memberDetails.member()); } From 553abc5d1273a0b690a889c3d4cf1679e6cd32ad Mon Sep 17 00:00:00 2001 From: qnfn120 <101265039+genius00hwan@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:56:42 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[COZY-440]=20fix=20:=20=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=A3=BC=EC=86=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cozymate_server/domain/mail/service/MailService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java b/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java index ddf141cf..d7377354 100644 --- a/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java +++ b/src/main/java/com/cozymate/cozymate_server/domain/mail/service/MailService.java @@ -47,7 +47,7 @@ public class MailService { private final AuthService authService; @Value("${spring.mail.username}") - private static final String ADMIN_MAIL_USERNAME = "qnfn120"; + private static final String ADMIN_MAIL_USERNAME = "cozymate0"; private static final String ADMIN_MAIL_DOMAIN = "@gmail.com"; // 관리자 이메일 주소