diff --git a/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java b/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java index 2363269c..1c150278 100644 --- a/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java +++ b/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java @@ -66,6 +66,8 @@ public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospe .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/login/social")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/sign-up")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/sign-up/email")).permitAll() + .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/search/**")).permitAll() + .requestMatchers(mvcMatcherBuilder.pattern("/intermediaries/search/**")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/intermediaries/phone/isDuplicated")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/intermediaries/sign-up/**")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/reissue-token")).permitAll() diff --git a/src/main/java/com/pawwithu/connectdog/domain/auth/controller/SignUpController.java b/src/main/java/com/pawwithu/connectdog/domain/auth/controller/SignUpController.java index 4dac2636..3eacb62b 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/auth/controller/SignUpController.java +++ b/src/main/java/com/pawwithu/connectdog/domain/auth/controller/SignUpController.java @@ -1,10 +1,7 @@ package com.pawwithu.connectdog.domain.auth.controller; import com.pawwithu.connectdog.domain.auth.dto.request.*; -import com.pawwithu.connectdog.domain.auth.dto.response.EmailResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryNameResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryPhoneResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.VolunteerPhoneResponse; +import com.pawwithu.connectdog.domain.auth.dto.response.*; import com.pawwithu.connectdog.domain.auth.service.AuthService; import com.pawwithu.connectdog.domain.auth.service.EmailService; import com.pawwithu.connectdog.error.dto.ErrorResponse; @@ -122,4 +119,40 @@ public ResponseEntity isIntermediaryNameDuplicated(@Re IntermediaryNameResponse response = authService.isIntermediaryNameDuplicated(request); return ResponseEntity.ok(response); } + + @Operation(summary = "이메일 찾기 - 봉사자 휴대폰 번호로 이메일 찾기", description = "봉사자 휴대폰 번호로 이메일을 찾습니다.", + responses = {@ApiResponse(responseCode = "200", description = "봉사자 휴대폰 번호로 이메일 찾기 성공") + , @ApiResponse(responseCode = "400" + , description = "V1, 휴대폰 번호는 필수 입력 값입니다. \t\n M1, 해당 이동봉사자를 찾을 수 없습니다." + , content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + @PostMapping("/volunteers/search/email") + public ResponseEntity findVolunteerEmail(@RequestBody @Valid VolunteerPhoneRequest request) { + VolunteerEmailResponse response = authService.findVolunteerEmail(request); + return ResponseEntity.ok(response); + } + + @Operation(summary = "이메일 찾기 - 모집자 휴대폰 번호로 이메일 찾기", description = "모집자 휴대폰 번호로 이메일을 찾습니다.", + responses = {@ApiResponse(responseCode = "200", description = "모집자 휴대폰 번호로 이메일 찾기 성공") + , @ApiResponse(responseCode = "400" + , description = "V1, 휴대폰 번호는 필수 입력 값입니다. \t\n M2, 해당 이동봉사 중개를 찾을 수 없습니다." + , content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + @PostMapping("/intermediaries/search/email") + public ResponseEntity findIntermediaryEmail(@RequestBody @Valid IntermediaryPhoneRequest request) { + IntermediaryEmailResponse response = authService.findIntermediaryEmail(request); + return ResponseEntity.ok(response); + } + + @Operation(summary = "비밀번호 찾기 - 이메일 인증번호 전송", description = "입력한 이메일로 인증번호를 전송합니다.", + responses = {@ApiResponse(responseCode = "200", description = "이메일 인증번호 전송 성공") + , @ApiResponse(responseCode = "400" + , description = "V1, 이메일 형식에 맞지 않습니다. \t\n V1, 이메일은 필수 입력 값입니다. \t\n A1, 이미 존재하는 이메일입니다. \t\n A4, 이메일 인증 코드 전송을 실패했습니다." + , content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + @PostMapping(value = {"/volunteers/search/send-email", "/intermediaries/search/send-email"}) + public ResponseEntity sendEmail(@RequestBody @Valid EmailRequest request){ + EmailResponse emailResponse = emailService.sendEmailWithoutAuth(request); + return ResponseEntity.ok(emailResponse); + } } diff --git a/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/IntermediaryEmailResponse.java b/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/IntermediaryEmailResponse.java new file mode 100644 index 00000000..d8eb694f --- /dev/null +++ b/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/IntermediaryEmailResponse.java @@ -0,0 +1,7 @@ +package com.pawwithu.connectdog.domain.auth.dto.response; + +public record IntermediaryEmailResponse(String email) { + public static IntermediaryEmailResponse of(String email){ + return new IntermediaryEmailResponse(email); + } +} \ No newline at end of file diff --git a/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/VolunteerEmailResponse.java b/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/VolunteerEmailResponse.java new file mode 100644 index 00000000..eecd27a6 --- /dev/null +++ b/src/main/java/com/pawwithu/connectdog/domain/auth/dto/response/VolunteerEmailResponse.java @@ -0,0 +1,7 @@ +package com.pawwithu.connectdog.domain.auth.dto.response; + +public record VolunteerEmailResponse(String email) { + public static VolunteerEmailResponse of(String email){ + return new VolunteerEmailResponse(email); + } +} \ No newline at end of file diff --git a/src/main/java/com/pawwithu/connectdog/domain/auth/service/AuthService.java b/src/main/java/com/pawwithu/connectdog/domain/auth/service/AuthService.java index 39edd726..c0f8f3f2 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/auth/service/AuthService.java +++ b/src/main/java/com/pawwithu/connectdog/domain/auth/service/AuthService.java @@ -4,9 +4,7 @@ import com.pawwithu.connectdog.domain.application.entity.Application; import com.pawwithu.connectdog.domain.application.repository.ApplicationRepository; import com.pawwithu.connectdog.domain.auth.dto.request.*; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryNameResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryPhoneResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.VolunteerPhoneResponse; +import com.pawwithu.connectdog.domain.auth.dto.response.*; import com.pawwithu.connectdog.domain.badge.repository.VolunteerBadgeRepository; import com.pawwithu.connectdog.domain.bookmark.repository.BookmarkRepository; import com.pawwithu.connectdog.domain.fcm.repository.IntermediaryFcmRepository; @@ -203,4 +201,18 @@ public IntermediaryNameResponse isIntermediaryNameDuplicated(IntermediaryNameReq IntermediaryNameResponse response = IntermediaryNameResponse.of(isDuplicated); return response; } + + @Transactional(readOnly = true) + public VolunteerEmailResponse findVolunteerEmail(VolunteerPhoneRequest request) { + Volunteer volunteer = volunteerRepository.findByPhone(request.phone()).orElseThrow(() -> new BadRequestException(VOLUNTEER_NOT_FOUND)); + VolunteerEmailResponse response = VolunteerEmailResponse.of(volunteer.getEmail()); + return response; + } + + @Transactional(readOnly = true) + public IntermediaryEmailResponse findIntermediaryEmail(IntermediaryPhoneRequest request) { + Intermediary intermediary = intermediaryRepository.findByPhone(request.phone()).orElseThrow(() -> new BadRequestException(INTERMEDIARY_NOT_FOUND)); + IntermediaryEmailResponse response = IntermediaryEmailResponse.of(intermediary.getEmail()); + return response; + } } diff --git a/src/main/java/com/pawwithu/connectdog/domain/auth/service/EmailService.java b/src/main/java/com/pawwithu/connectdog/domain/auth/service/EmailService.java index 296bba09..eeaddeba 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/auth/service/EmailService.java +++ b/src/main/java/com/pawwithu/connectdog/domain/auth/service/EmailService.java @@ -103,4 +103,15 @@ private String setContext(String code) { context.setVariable("code", code); return templateEngine.process("mail", context); } + + public EmailResponse sendEmailWithoutAuth(EmailRequest request) throws BadRequestException { + try{ + // 메일전송에 필요한 정보 설정 + MimeMessage emailForm = createEmailForm(request.email()); + emailSender.send(emailForm); + return new EmailResponse(authNum); + }catch (UnsupportedEncodingException | MessagingException e){ + throw new BadRequestException(EMAIL_SEND_ERROR); + } + } } \ No newline at end of file diff --git a/src/test/java/com/pawwithu/connectdog/domain/auth/controller/SignUpControllerTest.java b/src/test/java/com/pawwithu/connectdog/domain/auth/controller/SignUpControllerTest.java index 595bd964..3763e2b0 100644 --- a/src/test/java/com/pawwithu/connectdog/domain/auth/controller/SignUpControllerTest.java +++ b/src/test/java/com/pawwithu/connectdog/domain/auth/controller/SignUpControllerTest.java @@ -2,10 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.pawwithu.connectdog.domain.auth.dto.request.*; -import com.pawwithu.connectdog.domain.auth.dto.response.EmailResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryNameResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.IntermediaryPhoneResponse; -import com.pawwithu.connectdog.domain.auth.dto.response.VolunteerPhoneResponse; +import com.pawwithu.connectdog.domain.auth.dto.response.*; import com.pawwithu.connectdog.domain.auth.service.AuthService; import com.pawwithu.connectdog.domain.auth.service.EmailService; import com.pawwithu.connectdog.domain.volunteer.entity.SocialType; @@ -169,4 +166,42 @@ void setUp() { result.andExpect(status().isOk()); verify(authService, times(1)).isIntermediaryNameDuplicated(request); } + + @Test + void 이동봉사자_이메일_찾기() throws Exception { + //given + VolunteerPhoneRequest request = new VolunteerPhoneRequest("01000001111"); + VolunteerEmailResponse response = new VolunteerEmailResponse("abc@naver.com"); + + //when + given(authService.findVolunteerEmail(request)).willReturn(response); + ResultActions result = mockMvc.perform( + post("/volunteers/search/email") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + ); + + //then + result.andExpect(status().isOk()); + verify(authService, times(1)).findVolunteerEmail(request); + } + + @Test + void 모집자_이메일_찾기() throws Exception { + //given + IntermediaryPhoneRequest request = new IntermediaryPhoneRequest("01000001111"); + IntermediaryEmailResponse response = new IntermediaryEmailResponse("abc@naver.com"); + + //when + given(authService.findIntermediaryEmail(request)).willReturn(response); + ResultActions result = mockMvc.perform( + post("/intermediaries/search/email") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + ); + + //then + result.andExpect(status().isOk()); + verify(authService, times(1)).findIntermediaryEmail(request); + } } \ No newline at end of file