From f4a191f67fb89a3d0f926e4c36ae753ff1a25411 Mon Sep 17 00:00:00 2001 From: kyubeomHan Date: Thu, 2 Nov 2023 18:15:16 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feature=20:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=88=98=EC=A0=95=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/ExceptionList.java | 1 + .../user/controller/UserController.java | 10 ++--- ...hVerifyReq.java => UserEmailLoginReq.java} | 9 +++- .../dto/request/UserEmailSingReq.java | 41 +++++++++++++++++++ .../controller/dto/request/UserSingReq.java | 18 -------- .../controller/dto/response/UserLoginRes.java | 1 + .../everymeal/server/user/entity/User.java | 18 ++++---- .../user/repository/UserRepository.java | 1 + .../server/user/service/UserService.java | 10 ++--- .../server/user/service/UserServiceImpl.java | 25 +++++++---- .../user/controller/UserControllerTest.java | 12 +++--- .../user/service/UserServiceImplTest.java | 21 +++++----- 12 files changed, 108 insertions(+), 59 deletions(-) rename src/main/java/everymeal/server/user/controller/dto/request/{UserEmailAuthVerifyReq.java => UserEmailLoginReq.java} (62%) create mode 100644 src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java delete mode 100644 src/main/java/everymeal/server/user/controller/dto/request/UserSingReq.java diff --git a/src/main/java/everymeal/server/global/exception/ExceptionList.java b/src/main/java/everymeal/server/global/exception/ExceptionList.java index 2d6abb8..1f0ce5f 100644 --- a/src/main/java/everymeal/server/global/exception/ExceptionList.java +++ b/src/main/java/everymeal/server/global/exception/ExceptionList.java @@ -18,6 +18,7 @@ public enum ExceptionList { USER_NOT_FOUND("U0001", HttpStatus.NOT_FOUND, "등록된 유저가 아닙니다."), USER_AUTH_TIME_OUT("U0002", HttpStatus.FORBIDDEN, "인증 시간이 만료되었습니다."), USER_AUTH_FAIL("U0003", HttpStatus.FORBIDDEN, "인증에 실패하였습니다."), + USER_ALREADY_EXIST("U0004", HttpStatus.CONFLICT, "이미 등록된 유저입니다."), TOKEN_NOT_VALID("T0001", HttpStatus.NOT_ACCEPTABLE, "해당 토큰은 유효하지 않습니다."), TOKEN_EXPIRATION("T0002", HttpStatus.FORBIDDEN, "토큰이 만료되었습니다."), diff --git a/src/main/java/everymeal/server/user/controller/UserController.java b/src/main/java/everymeal/server/user/controller/UserController.java index 3022080..5af361d 100644 --- a/src/main/java/everymeal/server/user/controller/UserController.java +++ b/src/main/java/everymeal/server/user/controller/UserController.java @@ -6,8 +6,8 @@ import everymeal.server.global.util.authresolver.AuthUser; import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; -import everymeal.server.user.controller.dto.request.UserEmailAuthVerifyReq; -import everymeal.server.user.controller.dto.request.UserSingReq; +import everymeal.server.user.controller.dto.request.UserEmailLoginReq; +import everymeal.server.user.controller.dto.request.UserEmailSingReq; import everymeal.server.user.controller.dto.response.UserEmailAuthRes; import everymeal.server.user.controller.dto.response.UserLoginRes; import everymeal.server.user.service.UserService; @@ -38,7 +38,7 @@ public class UserController { @Operation(summary = "회원가입") @PostMapping - public ApplicationResponse signUp(@RequestBody UserSingReq request) { + public ApplicationResponse signUp(@RequestBody UserEmailSingReq request) { return ApplicationResponse.ok(userService.signUp(request)); } @@ -57,7 +57,7 @@ public ApplicationResponse signUp(@RequestBody UserSingReq request) { }) @PostMapping("/login") public ResponseEntity> login( - @RequestBody UserSingReq request) { + @RequestBody UserEmailLoginReq request) { UserLoginRes response = userService.login(request); ResponseCookie cookie = ResponseCookie.from("refresh-token", response.getRefreshToken()) @@ -114,7 +114,7 @@ public ApplicationResponse emailAuth( summary = "이메일 인증 확인", description = "이메일 인증을 확인합니다.
Request에는 이메일 인증 시 발송된 값이 담겨야 합니다.") public ApplicationResponse verifyEmailAuth( - @RequestBody UserEmailAuthVerifyReq request, + @RequestBody UserEmailLoginReq request, @AuthUser @Parameter(hidden = true) AuthenticatedUser authenticatedUser) { return ApplicationResponse.ok(userService.verifyEmailAuth(request, authenticatedUser)); } diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailAuthVerifyReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java similarity index 62% rename from src/main/java/everymeal/server/user/controller/dto/request/UserEmailAuthVerifyReq.java rename to src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java index eeb3604..f8a8ffa 100644 --- a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailAuthVerifyReq.java +++ b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -13,14 +14,20 @@ @NoArgsConstructor @AllArgsConstructor @Setter -public class UserEmailAuthVerifyReq { +public class UserEmailLoginReq { @Schema( description = "이메일 인증 API에서 반환된 토큰 값", defaultValue = "eyBdvsjfgsdkgb", example = "eyBdvsjfgsdkgb") + @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") private String emailAuthToken; @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") + @NotBlank(message = "인증번호를 입력해주세요.") private String emailAuthValue; + + @Schema(description = "선택 대학교 IDX", example = "1", defaultValue = "1") + @NotBlank(message = "대학교를 선택해주세요.") + private Long universityIdx; } diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java new file mode 100644 index 0000000..15f8589 --- /dev/null +++ b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java @@ -0,0 +1,41 @@ +package everymeal.server.user.controller.dto.request; + + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Builder +public class UserEmailSingReq { + + @Pattern(regexp = "^[^\\\\s]{1,10}$", message = "닉네임은 1~10자리로 입력해주세요.") + @Schema(description = "이메일", example = "test@naver.com") + private String nickname; + + @Schema( + description = "이메일 인증 API에서 반환된 토큰 값", + defaultValue = "eyBdvsjfgsdkgb", + example = "eyBdvsjfgsdkgb") + @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") + private String emailAuthToken; + + @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") + @NotBlank(message = "인증번호를 입력해주세요.") + private String emailAuthValue; + + @Schema(description = "선택 대학교 IDX", example = "1", defaultValue = "1") + @NotBlank(message = "대학교를 선택해주세요.") + private Long universityIdx; + + @Schema(description = "프로필 이미지 URL", example = "https://everymeal.s3.ap-northeast-2.amazonaws.com/1627667445.png") + @NotBlank(message = "프로필 이미지를 선택해주세요.") + private String profileImgKey; + +} diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserSingReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserSingReq.java deleted file mode 100644 index bfd6a11..0000000 --- a/src/main/java/everymeal/server/user/controller/dto/request/UserSingReq.java +++ /dev/null @@ -1,18 +0,0 @@ -package everymeal.server.user.controller.dto.request; - - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Builder -public class UserSingReq { - - @Schema(description = "유저의 기기 고유 번호", defaultValue = "123456789", example = "1234567890") - private String deviceId; -} diff --git a/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java b/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java index 13ff6eb..442621a 100644 --- a/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java +++ b/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java @@ -13,6 +13,7 @@ @Builder public class UserLoginRes { + private String accessToken; @JsonInclude(Include.NON_NULL) diff --git a/src/main/java/everymeal/server/user/entity/User.java b/src/main/java/everymeal/server/user/entity/User.java index 48bf807..c555c5e 100644 --- a/src/main/java/everymeal/server/user/entity/User.java +++ b/src/main/java/everymeal/server/user/entity/User.java @@ -3,6 +3,7 @@ import everymeal.server.global.entity.BaseEntity; import everymeal.server.university.entity.University; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -22,25 +23,28 @@ public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; - - private String deviceId; - private String nickName; - + @Column(unique = true) private String email; - private Boolean isDeleted; + private String profileImgUrl; + private String nickname; @ManyToOne private University university; @Builder - public User(String deviceId, String nickName, String email, University university) { - this.deviceId = deviceId; + public User(String nickName, String email, Boolean isDeleted, String profileImgUrl, + String nickname, + University university) { this.nickName = nickName; this.email = email; + this.isDeleted = isDeleted; + this.profileImgUrl = profileImgUrl; + this.nickname = nickname; this.university = university; } + public void setEmail(String email) { this.email = email; } diff --git a/src/main/java/everymeal/server/user/repository/UserRepository.java b/src/main/java/everymeal/server/user/repository/UserRepository.java index bf8af77..c121866 100644 --- a/src/main/java/everymeal/server/user/repository/UserRepository.java +++ b/src/main/java/everymeal/server/user/repository/UserRepository.java @@ -9,4 +9,5 @@ @Repository public interface UserRepository extends JpaRepository { Optional findByDeviceId(String deviceId); + Optional findByEmail(String email); } diff --git a/src/main/java/everymeal/server/user/service/UserService.java b/src/main/java/everymeal/server/user/service/UserService.java index e34683e..00605be 100644 --- a/src/main/java/everymeal/server/user/service/UserService.java +++ b/src/main/java/everymeal/server/user/service/UserService.java @@ -3,20 +3,20 @@ import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; -import everymeal.server.user.controller.dto.request.UserEmailAuthVerifyReq; -import everymeal.server.user.controller.dto.request.UserSingReq; +import everymeal.server.user.controller.dto.request.UserEmailLoginReq; +import everymeal.server.user.controller.dto.request.UserEmailSingReq; import everymeal.server.user.controller.dto.response.UserEmailAuthRes; import everymeal.server.user.controller.dto.response.UserLoginRes; public interface UserService { - Boolean signUp(UserSingReq userDeviceId); + Boolean signUp(UserEmailSingReq userDeviceId); - UserLoginRes login(UserSingReq request); + UserLoginRes login(UserEmailLoginReq request); Boolean isAuth(AuthenticatedUser authenticatedUser); UserEmailAuthRes emailAuth(UserEmailAuthReq request, AuthenticatedUser authenticatedUser); - Boolean verifyEmailAuth(UserEmailAuthVerifyReq request, AuthenticatedUser authenticatedUser); + Boolean verifyEmailAuth(UserEmailLoginReq request, AuthenticatedUser authenticatedUser); } diff --git a/src/main/java/everymeal/server/user/service/UserServiceImpl.java b/src/main/java/everymeal/server/user/service/UserServiceImpl.java index 7ddad0a..c9e3a2e 100644 --- a/src/main/java/everymeal/server/user/service/UserServiceImpl.java +++ b/src/main/java/everymeal/server/user/service/UserServiceImpl.java @@ -7,8 +7,8 @@ import everymeal.server.global.util.MailUtil; import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; -import everymeal.server.user.controller.dto.request.UserEmailAuthVerifyReq; -import everymeal.server.user.controller.dto.request.UserSingReq; +import everymeal.server.user.controller.dto.request.UserEmailLoginReq; +import everymeal.server.user.controller.dto.request.UserEmailSingReq; import everymeal.server.user.controller.dto.response.UserEmailAuthRes; import everymeal.server.user.controller.dto.response.UserLoginRes; import everymeal.server.user.entity.User; @@ -31,17 +31,28 @@ public class UserServiceImpl implements UserService { @Override @Transactional - public Boolean signUp(UserSingReq request) { - User user = User.builder().deviceId(request.getDeviceId()).build(); + public Boolean signUp(UserEmailSingReq request) { + String email = jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); + if (userRepository.findByEmail(email).isPresent()) { + throw new ApplicationException(ExceptionList.USER_ALREADY_EXIST); + } + + User user = User.builder().email(email).nickName(request.getNickname()).build(); userRepository.save(user); return true; } @Override - public UserLoginRes login(UserSingReq request) { + public UserLoginRes login(UserEmailLoginReq request) { + String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); + if (!request.getEmailAuthValue().equals(emailTokenFromAuthCode)) { + throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); + } + String email = jwtUtil.getEmailTokenFromAuthCode( + request.getEmailAuthToken()); User user = userRepository - .findByDeviceId(request.getDeviceId()) + .findByEmail(email) .orElseThrow(() -> new ApplicationException(ExceptionList.USER_NOT_FOUND)); String accessToken = jwtUtil.generateAccessToken(user.getIdx()); String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); @@ -94,7 +105,7 @@ public UserEmailAuthRes emailAuth( @Override @Transactional public Boolean verifyEmailAuth( - UserEmailAuthVerifyReq request, AuthenticatedUser authenticatedUser) { + UserEmailLoginReq request, AuthenticatedUser authenticatedUser) { String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); if (request.getEmailAuthValue().equals(emailTokenFromAuthCode)) { diff --git a/src/test/java/everymeal/server/user/controller/UserControllerTest.java b/src/test/java/everymeal/server/user/controller/UserControllerTest.java index 8da8ecf..92be0db 100644 --- a/src/test/java/everymeal/server/user/controller/UserControllerTest.java +++ b/src/test/java/everymeal/server/user/controller/UserControllerTest.java @@ -10,8 +10,8 @@ import everymeal.server.global.ControllerTestSupport; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; -import everymeal.server.user.controller.dto.request.UserEmailAuthVerifyReq; -import everymeal.server.user.controller.dto.request.UserSingReq; +import everymeal.server.user.controller.dto.request.UserEmailLoginReq; +import everymeal.server.user.controller.dto.request.UserEmailSingReq; import everymeal.server.user.controller.dto.response.UserLoginRes; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -24,7 +24,7 @@ class UserControllerTest extends ControllerTestSupport { @Test void signUp() throws Exception { // given - UserSingReq request = UserSingReq.builder().deviceId("123456789").build(); + UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); // when then mockMvc.perform( @@ -40,7 +40,7 @@ void signUp() throws Exception { @Test void login() throws Exception { // given - UserSingReq request = UserSingReq.builder().deviceId("123456789").build(); + UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); given(userService.login(any())) .willReturn( @@ -98,8 +98,8 @@ void authUser() throws Exception { @Test void checkEmailAuth() throws Exception { // given - UserEmailAuthVerifyReq request = - UserEmailAuthVerifyReq.builder() + UserEmailLoginReq request = + UserEmailLoginReq.builder() .emailAuthToken("testJwtToken") .emailAuthValue("145734") .build(); diff --git a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java index 7014ab1..f35ac82 100644 --- a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java +++ b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java @@ -10,8 +10,8 @@ import everymeal.server.global.util.MailUtil; import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; -import everymeal.server.user.controller.dto.request.UserEmailAuthVerifyReq; -import everymeal.server.user.controller.dto.request.UserSingReq; +import everymeal.server.user.controller.dto.request.UserEmailLoginReq; +import everymeal.server.user.controller.dto.request.UserEmailSingReq; import everymeal.server.user.controller.dto.response.UserEmailAuthRes; import everymeal.server.user.controller.dto.response.UserLoginRes; import everymeal.server.user.entity.User; @@ -37,7 +37,7 @@ void tearDown() { @Test void singUp() { // given - UserSingReq request = UserSingReq.builder().deviceId("123456789").build(); + UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); // when Boolean response = userService.signUp(request); @@ -53,7 +53,8 @@ void singUp() { @Test void login() { // given - UserSingReq request = UserSingReq.builder().deviceId("123456789").build(); + UserEmailLoginReq request = UserEmailLoginReq.builder().emailAuthValue("ey!gdsjgnsdjkr") + .emailAuthValue("145372").build(); userService.signUp(request); // when @@ -107,8 +108,8 @@ void emailAuthVerify() { userRepository.save(user); String token = jwtUtil.generateEmailToken(user.getIdx(), "test@gmail.com", "123456"); - UserEmailAuthVerifyReq request = - UserEmailAuthVerifyReq.builder() + UserEmailLoginReq request = + UserEmailLoginReq.builder() .emailAuthToken(token) .emailAuthValue("123456") .build(); @@ -135,8 +136,8 @@ void emailAuthVerifyWithNotExistUserIdx() { userRepository.save(user); String token = jwtUtil.generateEmailToken(user.getIdx(), "test@gmail.com", "123456"); - UserEmailAuthVerifyReq request = - UserEmailAuthVerifyReq.builder() + UserEmailLoginReq request = + UserEmailLoginReq.builder() .emailAuthToken(token) .emailAuthValue("123456") .build(); @@ -166,8 +167,8 @@ void emailAuthVerifyWithNotMatchAuthValue() { String token = jwtUtil.generateEmailToken(user.getIdx(), "", "123456"); - UserEmailAuthVerifyReq request = - UserEmailAuthVerifyReq.builder() + UserEmailLoginReq request = + UserEmailLoginReq.builder() .emailAuthToken(token) .emailAuthValue("1234567") .build(); From 85b9a979639ae60651e110a61ee79dc31e72f330 Mon Sep 17 00:00:00 2001 From: kyubeom Date: Sat, 4 Nov 2023 17:14:32 +0900 Subject: [PATCH 2/5] =?UTF-8?q?refactor=20:=20=EC=9C=A0=EC=A0=80=20API=20?= =?UTF-8?q?=EC=9E=AC=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로그인 API - 회원가입 API - 이메일 전송 API - 이메일 인증 확인 API - 이미 가입된 유저인지 확인 API --- .../global/exception/ExceptionList.java | 3 +- .../everymeal/server/global/util/JwtUtil.java | 11 +- .../server/university/entity/University.java | 3 +- .../user/controller/UserController.java | 125 +++++---- .../dto/request/UserEmailLoginReq.java | 27 +- .../dto/request/UserEmailSingReq.java | 56 ++-- .../controller/dto/response/UserLoginRes.java | 22 +- .../everymeal/server/user/entity/User.java | 19 +- .../user/repository/UserRepository.java | 3 +- .../server/user/service/UserService.java | 9 +- .../server/user/service/UserServiceImpl.java | 116 ++++---- src/main/resources/application.yml | 3 +- .../meal/service/MealServiceImplTest.java | 1 - .../service/UniversityServiceImplTest.java | 1 - .../user/controller/UserControllerTest.java | 57 ++-- .../user/service/UserServiceImplTest.java | 253 +++++++++++------- 16 files changed, 393 insertions(+), 316 deletions(-) diff --git a/src/main/java/everymeal/server/global/exception/ExceptionList.java b/src/main/java/everymeal/server/global/exception/ExceptionList.java index 1f0ce5f..2c23dcd 100644 --- a/src/main/java/everymeal/server/global/exception/ExceptionList.java +++ b/src/main/java/everymeal/server/global/exception/ExceptionList.java @@ -18,7 +18,8 @@ public enum ExceptionList { USER_NOT_FOUND("U0001", HttpStatus.NOT_FOUND, "등록된 유저가 아닙니다."), USER_AUTH_TIME_OUT("U0002", HttpStatus.FORBIDDEN, "인증 시간이 만료되었습니다."), USER_AUTH_FAIL("U0003", HttpStatus.FORBIDDEN, "인증에 실패하였습니다."), - USER_ALREADY_EXIST("U0004", HttpStatus.CONFLICT, "이미 등록된 유저입니다."), + USER_ALREADY_EXIST("U0004", HttpStatus.CONFLICT, "이미 등록된 이메일입니다."), + NICKNAME_ALREADY_EXIST("U0005", HttpStatus.CONFLICT, "이미 등록된 닉네임입니다."), TOKEN_NOT_VALID("T0001", HttpStatus.NOT_ACCEPTABLE, "해당 토큰은 유효하지 않습니다."), TOKEN_EXPIRATION("T0002", HttpStatus.FORBIDDEN, "토큰이 만료되었습니다."), diff --git a/src/main/java/everymeal/server/global/util/JwtUtil.java b/src/main/java/everymeal/server/global/util/JwtUtil.java index b4744d9..730d5e2 100644 --- a/src/main/java/everymeal/server/global/util/JwtUtil.java +++ b/src/main/java/everymeal/server/global/util/JwtUtil.java @@ -35,11 +35,10 @@ public class JwtUtil { @Value("${jwt.validity.refresh-seconds}") private Long refreshTokenExpirationMs; - public String generateEmailToken(Long userId, String email, String sendAuthPassword) { + public String generateEmailToken(String email, String sendAuthPassword) { Date now = new Date(); Date expiryDate = new Date(now.getTime() + (accessTokenExpirationMs * 2)); Map claims = new HashMap<>(); - claims.put("CLAIM_KEY_IDX", userId); claims.put("CLAIM_KEY_EMAIL", email); claims.put("CLAIM_KEY_SEND_AUTH_PASSWORD", sendAuthPassword); return Jwts.builder() @@ -95,6 +94,14 @@ public String getEmailTokenFromAuthCode(String token) { return null; } + public String getEmailTokenFromEmail(String token) { + Claims claims = getClaimsFromToken(tokenSubBearer(token), accessSecretKey); + if (claims != null) { + return claims.get("CLAIM_KEY_EMAIL").toString(); + } + return null; + } + private Claims getClaimsFromToken(String token, String secretKey) { try { Key key = Keys.hmacShaKeyFor(secretKey.getBytes()); diff --git a/src/main/java/everymeal/server/university/entity/University.java b/src/main/java/everymeal/server/university/entity/University.java index 094b6e1..0eaea73 100644 --- a/src/main/java/everymeal/server/university/entity/University.java +++ b/src/main/java/everymeal/server/university/entity/University.java @@ -36,8 +36,7 @@ public class University extends BaseEntity { private List stores = new ArrayList<>(); @Builder - public University(Long idx, String name, String campusName, Boolean isDeleted) { - this.idx = idx; + public University(String name, String campusName) { this.name = name; this.campusName = campusName; this.isDeleted = Boolean.FALSE; diff --git a/src/main/java/everymeal/server/user/controller/UserController.java b/src/main/java/everymeal/server/user/controller/UserController.java index 5af361d..2032a4a 100644 --- a/src/main/java/everymeal/server/user/controller/UserController.java +++ b/src/main/java/everymeal/server/user/controller/UserController.java @@ -2,9 +2,6 @@ import everymeal.server.global.dto.response.ApplicationResponse; -import everymeal.server.global.util.authresolver.Auth; -import everymeal.server.global.util.authresolver.AuthUser; -import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; import everymeal.server.user.controller.dto.request.UserEmailLoginReq; import everymeal.server.user.controller.dto.request.UserEmailSingReq; @@ -12,12 +9,10 @@ import everymeal.server.user.controller.dto.response.UserLoginRes; import everymeal.server.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseCookie; @@ -26,6 +21,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/api/v1/users") @@ -36,86 +32,101 @@ public class UserController { private final UserService userService; - @Operation(summary = "회원가입") - @PostMapping - public ApplicationResponse signUp(@RequestBody UserEmailSingReq request) { - return ApplicationResponse.ok(userService.signUp(request)); - } - @Operation( - summary = "로그인", - description = "로그인을 진행합니다.
로그인 성공 시, refresh-token을 쿠키로 반환합니다.") + summary = "회원가입", + description = + """ + 회원가입을 진행합니다.
+ 회원가입 성공 시, refresh-token을 쿠키로 반환합니다. + """) @ApiResponses({ @ApiResponse( responseCode = "200", - description = "로그인 성공", + description = "회원가입 성공", content = @Content(schema = @Schema(implementation = UserLoginRes.class))), @ApiResponse( - responseCode = "404", - description = "(U0001)유저를 찾을 수 없습니다.", - content = @Content(schema = @Schema())) + responseCode = "403", + description = + """ + (U0002)인증 시간이 만료되었습니다.
+ (U0003)인증에 실패하였습니다.
+ """, + content = @Content(schema = @Schema())), + @ApiResponse( + responseCode = "409", + description = + """ + (U0004)이미 가입된 유저입니다.
+ (U0005)이미 등록된 닉네임입니다.
+ """, + content = @Content(schema = @Schema())), }) - @PostMapping("/login") - public ResponseEntity> login( - @RequestBody UserEmailLoginReq request) { - UserLoginRes response = userService.login(request); - ResponseCookie cookie = - ResponseCookie.from("refresh-token", response.getRefreshToken()) - .httpOnly(true) - .sameSite("None") - .path("/") - .maxAge(60 * 60 * 24 * 30L) - .secure(true) - .build(); - response.setRefreshToken(null); - return ResponseEntity.ok() - .header("Set-Cookie", cookie.toString()) - .body(ApplicationResponse.ok(response)); + @PostMapping("/signup") + public ResponseEntity> signUp( + @RequestBody UserEmailSingReq request) { + UserLoginRes response = userService.signUp(request); + return setRefreshToken(response); } - @Auth(require = true) - @GetMapping("/auth") @Operation( - summary = "유저 이메일 인증 여부", - description = "유저가 인증되었는지 여부를 반환합니다.
인증되었다면 true, 아니라면 false를 반환합니다.") + summary = "로그인", + description = "로그인을 진행합니다.
로그인 성공 시, refresh-token을 쿠키로 반환합니다.") @ApiResponses({ @ApiResponse( responseCode = "200", description = "로그인 성공", - content = @Content(schema = @Schema(implementation = Boolean.class))), + content = @Content(schema = @Schema(implementation = UserLoginRes.class))), @ApiResponse( responseCode = "404", description = "(U0001)유저를 찾을 수 없습니다.", content = @Content(schema = @Schema())) }) - @SecurityRequirement(name = "bearerAuth") - public ApplicationResponse isAuth( - @AuthUser @Parameter(hidden = true) AuthenticatedUser authenticatedUser) { - return ApplicationResponse.ok(userService.isAuth(authenticatedUser)); + @PostMapping("/login") + public ResponseEntity> login( + @RequestBody UserEmailLoginReq request) { + UserLoginRes response = userService.login(request); + return setRefreshToken(response); } - @Auth(require = true) - @SecurityRequirement(name = "bearerAuth") - @PostMapping("/email/auth") + @PostMapping("/send/email") @Operation( - summary = "이메일 인증", + summary = "이메일 전송", description = "이메일 인증을 진행합니다.
Response에 5분 동안 유효한 JWT 토큰이 담기는데 해당 토큰에는 발송 값이 들어있습니다.") - public ApplicationResponse emailAuth( - @RequestBody UserEmailAuthReq request, - @AuthUser @Parameter(hidden = true) AuthenticatedUser authenticatedUser) { - return ApplicationResponse.ok(userService.emailAuth(request, authenticatedUser)); + public ApplicationResponse emailAuth(@RequestBody UserEmailAuthReq request) { + return ApplicationResponse.ok(userService.emailAuth(request)); } - @Auth(require = true) - @SecurityRequirement(name = "bearerAuth") - @PostMapping("/email/auth/verify") + @PostMapping("/email/verify") @Operation( summary = "이메일 인증 확인", description = "이메일 인증을 확인합니다.
Request에는 이메일 인증 시 발송된 값이 담겨야 합니다.") - public ApplicationResponse verifyEmailAuth( - @RequestBody UserEmailLoginReq request, - @AuthUser @Parameter(hidden = true) AuthenticatedUser authenticatedUser) { - return ApplicationResponse.ok(userService.verifyEmailAuth(request, authenticatedUser)); + public ApplicationResponse verifyEmailAuth(@RequestBody UserEmailLoginReq request) { + return ApplicationResponse.ok(userService.verifyEmailAuth(request)); + } + + @GetMapping("/email/check") + @Operation( + summary = "이미 가입된 유저인지 확인", + description = "이미 가입된 유저인지 확인합니다.
가입된 유저 true, 가입되지 않은 유저 false") + public ApplicationResponse checkUser( + @Schema(description = "이메일", example = "test@gmail.com") @RequestParam String email) { + return ApplicationResponse.ok(userService.checkUser(email)); + } + + private ResponseEntity> setRefreshToken( + UserLoginRes response) { + ResponseCookie cookie = + ResponseCookie.from("refresh-token", response.refreshToken()) + .httpOnly(true) + .sameSite("None") + .path("/") + .maxAge(60 * 60 * 24 * 30L) + .secure(true) + .build(); + response.withoutRefreshToken(); + return ResponseEntity.ok() + .header("Set-Cookie", cookie.toString()) + .body(ApplicationResponse.ok(response)); } } diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java index f8a8ffa..c7fe5d3 100644 --- a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java +++ b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java @@ -9,25 +9,16 @@ import lombok.NoArgsConstructor; import lombok.Setter; -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Setter -public class UserEmailLoginReq { +public record UserEmailLoginReq( @Schema( + description = "이메일 인증 API에서 반환된 토큰 값", + defaultValue = "eyBdvsjfgsdkgb", + example = "eyBdvsjfgsdkgb") + @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") + String emailAuthToken, - @Schema( - description = "이메일 인증 API에서 반환된 토큰 값", - defaultValue = "eyBdvsjfgsdkgb", - example = "eyBdvsjfgsdkgb") - @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") - private String emailAuthToken; - - @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") + @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") @NotBlank(message = "인증번호를 입력해주세요.") - private String emailAuthValue; + String emailAuthValue) { + - @Schema(description = "선택 대학교 IDX", example = "1", defaultValue = "1") - @NotBlank(message = "대학교를 선택해주세요.") - private Long universityIdx; } diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java index 15f8589..b3ca7ea 100644 --- a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java +++ b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailSingReq.java @@ -4,38 +4,26 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Builder -public class UserEmailSingReq { - - @Pattern(regexp = "^[^\\\\s]{1,10}$", message = "닉네임은 1~10자리로 입력해주세요.") - @Schema(description = "이메일", example = "test@naver.com") - private String nickname; - - @Schema( - description = "이메일 인증 API에서 반환된 토큰 값", - defaultValue = "eyBdvsjfgsdkgb", - example = "eyBdvsjfgsdkgb") - @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") - private String emailAuthToken; - - @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") - @NotBlank(message = "인증번호를 입력해주세요.") - private String emailAuthValue; - - @Schema(description = "선택 대학교 IDX", example = "1", defaultValue = "1") - @NotBlank(message = "대학교를 선택해주세요.") - private Long universityIdx; - - @Schema(description = "프로필 이미지 URL", example = "https://everymeal.s3.ap-northeast-2.amazonaws.com/1627667445.png") - @NotBlank(message = "프로필 이미지를 선택해주세요.") - private String profileImgKey; - -} +public record UserEmailSingReq( + @Pattern(regexp = "^[^\\\\s]{1,10}$", message = "닉네임은 1~10자리로 입력해주세요.") + @Schema(description = "이메일", example = "test@naver.com") + String nickname, + @Schema( + description = "이메일 인증 API에서 반환된 토큰 값", + defaultValue = "eyBdvsjfgsdkgb", + example = "eyBdvsjfgsdkgb") + @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") + String emailAuthToken, + @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") + @NotBlank(message = "인증번호를 입력해주세요.") + String emailAuthValue, + @Schema(description = "선택 대학교 IDX", example = "1", defaultValue = "1") + @NotBlank(message = "대학교를 선택해주세요.") + Long universityIdx, + @Schema( + description = "프로필 이미지 URL", + example = + "https://everymeal.s3.ap-northeast-2.amazonaws.com/1627667445.png") + @NotBlank(message = "프로필 이미지를 선택해주세요.") + String profileImgKey) {} diff --git a/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java b/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java index 442621a..262d7d4 100644 --- a/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java +++ b/src/main/java/everymeal/server/user/controller/dto/response/UserLoginRes.java @@ -4,19 +4,13 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; -@Getter -@Setter -@Builder -public class UserLoginRes { - - - private String accessToken; - - @JsonInclude(Include.NON_NULL) - @Schema(hidden = true) - private String refreshToken; +public record UserLoginRes( + String accessToken, + String nickname, + String profileImg, + @JsonInclude(Include.NON_NULL) @Schema(hidden = true) String refreshToken) { + public UserLoginRes withoutRefreshToken() { + return new UserLoginRes(accessToken, nickname, profileImg, null); + } } diff --git a/src/main/java/everymeal/server/user/entity/User.java b/src/main/java/everymeal/server/user/entity/User.java index c555c5e..24d3794 100644 --- a/src/main/java/everymeal/server/user/entity/User.java +++ b/src/main/java/everymeal/server/user/entity/User.java @@ -23,28 +23,33 @@ public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; + + @Column(unique = true) private String nickName; + @Column(unique = true) private String email; + private Boolean isDeleted; + private String profileImgUrl; - private String nickname; @ManyToOne private University university; @Builder - public User(String nickName, String email, Boolean isDeleted, String profileImgUrl, - String nickname, - University university) { + public User( + String nickName, + String email, + Boolean isDeleted, + String profileImgUrl, + University university) { this.nickName = nickName; this.email = email; - this.isDeleted = isDeleted; + this.isDeleted = Boolean.TRUE; this.profileImgUrl = profileImgUrl; - this.nickname = nickname; this.university = university; } - public void setEmail(String email) { this.email = email; } diff --git a/src/main/java/everymeal/server/user/repository/UserRepository.java b/src/main/java/everymeal/server/user/repository/UserRepository.java index c121866..54fbead 100644 --- a/src/main/java/everymeal/server/user/repository/UserRepository.java +++ b/src/main/java/everymeal/server/user/repository/UserRepository.java @@ -8,6 +8,7 @@ @Repository public interface UserRepository extends JpaRepository { - Optional findByDeviceId(String deviceId); Optional findByEmail(String email); + + Optional findByNickName(String nickname); } diff --git a/src/main/java/everymeal/server/user/service/UserService.java b/src/main/java/everymeal/server/user/service/UserService.java index 00605be..19acfd4 100644 --- a/src/main/java/everymeal/server/user/service/UserService.java +++ b/src/main/java/everymeal/server/user/service/UserService.java @@ -1,7 +1,6 @@ package everymeal.server.user.service; -import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; import everymeal.server.user.controller.dto.request.UserEmailLoginReq; import everymeal.server.user.controller.dto.request.UserEmailSingReq; @@ -10,13 +9,13 @@ public interface UserService { - Boolean signUp(UserEmailSingReq userDeviceId); + UserLoginRes signUp(UserEmailSingReq userDeviceId); UserLoginRes login(UserEmailLoginReq request); - Boolean isAuth(AuthenticatedUser authenticatedUser); + UserEmailAuthRes emailAuth(UserEmailAuthReq request); - UserEmailAuthRes emailAuth(UserEmailAuthReq request, AuthenticatedUser authenticatedUser); + Boolean verifyEmailAuth(UserEmailLoginReq request); - Boolean verifyEmailAuth(UserEmailLoginReq request, AuthenticatedUser authenticatedUser); + Boolean checkUser(String email); } diff --git a/src/main/java/everymeal/server/user/service/UserServiceImpl.java b/src/main/java/everymeal/server/user/service/UserServiceImpl.java index c9e3a2e..6fda714 100644 --- a/src/main/java/everymeal/server/user/service/UserServiceImpl.java +++ b/src/main/java/everymeal/server/user/service/UserServiceImpl.java @@ -5,7 +5,8 @@ import everymeal.server.global.exception.ExceptionList; import everymeal.server.global.util.JwtUtil; import everymeal.server.global.util.MailUtil; -import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; +import everymeal.server.university.entity.University; +import everymeal.server.university.repository.UniversityRepository; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; import everymeal.server.user.controller.dto.request.UserEmailLoginReq; import everymeal.server.user.controller.dto.request.UserEmailSingReq; @@ -25,77 +26,97 @@ @Transactional(readOnly = true) public class UserServiceImpl implements UserService { + private final UniversityRepository universityRepository; private final UserRepository userRepository; private final JwtUtil jwtUtil; private final MailUtil mailUtil; @Override @Transactional - public Boolean signUp(UserEmailSingReq request) { - String email = jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); + public UserLoginRes signUp(UserEmailSingReq request) { + String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); + if (!request.emailAuthValue().equals(emailTokenFromAuthCode)) { + throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); + } + String email = jwtUtil.getEmailTokenFromEmail(request.emailAuthToken()); if (userRepository.findByEmail(email).isPresent()) { throw new ApplicationException(ExceptionList.USER_ALREADY_EXIST); } + if (userRepository.findByNickName(request.nickname()).isPresent()) { + throw new ApplicationException(ExceptionList.NICKNAME_ALREADY_EXIST); + } - User user = User.builder().email(email).nickName(request.getNickname()).build(); + University university = + universityRepository + .findById(request.universityIdx()) + .orElseThrow( + () -> new ApplicationException(ExceptionList.UNIVERSITY_NOT_FOUND)); + User user = + User.builder() + .email(email) + .nickName(request.nickname()) + .profileImgUrl(request.profileImgKey()) + .university(university) + .build(); userRepository.save(user); - return true; + + String accessToken = jwtUtil.generateAccessToken(user.getIdx()); + String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); + return new UserLoginRes( + accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); } @Override public UserLoginRes login(UserEmailLoginReq request) { - String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); - if (!request.getEmailAuthValue().equals(emailTokenFromAuthCode)) { + String emailTokenFromAuthCode = + jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); + if (!request.emailAuthValue().equals(emailTokenFromAuthCode)) { throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); } - String email = jwtUtil.getEmailTokenFromAuthCode( - request.getEmailAuthToken()); + String email = jwtUtil.getEmailTokenFromEmail(request.emailAuthToken()); User user = userRepository .findByEmail(email) .orElseThrow(() -> new ApplicationException(ExceptionList.USER_NOT_FOUND)); String accessToken = jwtUtil.generateAccessToken(user.getIdx()); String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); - return UserLoginRes.builder().accessToken(accessToken).refreshToken(refreshToken).build(); + return new UserLoginRes( + accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); } @Override - public Boolean isAuth(AuthenticatedUser authenticatedUser) { - User user = - userRepository - .findByDeviceId(authenticatedUser.getDeviceId()) - .orElseThrow(() -> new ApplicationException(ExceptionList.USER_NOT_FOUND)); - return user.getEmail() != null; - } - - @Override - public UserEmailAuthRes emailAuth( - UserEmailAuthReq request, AuthenticatedUser authenticatedUser) { + public UserEmailAuthRes emailAuth(UserEmailAuthReq request) { try { Random random = SecureRandom.getInstanceStrong(); int authCode = random.nextInt(900000) + 100000; String htmlText = String.format( - "" - + "" - + "

안녕하세요!

" - + "

에브리밀 서비스에 가입해주셔서 감사합니다. 이메일 인증을 완료하여 식당 및 학식 정보를 더욱 편리하게 이용할 수 있습니다.

" - + "

아래의 인증 코드를 사용하여 이메일 인증을 진행해주세요:

" - + "

인증 코드: %s

" - + "
" - + "

감사합니다.

" - + "
" - + "\"에브리밀" - + "" - + "", + """ + + + 회원가입 인증 이메일 + + +
+

에브리밀 회원가입 인증 이메일

+

안녕하세요,

+

회원가입을 완료하려면 아래의 인증번호를 입력해주세요:

+
+

인증번호: %s

+
+

에브리밀은 이메일 인증을 완료하여 식당 및 학식 정보를 더욱 편리하게 이용할 수 있습니다.

+

에브리밀 서비스에 가입해주셔서 감사합니다.

+

감사합니다.

+ 에브리밀 로고 +
+ + + """, authCode); mailUtil.sendMail(request.getEmail(), "[에브리밀] 대학교 이메일 인증", htmlText); String mailJwt = - jwtUtil.generateEmailToken( - authenticatedUser.getIdx(), - request.getEmail(), - Integer.toString(authCode)); + jwtUtil.generateEmailToken(request.getEmail(), Integer.toString(authCode)); return UserEmailAuthRes.builder().emailAuthToken(mailJwt).build(); } catch (NoSuchAlgorithmException e) { return null; @@ -104,20 +125,17 @@ public UserEmailAuthRes emailAuth( @Override @Transactional - public Boolean verifyEmailAuth( - UserEmailLoginReq request, AuthenticatedUser authenticatedUser) { + public Boolean verifyEmailAuth(UserEmailLoginReq request) { String emailTokenFromAuthCode = - jwtUtil.getEmailTokenFromAuthCode(request.getEmailAuthToken()); - if (request.getEmailAuthValue().equals(emailTokenFromAuthCode)) { - User user = - userRepository - .findById(authenticatedUser.getIdx()) - .orElseThrow( - () -> new ApplicationException(ExceptionList.USER_NOT_FOUND)); - user.setEmail(emailTokenFromAuthCode); - return true; - } else { + jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); + if (!request.emailAuthValue().equals(emailTokenFromAuthCode)) { throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); } + return true; + } + + @Override + public Boolean checkUser(String email) { + return userRepository.findByEmail(email).isPresent(); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6b6f77b..12984b2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -10,7 +10,8 @@ spring: include: secret jpa: hibernate: - ddl-auto: none + ddl-auto: update + properties: hibernate: show_sql: true diff --git a/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java b/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java index 651e262..94221a1 100644 --- a/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java +++ b/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java @@ -341,7 +341,6 @@ private University getUniversity(String universityName, String campusName) { return University.builder() .name(universityName) .campusName(campusName) - .isDeleted(false) .build(); } } diff --git a/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java b/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java index 517326a..5ab8e76 100644 --- a/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java +++ b/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java @@ -61,7 +61,6 @@ private University getUniversity(String universityName, String campusName) { return University.builder() .name(universityName) .campusName(campusName) - .isDeleted(false) .build(); } } diff --git a/src/test/java/everymeal/server/user/controller/UserControllerTest.java b/src/test/java/everymeal/server/user/controller/UserControllerTest.java index 92be0db..2778ea3 100644 --- a/src/test/java/everymeal/server/user/controller/UserControllerTest.java +++ b/src/test/java/everymeal/server/user/controller/UserControllerTest.java @@ -24,30 +24,35 @@ class UserControllerTest extends ControllerTestSupport { @Test void signUp() throws Exception { // given - UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); + UserEmailSingReq request = + new UserEmailSingReq("testNickname", "Token", "sendValue", 1L, "testImageKey"); + + given(userService.signUp(any())) + .willReturn( + new UserLoginRes( + "accessToken", "testNickname", "testImageKey", "refreshToken")); // when then mockMvc.perform( - post("/api/v1/users") + post("/api/v1/users/signup") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isOk()) - .andExpect(jsonPath("$.message").value("OK")); + .andExpect(jsonPath("$.message").value("OK")) + .andExpect(cookie().exists("refresh-token")); } @DisplayName("로그인을 진행한다.") @Test void login() throws Exception { // given - UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); + UserEmailLoginReq request = new UserEmailLoginReq("testJwtToken", "145734"); given(userService.login(any())) .willReturn( - UserLoginRes.builder() - .accessToken("accessToken") - .refreshToken("refreshToken") - .build()); + new UserLoginRes( + "accessToken", "testNickname", "testImageKey", "refreshToken")); // when then mockMvc.perform( @@ -60,33 +65,31 @@ void login() throws Exception { .andExpect(cookie().exists("refresh-token")); } - @DisplayName("유저 인증 여부를 확인한다.") + @DisplayName("이메일 전송합니다.") @Test - void checkUserAuth() throws Exception { + void emailAuth() throws Exception { // given - String accessToken = "eyTestToken1ojkfnsnjie432GFDdss"; - - given(userService.isAuth(any())).willReturn(true); + UserEmailAuthReq request = new UserEmailAuthReq("test@gmail.com"); // when then mockMvc.perform( - get("/api/v1/users/auth") - .content(accessToken) + post("/api/v1/users/send/email") + .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.message").value("OK")); } - @DisplayName("유저 인증을 진행한다.") + @DisplayName("이메일 인증을 진행합니다.") @Test - void authUser() throws Exception { + void verifyEmailAuth() throws Exception { // given - UserEmailAuthReq request = UserEmailAuthReq.builder().email("test@gmail.com").build(); + UserEmailAuthReq request = new UserEmailAuthReq("test@gmail.com"); // when then mockMvc.perform( - post("/api/v1/users/email/auth") + post("/api/v1/users/email/verify") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) @@ -94,20 +97,18 @@ void authUser() throws Exception { .andExpect(jsonPath("$.message").value("OK")); } - @DisplayName("이메일 인증 확인을 진행한다.") + @DisplayName("이미 가입된 유저인지 확인") @Test - void checkEmailAuth() throws Exception { + void checkUser() throws Exception { // given - UserEmailLoginReq request = - UserEmailLoginReq.builder() - .emailAuthToken("testJwtToken") - .emailAuthValue("145734") - .build(); + UserEmailAuthReq request = new UserEmailAuthReq("test@gmail.com"); + + given(userService.checkUser(any())).willReturn(true); // when then mockMvc.perform( - post("/api/v1/users/email/auth/verify") - .content(objectMapper.writeValueAsString(request)) + get("/api/v1/users/email/check") + .queryParam("email", "test@gmail.com") .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) .andExpect(status().isOk()) diff --git a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java index f35ac82..ec347d3 100644 --- a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java +++ b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; import everymeal.server.global.IntegrationTestSupport; import everymeal.server.global.exception.ApplicationException; @@ -9,6 +11,8 @@ import everymeal.server.global.util.JwtUtil; import everymeal.server.global.util.MailUtil; import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; +import everymeal.server.university.entity.University; +import everymeal.server.university.repository.UniversityRepository; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; import everymeal.server.user.controller.dto.request.UserEmailLoginReq; import everymeal.server.user.controller.dto.request.UserEmailSingReq; @@ -20,13 +24,16 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; class UserServiceImplTest extends IntegrationTestSupport { @Autowired private UserService userService; @Autowired private UserRepository userRepository; @Autowired private JwtUtil jwtUtil; - @Autowired private MailUtil mailUtil; + @MockBean private MailUtil mailUtil; + @Autowired private UniversityRepository universityRepository; + @AfterEach void tearDown() { @@ -37,51 +44,144 @@ void tearDown() { @Test void singUp() { // given - UserEmailSingReq request = UserEmailSingReq.builder().deviceId("123456789").build(); + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + + University university = universityRepository.save(University.builder() + .name("명지대학교") + .campusName("인문캠퍼스") + .build()); + UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); // when - Boolean response = userService.signUp(request); + UserLoginRes userLoginRes = userService.signUp(request); // then + assertThat(userLoginRes.nickname()).isEqualTo(request.nickname()); + assertThat(userLoginRes.profileImg()).isEqualTo(request.profileImgKey()); + } + + @DisplayName("회원가입에서 이메일 토큰에서 추출한 값과 요청 값이 다를 경우 에러가 발생한다.") + @Test + void singUpEmailTokenNotMatched() { + // given + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + + University university = universityRepository.save(University.builder() + .name("명지대학교") + .campusName("인문캠퍼스") + .build()); + UserEmailSingReq request = new UserEmailSingReq("nickname", token, "67891", university.getIdx(), "imageKey"); + + // when then + ApplicationException applicationException = + assertThrows( + ApplicationException.class, () -> userService.signUp(request)); + + assertEquals( + applicationException.getErrorCode(), + ExceptionList.USER_AUTH_FAIL.getCODE()); + } + + @DisplayName("회원가입에서 이미 존재한 이메일인 경우 에러가 발생한다. ") + @Test + void singUpEmailNotMatched() { + // given + userRepository.save(createUser("test@gmail.com", "nickname2")); + userRepository.flush(); + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + + University university = universityRepository.save(University.builder() + .name("명지대학교") + .campusName("인문캠퍼스") + .build()); + UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); + + // when then + ApplicationException applicationException = + assertThrows( + ApplicationException.class, () -> userService.signUp(request)); + + assertEquals( + applicationException.getErrorCode(), + ExceptionList.USER_ALREADY_EXIST.getCODE()); + } + + @DisplayName("회원가입에서 이미 존재한 닉네임인 경우 에러가 발생한다. ") + @Test + void singUpAlreadyNickname() { + // given + userRepository.saveAndFlush(createUser("test2@gmail.com", "nickname")); + + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + + University university = universityRepository.save(University.builder() + .name("명지대학교") + .campusName("인문캠퍼스") + .build()); + UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); + + // when then + ApplicationException applicationException = + assertThrows( + ApplicationException.class, () -> userService.signUp(request)); + assertEquals( - userRepository.findByDeviceId(request.getDeviceId()).get().getDeviceId(), - request.getDeviceId()); - assertTrue(response); + applicationException.getErrorCode(), + ExceptionList.NICKNAME_ALREADY_EXIST.getCODE()); } @DisplayName("로그인을 진행한다.") @Test void login() { // given - UserEmailLoginReq request = UserEmailLoginReq.builder().emailAuthValue("ey!gdsjgnsdjkr") - .emailAuthValue("145372").build(); - userService.signUp(request); + userRepository.saveAndFlush(createUser("test@gmail.com", "nickname")); + + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + UserEmailLoginReq request = new UserEmailLoginReq(token, "12345"); // when - UserLoginRes response = userService.login(request); + UserLoginRes userLoginRes = userService.login(request); // then - assertNotNull(response.getRefreshToken()); + assertThat(userLoginRes.nickname()).isEqualTo("nickname"); } - @DisplayName("유저 인증 여부를 반환한다.") + @DisplayName("로그인에서 추출한 토큰이 요청한 토큰과 다를 경우 에러가 발생한다.") @Test - void isUserAuthenticated() { + void loginTokenValueNotMatched() { // given - User user = - userRepository.save( - User.builder() - .deviceId("dsafkml-fgsmkgrlms-421m4f") - .email("test@mju.ac.kr") - .build()); - AuthenticatedUser authenticatedUser = - AuthenticatedUser.builder().deviceId("dsafkml-fgsmkgrlms-421m4f").build(); + userRepository.saveAndFlush(createUser("test@gmail.com", "nickname")); - // when - Boolean response = userService.isAuth(authenticatedUser); + String token = jwtUtil.generateEmailToken("test@gmail.com", "67891"); + UserEmailLoginReq request = new UserEmailLoginReq(token, "12345"); - // then - assertTrue(response); + // when then + ApplicationException applicationException = + assertThrows( + ApplicationException.class, () -> userService.login(request)); + + assertEquals( + applicationException.getErrorCode(), + ExceptionList.USER_AUTH_FAIL.getCODE()); + } + + @DisplayName("로그인에서 이메일이 존재하지 않을 경우 에러가 발생한다.") + @Test + void loginEmailNotMatched() { + // given + userRepository.saveAndFlush(createUser("test@gmail.com", "nickname")); + + String token = jwtUtil.generateEmailToken("test2@gmail.com", "12345"); + UserEmailLoginReq request = new UserEmailLoginReq(token, "12345"); + + // when then + ApplicationException applicationException = + assertThrows( + ApplicationException.class, () -> userService.login(request)); + + assertEquals( + applicationException.getErrorCode(), + ExceptionList.USER_NOT_FOUND.getCODE()); } @DisplayName("이메일 인증을 진행한다.") @@ -90,100 +190,63 @@ void emailAuth() { // given UserEmailAuthReq request = UserEmailAuthReq.builder().email("test@gmail.com").build(); - AuthenticatedUser authenticatedUser = - AuthenticatedUser.builder().deviceId("dsafkml-fgsmkgrlms-421m4f").build(); - // when - UserEmailAuthRes response = userService.emailAuth(request, authenticatedUser); + UserEmailAuthRes response = userService.emailAuth(request); // then assertThat(response).isNotNull(); } - @DisplayName("이메일 인증 확인을 진행한다.") + @DisplayName("이메일로 전송된 인증 값이 토큰의 인증값과 일치한지 확인한다.") @Test - void emailAuthVerify() { + void verifyEmailAuth() { // given - User user = User.builder().deviceId("dsafkml-fgsmkgrlms-421m4f").email(null).build(); - userRepository.save(user); - - String token = jwtUtil.generateEmailToken(user.getIdx(), "test@gmail.com", "123456"); - UserEmailLoginReq request = - UserEmailLoginReq.builder() - .emailAuthToken(token) - .emailAuthValue("123456") - .build(); - - AuthenticatedUser authenticatedUser = - AuthenticatedUser.builder() - .idx(user.getIdx()) - .deviceId("dsafkml-fgsmkgrlms-421m4f") - .build(); + String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); + + UserEmailLoginReq request = new UserEmailLoginReq(token, "12345"); // when - Boolean response = userService.verifyEmailAuth(request, authenticatedUser); + Boolean response = userService.verifyEmailAuth(request); // then - assertTrue(response); + assertThat(response).isTrue(); } - @DisplayName("이메일 인증 과정에서 없는 유저의 인덱스가 들어 있을 경우, 예외가 발생한다.") + + @DisplayName("이메일로 전송된 인증 값이 토큰의 인증값과 일치한지 않다면 에러가 발생한다.") @Test - void emailAuthVerifyWithNotExistUserIdx() { + void verifyEmailAuthNotMatched() { // given + String token = jwtUtil.generateEmailToken("test@gmail.com", "67891"); + UserEmailLoginReq request = new UserEmailLoginReq(token, "12345"); - User user = User.builder().deviceId("dsafkml-fgsmkgrlms-421m4f").email(null).build(); - userRepository.save(user); - - String token = jwtUtil.generateEmailToken(user.getIdx(), "test@gmail.com", "123456"); - UserEmailLoginReq request = - UserEmailLoginReq.builder() - .emailAuthToken(token) - .emailAuthValue("123456") - .build(); - - AuthenticatedUser authenticatedUser = - AuthenticatedUser.builder() - .idx(user.getIdx()) - .deviceId("dsafkml-fgsmkgrlms-421m4f") - .build(); - - userRepository.delete(user); - - // when & then + // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, - () -> userService.verifyEmailAuth(request, authenticatedUser)); - assertEquals(applicationException.getErrorCode(), ExceptionList.USER_NOT_FOUND.getCODE()); + assertThrows( + ApplicationException.class, () -> userService.verifyEmailAuth(request)); + + assertEquals( + applicationException.getErrorCode(), + ExceptionList.USER_AUTH_FAIL.getCODE()); } - @DisplayName("토큰에서 추출한 인증값과 유저가 입력한 인증값이 일치하지 않을 경우, 예외가 발생한다.") + @DisplayName("이미 가입된 유저인지 확인한다") @Test - void emailAuthVerifyWithNotMatchAuthValue() { + void checkUser(){ // given - User user = User.builder().deviceId("dsafkml-fgsmkgrlms-421m4f").email(null).build(); - userRepository.save(user); + userRepository.saveAndFlush(createUser("test@gmail.com","12345")); - String token = jwtUtil.generateEmailToken(user.getIdx(), "", "123456"); - - UserEmailLoginReq request = - UserEmailLoginReq.builder() - .emailAuthToken(token) - .emailAuthValue("1234567") - .build(); + // when + Boolean response = userService.checkUser("test@gmail.com"); - AuthenticatedUser authenticatedUser = - AuthenticatedUser.builder() - .idx(user.getIdx()) - .deviceId("dsafkml-fgsmkgrlms-421m4f") - .build(); + // then + assertThat(response).isTrue(); + } - // when & then - ApplicationException applicationException = - assertThrows( - ApplicationException.class, - () -> userService.verifyEmailAuth(request, authenticatedUser)); - assertEquals(applicationException.getErrorCode(), ExceptionList.USER_AUTH_FAIL.getCODE()); + private User createUser(String email, String nickname){ + return User.builder() + .email(email) + .nickName(nickname) + .build(); } } From 693213beb1fe94b32d4906378dfb1ec936800ee4 Mon Sep 17 00:00:00 2001 From: kyubeom Date: Sat, 4 Nov 2023 17:26:24 +0900 Subject: [PATCH 3/5] =?UTF-8?q?refactor=20:=20Spotless=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/UserEmailLoginReq.java | 28 ++--- .../server/user/service/UserServiceImpl.java | 8 +- .../meal/service/MealServiceImplTest.java | 5 +- .../service/UniversityServiceImplTest.java | 5 +- .../user/service/UserServiceImplTest.java | 100 +++++++----------- 5 files changed, 54 insertions(+), 92 deletions(-) diff --git a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java index c7fe5d3..9aad018 100644 --- a/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java +++ b/src/main/java/everymeal/server/user/controller/dto/request/UserEmailLoginReq.java @@ -3,22 +3,14 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -public record UserEmailLoginReq( @Schema( - description = "이메일 인증 API에서 반환된 토큰 값", - defaultValue = "eyBdvsjfgsdkgb", - example = "eyBdvsjfgsdkgb") - @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") - String emailAuthToken, - - @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") - @NotBlank(message = "인증번호를 입력해주세요.") - String emailAuthValue) { - - -} +public record UserEmailLoginReq( + @Schema( + description = "이메일 인증 API에서 반환된 토큰 값", + defaultValue = "eyBdvsjfgsdkgb", + example = "eyBdvsjfgsdkgb") + @NotBlank(message = "이메일 인증 토큰을 입력해주세요.") + String emailAuthToken, + @Schema(description = "이메일 유저가 입력한 인증 값", defaultValue = "123456", example = "123456") + @NotBlank(message = "인증번호를 입력해주세요.") + String emailAuthValue) {} diff --git a/src/main/java/everymeal/server/user/service/UserServiceImpl.java b/src/main/java/everymeal/server/user/service/UserServiceImpl.java index 6fda714..35e7f4d 100644 --- a/src/main/java/everymeal/server/user/service/UserServiceImpl.java +++ b/src/main/java/everymeal/server/user/service/UserServiceImpl.java @@ -68,8 +68,7 @@ public UserLoginRes signUp(UserEmailSingReq request) { @Override public UserLoginRes login(UserEmailLoginReq request) { - String emailTokenFromAuthCode = - jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); + String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); if (!request.emailAuthValue().equals(emailTokenFromAuthCode)) { throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); } @@ -81,7 +80,7 @@ public UserLoginRes login(UserEmailLoginReq request) { String accessToken = jwtUtil.generateAccessToken(user.getIdx()); String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); return new UserLoginRes( - accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); + accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); } @Override @@ -126,8 +125,7 @@ public UserEmailAuthRes emailAuth(UserEmailAuthReq request) { @Override @Transactional public Boolean verifyEmailAuth(UserEmailLoginReq request) { - String emailTokenFromAuthCode = - jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); + String emailTokenFromAuthCode = jwtUtil.getEmailTokenFromAuthCode(request.emailAuthToken()); if (!request.emailAuthValue().equals(emailTokenFromAuthCode)) { throw new ApplicationException(ExceptionList.USER_AUTH_FAIL); } diff --git a/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java b/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java index 94221a1..5327a1e 100644 --- a/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java +++ b/src/test/java/everymeal/server/meal/service/MealServiceImplTest.java @@ -338,9 +338,6 @@ private RestaurantRegisterReq getRestaurantRegisterReq() { } private University getUniversity(String universityName, String campusName) { - return University.builder() - .name(universityName) - .campusName(campusName) - .build(); + return University.builder().name(universityName).campusName(campusName).build(); } } diff --git a/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java b/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java index 5ab8e76..7a063cf 100644 --- a/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java +++ b/src/test/java/everymeal/server/university/service/UniversityServiceImplTest.java @@ -58,9 +58,6 @@ void getUniversities() { } private University getUniversity(String universityName, String campusName) { - return University.builder() - .name(universityName) - .campusName(campusName) - .build(); + return University.builder().name(universityName).campusName(campusName).build(); } } diff --git a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java index ec347d3..809f3bc 100644 --- a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java +++ b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java @@ -2,15 +2,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; import everymeal.server.global.IntegrationTestSupport; import everymeal.server.global.exception.ApplicationException; import everymeal.server.global.exception.ExceptionList; import everymeal.server.global.util.JwtUtil; import everymeal.server.global.util.MailUtil; -import everymeal.server.global.util.authresolver.entity.AuthenticatedUser; import everymeal.server.university.entity.University; import everymeal.server.university.repository.UniversityRepository; import everymeal.server.user.controller.dto.request.UserEmailAuthReq; @@ -34,7 +31,6 @@ class UserServiceImplTest extends IntegrationTestSupport { @MockBean private MailUtil mailUtil; @Autowired private UniversityRepository universityRepository; - @AfterEach void tearDown() { userRepository.deleteAllInBatch(); @@ -46,11 +42,11 @@ void singUp() { // given String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); - University university = universityRepository.save(University.builder() - .name("명지대학교") - .campusName("인문캠퍼스") - .build()); - UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); + University university = + universityRepository.save( + University.builder().name("명지대학교").campusName("인문캠퍼스").build()); + UserEmailSingReq request = + new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); // when UserLoginRes userLoginRes = userService.signUp(request); @@ -66,20 +62,17 @@ void singUpEmailTokenNotMatched() { // given String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); - University university = universityRepository.save(University.builder() - .name("명지대학교") - .campusName("인문캠퍼스") - .build()); - UserEmailSingReq request = new UserEmailSingReq("nickname", token, "67891", university.getIdx(), "imageKey"); + University university = + universityRepository.save( + University.builder().name("명지대학교").campusName("인문캠퍼스").build()); + UserEmailSingReq request = + new UserEmailSingReq("nickname", token, "67891", university.getIdx(), "imageKey"); // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.signUp(request)); + assertThrows(ApplicationException.class, () -> userService.signUp(request)); - assertEquals( - applicationException.getErrorCode(), - ExceptionList.USER_AUTH_FAIL.getCODE()); + assertEquals(applicationException.getErrorCode(), ExceptionList.USER_AUTH_FAIL.getCODE()); } @DisplayName("회원가입에서 이미 존재한 이메일인 경우 에러가 발생한다. ") @@ -90,20 +83,18 @@ void singUpEmailNotMatched() { userRepository.flush(); String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); - University university = universityRepository.save(University.builder() - .name("명지대학교") - .campusName("인문캠퍼스") - .build()); - UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); + University university = + universityRepository.save( + University.builder().name("명지대학교").campusName("인문캠퍼스").build()); + UserEmailSingReq request = + new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.signUp(request)); + assertThrows(ApplicationException.class, () -> userService.signUp(request)); assertEquals( - applicationException.getErrorCode(), - ExceptionList.USER_ALREADY_EXIST.getCODE()); + applicationException.getErrorCode(), ExceptionList.USER_ALREADY_EXIST.getCODE()); } @DisplayName("회원가입에서 이미 존재한 닉네임인 경우 에러가 발생한다. ") @@ -114,20 +105,19 @@ void singUpAlreadyNickname() { String token = jwtUtil.generateEmailToken("test@gmail.com", "12345"); - University university = universityRepository.save(University.builder() - .name("명지대학교") - .campusName("인문캠퍼스") - .build()); - UserEmailSingReq request = new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); + University university = + universityRepository.save( + University.builder().name("명지대학교").campusName("인문캠퍼스").build()); + UserEmailSingReq request = + new UserEmailSingReq("nickname", token, "12345", university.getIdx(), "imageKey"); // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.signUp(request)); + assertThrows(ApplicationException.class, () -> userService.signUp(request)); assertEquals( - applicationException.getErrorCode(), - ExceptionList.NICKNAME_ALREADY_EXIST.getCODE()); + applicationException.getErrorCode(), + ExceptionList.NICKNAME_ALREADY_EXIST.getCODE()); } @DisplayName("로그인을 진행한다.") @@ -157,13 +147,10 @@ void loginTokenValueNotMatched() { // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.login(request)); + assertThrows(ApplicationException.class, () -> userService.login(request)); - assertEquals( - applicationException.getErrorCode(), - ExceptionList.USER_AUTH_FAIL.getCODE()); - } + assertEquals(applicationException.getErrorCode(), ExceptionList.USER_AUTH_FAIL.getCODE()); + } @DisplayName("로그인에서 이메일이 존재하지 않을 경우 에러가 발생한다.") @Test @@ -176,12 +163,9 @@ void loginEmailNotMatched() { // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.login(request)); + assertThrows(ApplicationException.class, () -> userService.login(request)); - assertEquals( - applicationException.getErrorCode(), - ExceptionList.USER_NOT_FOUND.getCODE()); + assertEquals(applicationException.getErrorCode(), ExceptionList.USER_NOT_FOUND.getCODE()); } @DisplayName("이메일 인증을 진행한다.") @@ -212,7 +196,6 @@ void verifyEmailAuth() { assertThat(response).isTrue(); } - @DisplayName("이메일로 전송된 인증 값이 토큰의 인증값과 일치한지 않다면 에러가 발생한다.") @Test void verifyEmailAuthNotMatched() { @@ -222,19 +205,17 @@ void verifyEmailAuthNotMatched() { // when then ApplicationException applicationException = - assertThrows( - ApplicationException.class, () -> userService.verifyEmailAuth(request)); + assertThrows( + ApplicationException.class, () -> userService.verifyEmailAuth(request)); - assertEquals( - applicationException.getErrorCode(), - ExceptionList.USER_AUTH_FAIL.getCODE()); + assertEquals(applicationException.getErrorCode(), ExceptionList.USER_AUTH_FAIL.getCODE()); } @DisplayName("이미 가입된 유저인지 확인한다") @Test - void checkUser(){ + void checkUser() { // given - userRepository.saveAndFlush(createUser("test@gmail.com","12345")); + userRepository.saveAndFlush(createUser("test@gmail.com", "12345")); // when Boolean response = userService.checkUser("test@gmail.com"); @@ -243,10 +224,7 @@ void checkUser(){ assertThat(response).isTrue(); } - private User createUser(String email, String nickname){ - return User.builder() - .email(email) - .nickName(nickname) - .build(); + private User createUser(String email, String nickname) { + return User.builder().email(email).nickName(nickname).build(); } } From 054e81f8e92983bd8743c6092711c5fe95e591f8 Mon Sep 17 00:00:00 2001 From: kyubeom Date: Sat, 4 Nov 2023 22:20:45 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor=20:=20Index=20=EC=A0=81=EC=9A=A9,?= =?UTF-8?q?=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=9E=AC?= =?UTF-8?q?=EC=84=A4=EC=A0=95,=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - User(email, nickname) 인덱스 적용 - repository Object-> User 오타 수정 - email 관련 엔드포인트 수정 --- .../server/user/controller/UserController.java | 6 +++--- .../everymeal/server/user/entity/User.java | 18 +++++++----------- .../server/user/repository/UserRepository.java | 2 +- .../server/user/service/UserService.java | 2 +- .../server/user/service/UserServiceImpl.java | 8 ++++---- .../user/controller/UserControllerTest.java | 6 +++--- .../user/service/UserServiceImplTest.java | 2 +- 7 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/main/java/everymeal/server/user/controller/UserController.java b/src/main/java/everymeal/server/user/controller/UserController.java index 2032a4a..fe1ccbf 100644 --- a/src/main/java/everymeal/server/user/controller/UserController.java +++ b/src/main/java/everymeal/server/user/controller/UserController.java @@ -88,7 +88,7 @@ public ResponseEntity> login( return setRefreshToken(response); } - @PostMapping("/send/email") + @PostMapping("/email") @Operation( summary = "이메일 전송", description = @@ -97,7 +97,7 @@ public ApplicationResponse emailAuth(@RequestBody UserEmailAut return ApplicationResponse.ok(userService.emailAuth(request)); } - @PostMapping("/email/verify") + @GetMapping("/email/verify") @Operation( summary = "이메일 인증 확인", description = "이메일 인증을 확인합니다.
Request에는 이메일 인증 시 발송된 값이 담겨야 합니다.") @@ -105,7 +105,7 @@ public ApplicationResponse verifyEmailAuth(@RequestBody UserEmailLoginR return ApplicationResponse.ok(userService.verifyEmailAuth(request)); } - @GetMapping("/email/check") + @GetMapping("/email") @Operation( summary = "이미 가입된 유저인지 확인", description = "이미 가입된 유저인지 확인합니다.
가입된 유저 true, 가입되지 않은 유저 false") diff --git a/src/main/java/everymeal/server/user/entity/User.java b/src/main/java/everymeal/server/user/entity/User.java index 24d3794..c3be364 100644 --- a/src/main/java/everymeal/server/user/entity/User.java +++ b/src/main/java/everymeal/server/user/entity/User.java @@ -8,6 +8,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Index; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import lombok.Builder; @@ -15,7 +16,7 @@ import lombok.NoArgsConstructor; @Getter -@Table +@Table(indexes = {@Index(name = "idx__email__nickname", columnList = "email")}) @Entity(name = "users") @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) public class User extends BaseEntity { @@ -24,8 +25,8 @@ public class User extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; - @Column(unique = true) - private String nickName; + @Column(unique = true, length = 50) + private String nickname; @Column(unique = true) private String email; @@ -37,15 +38,10 @@ public class User extends BaseEntity { @ManyToOne private University university; @Builder - public User( - String nickName, - String email, - Boolean isDeleted, - String profileImgUrl, - University university) { - this.nickName = nickName; + public User(String nickname, String email, String profileImgUrl, University university) { + this.nickname = nickname; this.email = email; - this.isDeleted = Boolean.TRUE; + this.isDeleted = Boolean.FALSE; this.profileImgUrl = profileImgUrl; this.university = university; } diff --git a/src/main/java/everymeal/server/user/repository/UserRepository.java b/src/main/java/everymeal/server/user/repository/UserRepository.java index 54fbead..8d60f92 100644 --- a/src/main/java/everymeal/server/user/repository/UserRepository.java +++ b/src/main/java/everymeal/server/user/repository/UserRepository.java @@ -10,5 +10,5 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); - Optional findByNickName(String nickname); + Optional findByNickname(String nickname); } diff --git a/src/main/java/everymeal/server/user/service/UserService.java b/src/main/java/everymeal/server/user/service/UserService.java index 19acfd4..a1d1a41 100644 --- a/src/main/java/everymeal/server/user/service/UserService.java +++ b/src/main/java/everymeal/server/user/service/UserService.java @@ -9,7 +9,7 @@ public interface UserService { - UserLoginRes signUp(UserEmailSingReq userDeviceId); + UserLoginRes signUp(UserEmailSingReq request); UserLoginRes login(UserEmailLoginReq request); diff --git a/src/main/java/everymeal/server/user/service/UserServiceImpl.java b/src/main/java/everymeal/server/user/service/UserServiceImpl.java index 35e7f4d..cac78aa 100644 --- a/src/main/java/everymeal/server/user/service/UserServiceImpl.java +++ b/src/main/java/everymeal/server/user/service/UserServiceImpl.java @@ -42,7 +42,7 @@ public UserLoginRes signUp(UserEmailSingReq request) { if (userRepository.findByEmail(email).isPresent()) { throw new ApplicationException(ExceptionList.USER_ALREADY_EXIST); } - if (userRepository.findByNickName(request.nickname()).isPresent()) { + if (userRepository.findByNickname(request.nickname()).isPresent()) { throw new ApplicationException(ExceptionList.NICKNAME_ALREADY_EXIST); } @@ -54,7 +54,7 @@ public UserLoginRes signUp(UserEmailSingReq request) { User user = User.builder() .email(email) - .nickName(request.nickname()) + .nickname(request.nickname()) .profileImgUrl(request.profileImgKey()) .university(university) .build(); @@ -63,7 +63,7 @@ public UserLoginRes signUp(UserEmailSingReq request) { String accessToken = jwtUtil.generateAccessToken(user.getIdx()); String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); return new UserLoginRes( - accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); + accessToken, user.getNickname(), user.getProfileImgUrl(), refreshToken); } @Override @@ -80,7 +80,7 @@ public UserLoginRes login(UserEmailLoginReq request) { String accessToken = jwtUtil.generateAccessToken(user.getIdx()); String refreshToken = jwtUtil.generateRefreshToken(user.getIdx(), accessToken); return new UserLoginRes( - accessToken, user.getNickName(), user.getProfileImgUrl(), refreshToken); + accessToken, user.getNickname(), user.getProfileImgUrl(), refreshToken); } @Override diff --git a/src/test/java/everymeal/server/user/controller/UserControllerTest.java b/src/test/java/everymeal/server/user/controller/UserControllerTest.java index 2778ea3..482f50a 100644 --- a/src/test/java/everymeal/server/user/controller/UserControllerTest.java +++ b/src/test/java/everymeal/server/user/controller/UserControllerTest.java @@ -73,7 +73,7 @@ void emailAuth() throws Exception { // when then mockMvc.perform( - post("/api/v1/users/send/email") + post("/api/v1/users/email") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) @@ -89,7 +89,7 @@ void verifyEmailAuth() throws Exception { // when then mockMvc.perform( - post("/api/v1/users/email/verify") + get("/api/v1/users/email/verify") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) @@ -107,7 +107,7 @@ void checkUser() throws Exception { // when then mockMvc.perform( - get("/api/v1/users/email/check") + get("/api/v1/users/email") .queryParam("email", "test@gmail.com") .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()) diff --git a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java index 809f3bc..dfb74bf 100644 --- a/src/test/java/everymeal/server/user/service/UserServiceImplTest.java +++ b/src/test/java/everymeal/server/user/service/UserServiceImplTest.java @@ -225,6 +225,6 @@ void checkUser() { } private User createUser(String email, String nickname) { - return User.builder().email(email).nickName(nickname).build(); + return User.builder().email(email).nickname(nickname).build(); } } From 9eefcce71b665fc68a16323755257957fe837890 Mon Sep 17 00:00:00 2001 From: kyubeom Date: Sat, 4 Nov 2023 22:51:46 +0900 Subject: [PATCH 5/5] =?UTF-8?q?refactor=20:=20Index=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 닉네임 추가 --- src/main/java/everymeal/server/user/entity/User.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/everymeal/server/user/entity/User.java b/src/main/java/everymeal/server/user/entity/User.java index c3be364..38bd6db 100644 --- a/src/main/java/everymeal/server/user/entity/User.java +++ b/src/main/java/everymeal/server/user/entity/User.java @@ -16,7 +16,11 @@ import lombok.NoArgsConstructor; @Getter -@Table(indexes = {@Index(name = "idx__email__nickname", columnList = "email")}) +@Table( + indexes = { + @Index(name = "idx__email", columnList = "email"), + @Index(name = "idx__nickname", columnList = "nickname") + }) @Entity(name = "users") @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) public class User extends BaseEntity {