diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/request/OrgRequest.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/request/OrgRequest.java index c29ed56..e3166dc 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/request/OrgRequest.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/request/OrgRequest.java @@ -1,5 +1,6 @@ package com.whereyouad.WhereYouAd.domains.organization.application.dto.request; +import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; public class OrgRequest { @@ -22,4 +23,9 @@ public record Update ( String logoUrl ) {} + public record Invite( + @NotBlank(message = "이메일은 필수입니다.") + @Email(message = "이메일 형식이 올바르지 않습니다.") + String email + ) {} } diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/response/OrgResponse.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/response/OrgResponse.java index f87b707..3152901 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/response/OrgResponse.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/dto/response/OrgResponse.java @@ -68,4 +68,10 @@ public record OrgMemberDTO( String profileImageUrl, String role ) {} + + public record OrgInvitationResponse( + Long orgId, + String message, + String email + ) {} } \ No newline at end of file diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/mapper/OrgMemberConverter.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/mapper/OrgMemberConverter.java index 73f5f16..42ec122 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/mapper/OrgMemberConverter.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/application/mapper/OrgMemberConverter.java @@ -5,14 +5,25 @@ import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.Organization; import com.whereyouad.WhereYouAd.domains.user.persistence.entity.User; +import java.time.LocalDateTime; + public class OrgMemberConverter { public static OrgMember toOrgMemberADMIN(User user, Organization organization) { return OrgMember.builder() .user(user) .organization(organization) - .joinedAt(organization.getCreatedAt()) //생성한 사람의 조직 합류 시간은 조직 생성 시간과 동일 - .role(OrgRole.ADMIN) //생성한 사람은 ADMIN + .joinedAt(organization.getCreatedAt()) // 생성한 사람의 조직 합류 시간은 조직 생성 시간과 동일 + .role(OrgRole.ADMIN) // 생성한 사람은 ADMIN + .build(); + } + + public static OrgMember toOrgMemberMEMBER(User user, Organization organization) { + return OrgMember.builder() + .user(user) + .organization(organization) + .joinedAt(LocalDateTime.now()) // 조직 초대 완료 시점 + .role(OrgRole.MEMBER) // 초대된 사람은 MEMBER (default) .build(); } } diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgService.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgService.java index 0ae762f..504257f 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgService.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgService.java @@ -21,4 +21,8 @@ public interface OrgService { // orgId 조직에서 memberId에 해당하는 맴버 제거 void removeMemberFromOrg(Long userId, Long orgId, Long memberId); + + OrgResponse.OrgInvitationResponse sendOrgInvitation(Long userId, Long orgId, String email); + + OrgResponse.OrgInvitationResponse acceptOrgInvitation(Long userId, String token); } diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgServiceImpl.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgServiceImpl.java index 7033239..ba4c3db 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgServiceImpl.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/domain/service/OrgServiceImpl.java @@ -12,16 +12,19 @@ import com.whereyouad.WhereYouAd.domains.organization.persistence.entity.Organization; import com.whereyouad.WhereYouAd.domains.organization.persistence.repository.OrgMemberRepository; import com.whereyouad.WhereYouAd.domains.organization.persistence.repository.OrgRepository; +import com.whereyouad.WhereYouAd.domains.user.domain.service.EmailService; import com.whereyouad.WhereYouAd.domains.user.exception.code.UserErrorCode; import com.whereyouad.WhereYouAd.domains.user.exception.handler.UserHandler; import com.whereyouad.WhereYouAd.domains.user.persistence.entity.User; import com.whereyouad.WhereYouAd.domains.user.persistence.repository.UserRepository; +import com.whereyouad.WhereYouAd.global.utils.RedisUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Objects; +import java.util.UUID; @Service @Transactional @@ -32,6 +35,9 @@ public class OrgServiceImpl implements OrgService { private final OrgMemberRepository orgMemberRepository; private final UserRepository userRepository; + private final RedisUtil redisUtil; + private final EmailService emailService; + // 조직(워크스페이스) 생성 메서드 public OrgResponse.Create createOrganization(Long userId, OrgRequest.Create request) { @@ -190,4 +196,77 @@ public void removeMemberFromOrg(Long userId, Long orgId, Long memberId) { // 5. 중간 테이블에서 해당 멤버 삭제 orgMemberRepository.delete(targetMember); } + + @Override + // 조직 초대 이메일 보내기 + public OrgResponse.OrgInvitationResponse sendOrgInvitation(Long userId, Long orgId, String email) { + Organization organization = orgRepository.findById(orgId) + .orElseThrow(() -> new OrgHandler(OrgErrorCode.ORG_NOT_FOUND)); + + // 초대자와 조직 관계 검증 (초대자가 조직의 멤버인지 확인) + User sender = userRepository.findById(userId) + .orElseThrow(() -> new UserHandler(UserErrorCode.USER_NOT_FOUND)); + + if (!orgMemberRepository.existsByUserAndOrganization(sender, organization)) { + // 초대자가 조직 멤버가 아님 -> 권한 없음 + throw new OrgHandler(OrgErrorCode.ORG_FORBIDDEN); + } + + // 초대 완료 여부 확인, 가입 여부에 상관 없이 이메일 발송 + userRepository.findUserByEmail(email).ifPresent(user -> { + if (orgMemberRepository.existsByUserAndOrganization(user, organization)) { + throw new OrgHandler(OrgErrorCode.ORG_MEMBER_ALREADY_ACTIVE); + } + }); + + // Redis key = 임의의 UUID 토큰(조직 초대 이메일 내 링크를 구별) + String token = UUID.randomUUID().toString(); + // Redis value = 조직 아이디와 이메일의 조합 + String value = orgId + ":" + email; + redisUtil.setDataExpire("INVITE:" + token, value, 3600 * 24L); + + emailService.sendEmailForOrgInvitation(token, email, organization.getName()); + + return new OrgResponse.OrgInvitationResponse(orgId, "조직 멤버 초대 이메일을 전송하였습니다.", email); + } + + @Override + // 조직 초대 수락 (이메일 내 링크 클릭 시) + public OrgResponse.OrgInvitationResponse acceptOrgInvitation(Long userId, String token) { + // 링크 만료 또는 유효하지 않을 시 + if (token == null) + throw new OrgHandler(OrgErrorCode.ORG_INVITATION_INVALID); + + // Redis 내 UUID(key)에 대한 email(value) 비교 + String value = redisUtil.getData("INVITE:" + token); + if (value == null) { + throw new OrgHandler(OrgErrorCode.ORG_INVITATION_INVALID); + } + + String[] valueForSplit = value.split(":"); + String email = valueForSplit[1]; + + // 로그인한 사용자 검증 + User user = userRepository.findById(userId) + .orElseThrow(() -> new UserHandler(UserErrorCode.USER_NOT_FOUND)); + + // 초대된 이메일과 현재 로그인한 사용자의 이메일이 일치하는지 확인 + if (!user.getEmail().equals(email)) { + throw new OrgHandler(OrgErrorCode.ORG_INVITATION_FORBIDDEN_USER); + } + + Organization organization = orgRepository.findById(Long.parseLong(valueForSplit[0])) + .orElseThrow(() -> new OrgHandler(OrgErrorCode.ORG_NOT_FOUND)); + + // 이미 멤버인지 중복 체크 + if (orgMemberRepository.existsByUserAndOrganization(user, organization)) + throw new OrgHandler(OrgErrorCode.ORG_MEMBER_ALREADY_ACTIVE); + + orgMemberRepository.save(OrgMemberConverter.toOrgMemberMEMBER(user, organization)); + + // Redis 사용 토큰 삭제 + redisUtil.deleteData("INVITE:" + token); + + return new OrgResponse.OrgInvitationResponse(organization.getId(), "조직 멤버 초대 이메일을 수락하였습니다.", email); + } } diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/exception/code/OrgErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/exception/code/OrgErrorCode.java index fca280f..c08f747 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/exception/code/OrgErrorCode.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/exception/code/OrgErrorCode.java @@ -24,9 +24,17 @@ public enum OrgErrorCode implements BaseErrorCode { //409 ORG_ALREADY_ACTIVE(HttpStatus.CONFLICT, "ORG_409_1", "해당 조직은 이미 활성화 상태 입니다."), - //410 ORG_SOFT_DELETED(HttpStatus.GONE, "ORG_410_1", "해당 조직은 삭제된 조직입니다.(Soft Delete)"), + + // 409 + ORG_MEMBER_ALREADY_ACTIVE(HttpStatus.CONFLICT, "ORG_MEMBER_409_1", "이미 해당 조직에 초대되어있습니다."), + + // 400 + ORG_INVITATION_INVALID(HttpStatus.BAD_REQUEST, "ORG_INVITATION_400", "조직 초대 토큰이 만료되었거나 유효하지 않습니다."), + + // 403 + ORG_INVITATION_FORBIDDEN_USER(HttpStatus.FORBIDDEN, "ORG_INVITATION_403_1", "초대된 이메일과 현재 로그인한 사용자의 이메일이 일치하지 않습니다."), ; private final HttpStatus httpStatus; diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/persistence/repository/OrgMemberRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/persistence/repository/OrgMemberRepository.java index c3ac8f5..4197524 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/persistence/repository/OrgMemberRepository.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/persistence/repository/OrgMemberRepository.java @@ -56,4 +56,6 @@ int countByOrganizationIdAndUserStatus( @Param("orgId") Long orgId, @Param("status") UserStatus status ); + + Boolean existsByUserAndOrganization(User user, Organization organization); } \ No newline at end of file diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/OrgController.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/OrgController.java index 77b8ded..7072404 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/OrgController.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/OrgController.java @@ -53,7 +53,6 @@ public ResponseEntity> getOrganizationDetail ); } - @PatchMapping("/{orgId}") public ResponseEntity> modifyOrganization( @AuthenticationPrincipal(expression = "userId") Long userId, @@ -125,4 +124,20 @@ public ResponseEntity> removeMember( orgService.removeMemberFromOrg(userId, orgId, memberId); return ResponseEntity.ok(DataResponse.from("해당 맴버가 조직에서 제외되었습니다.")); } + + @PostMapping("/members/{orgId}/invitation") + public ResponseEntity> sendOrgInvitation( + @AuthenticationPrincipal(expression = "userId") Long userId, @PathVariable Long orgId, + @RequestBody @Valid OrgRequest.Invite request) { + OrgResponse.OrgInvitationResponse orgInvitationResponse = orgService.sendOrgInvitation(userId, orgId, + request.email()); + return ResponseEntity.ok(DataResponse.from(orgInvitationResponse)); + } + + @PostMapping("/invitations/{token}") + public ResponseEntity> acceptOrgInvitation( + @AuthenticationPrincipal(expression = "userId") Long userId, @PathVariable String token) { + OrgResponse.OrgInvitationResponse orgInvitationResponse = orgService.acceptOrgInvitation(userId, token); + return ResponseEntity.ok(DataResponse.from(orgInvitationResponse)); + } } \ No newline at end of file diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/docs/OrgControllerDocs.java b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/docs/OrgControllerDocs.java index f6269a5..ac356c4 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/docs/OrgControllerDocs.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/organization/presentation/docs/OrgControllerDocs.java @@ -134,4 +134,30 @@ public ResponseEntity> removeMember( @PathVariable Long orgId, @PathVariable Long memberId ); + + @Operation(summary = "조직 초대 이메일 발송 API", description = "조직 관리자가 이메일을 입력하여 새로운 멤버를 초대합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "401", description = "로그인 필요"), + @ApiResponse(responseCode = "403", description = "조직 멤버가 아닌 사용자의 요청"), + @ApiResponse(responseCode = "404", description = "조직을 찾을 수 없음"), + @ApiResponse(responseCode = "409", description = "이미 조직에 가입된 사용자") + }) + public ResponseEntity> sendOrgInvitation( + @AuthenticationPrincipal(expression = "userId") Long userId, + @PathVariable Long orgId, + @RequestBody @Valid OrgRequest.Invite request + ); + + @Operation(summary = "조직 초대 수락 API", description = "이메일로 받은 초대 토큰을 통해 조직 가입을 수락합니다. (로그인 필수, 본인 확인)") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "유효하지 않거나 만료된 토큰"), + @ApiResponse(responseCode = "401", description = "로그인 필요"), + @ApiResponse(responseCode = "403", description = "초대된 이메일과 로그인한 사용자가 불일치") + }) + public ResponseEntity> acceptOrgInvitation( + @AuthenticationPrincipal(expression = "userId") Long userId, + @PathVariable String token + ); } \ No newline at end of file diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/user/domain/service/EmailService.java b/src/main/java/com/whereyouad/WhereYouAd/domains/user/domain/service/EmailService.java index ad7ff56..ac54b53 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/user/domain/service/EmailService.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/user/domain/service/EmailService.java @@ -24,14 +24,17 @@ public class EmailService { private final RedisUtil redisUtil; private final UserRepository userRepository; - //application.yml 적용 필요 + // application.yml 적용 필요 @Value("${spring.mail.username}") private String senderEmail; - //인증코드 이메일 발송 로직 (최초 회원가입 시) + @Value("${spring.application.base-url}") + private String baseUrl; + + // 인증코드 이메일 발송 로직 (최초 회원가입 시) public EmailSentResponse sendEmail(String toEmail) { - if (userRepository.existsByEmail(toEmail)) { //이미 해당 이메일로 생성한 계정이 있으면 - throw new UserHandler(UserErrorCode.USER_EMAIL_DUPLICATE); //이메일 중복 예외(회원가입 시 사용했던 예외) + if (userRepository.existsByEmail(toEmail)) { // 이미 해당 이메일로 생성한 계정이 있으면 + throw new UserHandler(UserErrorCode.USER_EMAIL_DUPLICATE); // 이메일 중복 예외(회원가입 시 사용했던 예외) } String type = "회원가입"; @@ -39,87 +42,103 @@ public EmailSentResponse sendEmail(String toEmail) { return emailSendTemplate(toEmail, type); } - //비밀번호 재설정을 위한 인증코드 이메일 발송 로직 (이미 회원가입 된 상태에서 비밀번호 재설정) + // 비밀번호 재설정을 위한 인증코드 이메일 발송 로직 (이미 회원가입 된 상태에서 비밀번호 재설정) public EmailSentResponse sendEmailForPwd(String toEmail) { - if (userRepository.existsByEmail(toEmail)) { //이미 회원가입 되어있는 것이 확인되면 + if (userRepository.existsByEmail(toEmail)) { // 이미 회원가입 되어있는 것이 확인되면 String type = "비밀번호 재설정"; - return emailSendTemplate(toEmail, type); //정상적으로 이메일 발송 - } else { //만약 회원가입 되어있지 않다면 - throw new UserHandler(UserErrorCode.USER_NOT_FOUND); //예외발생 + return emailSendTemplate(toEmail, type); // 정상적으로 이메일 발송 + } else { // 만약 회원가입 되어있지 않다면 + throw new UserHandler(UserErrorCode.USER_NOT_FOUND); // 예외발생 } } - //기존 이메일 발송 로직 템플릿 화 + // 조직 멤버 초대 이메일 발송 + public void sendEmailForOrgInvitation(String token, String toEmail, String orgName) { + try { + // 이메일 전송 + SimpleMailMessage message = new SimpleMailMessage(); + message.setTo(toEmail); + + message.setSubject("[Where You Ad] 조직 " + orgName + "에 초대 되었습니다."); + message.setText(baseUrl + "/api/org/invitations/" + token); + message.setFrom(senderEmail); + + emailSender.send(message); + } catch (MailException e) { // 예외 발생 + throw new UserHandler(UserErrorCode.USER_EMAIL_NOT_VALID); // 통합 응답 처리 예외로 반환 + } + } + + // 기존 이메일 발송 로직 템플릿 화 private EmailSentResponse emailSendTemplate(String toEmail, String type) { - //인증코드 재전송 로직 -> 이미 Redis 에 해당 이메일 인증코드가 있을시 삭제 + // 인증코드 재전송 로직 -> 이미 Redis 에 해당 이메일 인증코드가 있을시 삭제 String redisKey = "CODE:" + toEmail; if (redisUtil.getData(redisKey) != null) { redisUtil.deleteData(redisKey); } - String authCode = createCode(); //인증코드 생성 + String authCode = createCode(); // 인증코드 생성 if (isTestEmail(toEmail)) { - //테스트용 가짜 이메일은 서버 로그로만 인증코드를 보여주기 - //실제 이메일 발송 X - //존재하지 않는 이메일 주소로 계속 이메일을 보내면 인증코드 전송용 이메일 계정이 스팸처리 될 가능성 존재하여 로그로 남기기 + // 테스트용 가짜 이메일은 서버 로그로만 인증코드를 보여주기 + // 실제 이메일 발송 X + // 존재하지 않는 이메일 주소로 계속 이메일을 보내면 인증코드 전송용 이메일 계정이 스팸처리 될 가능성 존재하여 로그로 남기기 log.warn("{} 이메일 -> 테스트 or 개발용 가짜 이메일 입니다.", toEmail); log.warn("[TEST 모드] 실제 발송을 건너뜁니다."); log.warn("[TEST 모드] 수신자: {}", toEmail); log.warn("[TEST 모드] 인증코드: {}", authCode); - } else { //실제 존재하는 이메일이라면 + } else { // 실제 존재하는 이메일이라면 try { - //실제 인증 코드가 담긴 이메일 전송 + // 실제 인증 코드가 담긴 이메일 전송 SimpleMailMessage message = new SimpleMailMessage(); message.setTo(toEmail); - //어떤 유형의 인증(최초 회원가입 or 비밀번호 재설정) 인지 구분하여 인증코드 발송 + // 어떤 유형의 인증(최초 회원가입 or 비밀번호 재설정) 인지 구분하여 인증코드 발송 message.setSubject("whereyouad " + type + " 인증번호"); - message.setText("[Where You Ad] " + type + "\n 인증 번호는 [" + authCode + "] 입니다."); + message.setText("[Where You Ad] " + type + "\n 인증 번호는 [" + authCode + "] 입니다."); message.setFrom(senderEmail); - emailSender.send(message); //만약 실제 존재하는 이메일인데 사용자가 오타를 냈다면 - } catch (MailException e) { //예외 발생 - throw new UserHandler(UserErrorCode.USER_EMAIL_NOT_VALID); //통합 응답 처리 예외로 반환 + emailSender.send(message); // 만약 실제 존재하는 이메일인데 사용자가 오타를 냈다면 + } catch (MailException e) { // 예외 발생 + throw new UserHandler(UserErrorCode.USER_EMAIL_NOT_VALID); // 통합 응답 처리 예외로 반환 } - } - //Redis에 저장 (Key: "CODE:이메일", Value: "123456", 유효시간: 180초(3분)) - //테스트 계정도 인증은 해야하니 Redis 에 코드가 저장 되어야 함. - //테스트 계정의 인증은 서버 로그를 통해 인증코드를 얻어 입력. + // Redis에 저장 (Key: "CODE:이메일", Value: "123456", 유효시간: 180초(3분)) + // 테스트 계정도 인증은 해야하니 Redis 에 코드가 저장 되어야 함. + // 테스트 계정의 인증은 서버 로그를 통해 인증코드를 얻어 입력. redisUtil.setDataExpire("CODE:" + toEmail, authCode, 60 * 3L); return new EmailSentResponse("인증코드를 이메일로 전송했습니다.", toEmail, 180L); } - //인증코드 검증 메서드 + // 인증코드 검증 메서드 public void verifyEmailCode(String email, String inputCode) { - //해당 이메일 값으로 Redis 에서 조회 + // 해당 이메일 값으로 Redis 에서 조회 String key = "CODE:" + email; String savedCode = redisUtil.getData(key); - //만약 인증코드가 없거나 잘못 입력했다면, + // 만약 인증코드가 없거나 잘못 입력했다면, if (savedCode == null || !savedCode.equals(inputCode)) { - throw new UserHandler(UserErrorCode.USER_EMAIL_AUTH_INVALID); //예외 발생(BAD_REQUEST) + throw new UserHandler(UserErrorCode.USER_EMAIL_AUTH_INVALID); // 예외 발생(BAD_REQUEST) } - //정상적으로 인증코드를 입력했다면, - //기존 Redis 에 저장된 데이터를 지우고, + // 정상적으로 인증코드를 입력했다면, + // 기존 Redis 에 저장된 데이터를 지우고, redisUtil.deleteData(key); - //"해당 이메일이 정상적으로 인증되었다" 는 값을 다시 Redis 에 저장 -> 이후 회원가입(signup) 내부 로직에서 활용 - redisUtil.setDataExpire("VERIFIED:" + email, "TRUE", 60 * 60L); //1시간 뒤 Expire + // "해당 이메일이 정상적으로 인증되었다" 는 값을 다시 Redis 에 저장 -> 이후 회원가입(signup) 내부 로직에서 활용 + redisUtil.setDataExpire("VERIFIED:" + email, "TRUE", 60 * 60L); // 1시간 뒤 Expire } - //테스트용 이메일은, "test" 로 시작하거나, "example.com" 으로 끝나야 한다. + // 테스트용 이메일은, "test" 로 시작하거나, "example.com" 으로 끝나야 한다. private boolean isTestEmail(String email) { return email.startsWith("test") || email.endsWith("example.com"); } - //무작위 인증코드 값 생성 + // 무작위 인증코드 값 생성 private String createCode() { - return String.valueOf((int)(Math.random() * (900000)) + 100000); + return String.valueOf((int) (Math.random() * (900000)) + 100000); } } diff --git a/src/main/java/com/whereyouad/WhereYouAd/domains/user/presentation/AuthController.java b/src/main/java/com/whereyouad/WhereYouAd/domains/user/presentation/AuthController.java index e34e374..cdda499 100644 --- a/src/main/java/com/whereyouad/WhereYouAd/domains/user/presentation/AuthController.java +++ b/src/main/java/com/whereyouad/WhereYouAd/domains/user/presentation/AuthController.java @@ -2,6 +2,7 @@ import com.whereyouad.WhereYouAd.domains.user.application.dto.request.LoginRequest; import com.whereyouad.WhereYouAd.domains.user.domain.service.AuthService; +import com.whereyouad.WhereYouAd.domains.user.domain.service.EmailService; import com.whereyouad.WhereYouAd.domains.user.presentation.docs.AuthControllerDocs; import com.whereyouad.WhereYouAd.global.response.DataResponse; import com.whereyouad.WhereYouAd.global.security.jwt.dto.TokenResponse; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ae71d21..8a88ab3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,8 @@ server: spring: application: name: WhereYouAd + # 서버 기본 주소 + base-url: ${BASE_URL:http://localhost:8080} # 1. 데이터베이스 설정 datasource: