From 37d69b084ffd5be5e9b8649c5e38541b0c7d5328 Mon Sep 17 00:00:00 2001 From: YeongJu Lee <84129098+2zerozu@users.noreply.github.com> Date: Thu, 20 Jul 2023 18:39:43 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20=EB=94=94=EB=8D=B0=EC=9D=B4=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95,?= =?UTF-8?q?=20=EC=9C=A0=EC=A0=80=EC=9D=98=20=EC=86=8C=EC=9B=90=EA=B6=8C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20=EB=B9=88=20=EC=BD=98?= =?UTF-8?q?=ED=85=90=EC=B8=A0=20=EC=A0=9C=EC=99=B8=ED=95=98=EA=B8=B0=20(#1?= =?UTF-8?q?01)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Fix d day calculator * feat: Add user wishcoupon except blank logic --- .../java/com/universe/uni/service/HomeService.java | 11 ++++++----- .../java/com/universe/uni/service/UserService.java | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/universe/uni/service/HomeService.java b/src/main/java/com/universe/uni/service/HomeService.java index 2de0fe6..ccffee2 100644 --- a/src/main/java/com/universe/uni/service/HomeService.java +++ b/src/main/java/com/universe/uni/service/HomeService.java @@ -1,7 +1,8 @@ package com.universe.uni.service; -import java.time.LocalDate; -import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; import org.springframework.stereotype.Service; @@ -73,9 +74,9 @@ private int calculateScore(List gameHistoryList, GameResult res } private int calculateDays(Couple couple) { - LocalDate today = LocalDate.now(); - Period period = Period.between(couple.getStartDate(), today); - return period.getDays() + 1; + ZonedDateTime localTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); + long dDay = ChronoUnit.DAYS.between(couple.getStartDate(), localTime.toLocalDate()); + return (int)dDay + 1; } private CoupleDto fromCoupleToCoupleDtoMapper(Couple couple) { diff --git a/src/main/java/com/universe/uni/service/UserService.java b/src/main/java/com/universe/uni/service/UserService.java index 02ccbb0..929a6ea 100644 --- a/src/main/java/com/universe/uni/service/UserService.java +++ b/src/main/java/com/universe/uni/service/UserService.java @@ -84,6 +84,7 @@ public UserWishCouponResponseDto getUserWishCouponList(Long userId) { .stream() .flatMap(entry -> entry.getValue().stream()) .map(this::fromWishCouponToWishCouponDto) + .filter(wishCouponDto -> !wishCouponDto.content().isBlank()) .collect(Collectors.toList()); return UserWishCouponResponseDto.builder() From 17166d2b55a33f1527dc2732db32fce709d30f54 Mon Sep 17 00:00:00 2001 From: YeongJu Lee <84129098+2zerozu@users.noreply.github.com> Date: Fri, 21 Jul 2023 00:37:21 +0900 Subject: [PATCH 2/4] fix: Fix newWishCoupon logic (#102) --- src/main/java/com/universe/uni/service/UserService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/universe/uni/service/UserService.java b/src/main/java/com/universe/uni/service/UserService.java index 929a6ea..a2261d9 100644 --- a/src/main/java/com/universe/uni/service/UserService.java +++ b/src/main/java/com/universe/uni/service/UserService.java @@ -75,7 +75,7 @@ public UserWishCouponResponseDto getUserWishCouponList(Long userId) { int availableWishCoupon = (int)wishCouponList.stream().filter(wishCoupon -> !wishCoupon.isUsed()).count(); - int newWishCoupon = (int)wishCouponList.stream().filter(WishCoupon::isVisible).count(); + int newWishCoupon = (int)wishCouponList.stream().filter(wishCoupon -> !wishCoupon.isVisible()).count(); List wishCouponDtoList = wishCouponList.stream() .sorted(Comparator.comparing(WishCoupon::getId).reversed()) From fda30d2cbefb7395a547dae0bd6be609a164e4b5 Mon Sep 17 00:00:00 2001 From: YeongJu Lee <84129098+2zerozu@users.noreply.github.com> Date: Fri, 21 Jul 2023 03:07:25 +0900 Subject: [PATCH 3/4] feat: Add nickname in wishcoupon response (#103) --- .../com/universe/uni/dto/response/WishCouponResponseDto.java | 3 ++- src/main/java/com/universe/uni/service/WishCouponService.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java b/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java index 903a64a..9a4da0f 100644 --- a/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java +++ b/src/main/java/com/universe/uni/dto/response/WishCouponResponseDto.java @@ -5,10 +5,11 @@ import lombok.Builder; -@JsonPropertyOrder({"isMine", "wishCoupon"}) +@JsonPropertyOrder({"isMine", "nickname", "wishCoupon"}) @Builder public record WishCouponResponseDto( boolean isMine, + String nickname, WishCouponDto wishCoupon ) { } diff --git a/src/main/java/com/universe/uni/service/WishCouponService.java b/src/main/java/com/universe/uni/service/WishCouponService.java index f6a575a..3520219 100644 --- a/src/main/java/com/universe/uni/service/WishCouponService.java +++ b/src/main/java/com/universe/uni/service/WishCouponService.java @@ -65,6 +65,7 @@ public WishCouponResponseDto getWishCoupon(Long wishCouponId) { return WishCouponResponseDto.builder() .isMine(isMine) + .nickname(user.getNickname()) .wishCoupon(fromWishCouponToWishCouponDto(wishCoupon)) .build(); } From 4c99a08492f36c20f8fb13fd91d1a735e649b32c Mon Sep 17 00:00:00 2001 From: Jinsu Park Date: Fri, 21 Jul 2023 04:48:53 +0900 Subject: [PATCH 4/4] feat: Feature apple login (#104) * feat: Create apple payload information storage record * feat: Create Apple Token Decoder * feat: Add Apple Login --- .../uni/controller/AuthController.java | 13 +++++--- .../com/universe/uni/domain/ApplePayload.java | 29 +++++++++++++++++ .../uni/domain/AppleTokenDecodeManager.java | 31 +++++++++++++++++++ .../uni/domain/AppleTokenManager.java | 8 +++++ .../com/universe/uni/service/AuthService.java | 23 ++++++++++++-- .../uni/service/AuthServiceContract.java | 3 ++ 6 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/universe/uni/domain/ApplePayload.java create mode 100644 src/main/java/com/universe/uni/domain/AppleTokenDecodeManager.java create mode 100644 src/main/java/com/universe/uni/domain/AppleTokenManager.java diff --git a/src/main/java/com/universe/uni/controller/AuthController.java b/src/main/java/com/universe/uni/controller/AuthController.java index 77e3b37..604da5f 100644 --- a/src/main/java/com/universe/uni/controller/AuthController.java +++ b/src/main/java/com/universe/uni/controller/AuthController.java @@ -35,10 +35,15 @@ public AuthTokenDto authByGoogle(@RequestBody AuthRequestDto request) { return authService.authWithGoogle(request.code()); } - @GetMapping("kakao/callback") - public AuthRequestDto redirectKakaoAuth(@RequestParam(name = "code") String authenticationCode) { - return new AuthRequestDto(authenticationCode); - } + @PostMapping("apple") + public AuthTokenDto authByApple(@RequestBody AuthRequestDto request) { + return authService.authWithAppleUser(request.code()); + } + + @GetMapping("kakao/callback") + public AuthRequestDto redirectKakaoAuth(@RequestParam(name = "code") String authenticationCode) { + return new AuthRequestDto(authenticationCode); + } @GetMapping("google/callback") public AuthRequestDto redirectGoogleAuth(@RequestParam(name = "code") String authenticationCode) { diff --git a/src/main/java/com/universe/uni/domain/ApplePayload.java b/src/main/java/com/universe/uni/domain/ApplePayload.java new file mode 100644 index 0000000..a08ccbf --- /dev/null +++ b/src/main/java/com/universe/uni/domain/ApplePayload.java @@ -0,0 +1,29 @@ +package com.universe.uni.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record ApplePayload( + @JsonProperty("aud") + String aud, + @JsonProperty("auth_time") + Long authTime, + @JsonProperty("c_hash") + String cHash, + @JsonProperty("email") + String email, + @JsonProperty("email_verified") + String emailVerified, + @JsonProperty("exp") + Long exp, + @JsonProperty("iat") + Long iat, + @JsonProperty("is_private_email") + String isPrivateEmail, + @JsonProperty("iss") + String iss, + @JsonProperty("nonce_supported") + Boolean nonceSupported, + @JsonProperty("sub") + String sub +) { +} diff --git a/src/main/java/com/universe/uni/domain/AppleTokenDecodeManager.java b/src/main/java/com/universe/uni/domain/AppleTokenDecodeManager.java new file mode 100644 index 0000000..68113a9 --- /dev/null +++ b/src/main/java/com/universe/uni/domain/AppleTokenDecodeManager.java @@ -0,0 +1,31 @@ +package com.universe.uni.domain; + +import java.util.Base64; + +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.universe.uni.exception.UnauthorizedException; +import com.universe.uni.exception.dto.ErrorType; + +@Component +public class AppleTokenDecodeManager implements AppleTokenManager { + + @Override + public String decodeEmail(String token) { + String[] encodedToken = token.split("\\."); + String encodedPayload = encodedToken[1]; + Base64.Decoder decoder = Base64.getDecoder(); + String payLoad = new String(decoder.decode(encodedPayload)); + + ObjectMapper mapper = new ObjectMapper(); + ApplePayload applePayload = null; + try { + applePayload = mapper.readValue(payLoad, ApplePayload.class); + } catch (JsonProcessingException e) { + throw new UnauthorizedException(ErrorType.UNSUPPORTED_TOKEN); + } + return applePayload.email(); + } +} diff --git a/src/main/java/com/universe/uni/domain/AppleTokenManager.java b/src/main/java/com/universe/uni/domain/AppleTokenManager.java new file mode 100644 index 0000000..365c8e1 --- /dev/null +++ b/src/main/java/com/universe/uni/domain/AppleTokenManager.java @@ -0,0 +1,8 @@ +package com.universe.uni.domain; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public interface AppleTokenManager { + + String decodeEmail(String token); +} diff --git a/src/main/java/com/universe/uni/service/AuthService.java b/src/main/java/com/universe/uni/service/AuthService.java index bbd7979..d25a529 100644 --- a/src/main/java/com/universe/uni/service/AuthService.java +++ b/src/main/java/com/universe/uni/service/AuthService.java @@ -4,12 +4,14 @@ import org.springframework.stereotype.Service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.universe.uni.domain.AppleTokenManager; import com.universe.uni.domain.SnsType; import com.universe.uni.domain.entity.User; import com.universe.uni.dto.AuthTokenDto; -import com.universe.uni.external.response.GoogleAccessTokenResponse; +import com.universe.uni.exception.ApiException; +import com.universe.uni.exception.dto.ErrorType; import com.universe.uni.external.response.GoogleUserInfoResponse; -import com.universe.uni.external.response.KakaoAuthResponse; import com.universe.uni.external.response.KakaoUserResponse; import com.universe.uni.repository.GoogleRepository; import com.universe.uni.repository.KakaoRepository; @@ -25,6 +27,7 @@ public class AuthService implements AuthServiceContract { private final KakaoRepository kakaoRepository; private final GoogleRepository googleRepository; private final UserRepository userRepository; + private final AppleTokenManager appleTokenManager; @Override @Transactional @@ -58,6 +61,22 @@ private User registerGoogleUser(GoogleUserInfoResponse googleUser) { .build(); } + @Override + @Transactional + public AuthTokenDto authWithAppleUser(String identityToken) { + final String userEmail = appleTokenManager.decodeEmail(identityToken); + final User user = userRepository.findBySnsAuthCode(userEmail) + .orElseGet(() -> userRepository.save(registerAppleUser(userEmail))); + return beIssuedAuthToken(user.getId()); + } + + private User registerAppleUser(String email) { + return User.builder() + .snsType(SnsType.APPLE) + .snsAuthCode(email) + .build(); + } + private AuthTokenDto beIssuedAuthToken(long userId) { return jwtManager.issueToken(userId); } diff --git a/src/main/java/com/universe/uni/service/AuthServiceContract.java b/src/main/java/com/universe/uni/service/AuthServiceContract.java index 0345002..094ff5c 100644 --- a/src/main/java/com/universe/uni/service/AuthServiceContract.java +++ b/src/main/java/com/universe/uni/service/AuthServiceContract.java @@ -10,4 +10,7 @@ public interface AuthServiceContract { @Transactional AuthTokenDto authWithGoogle(String accessToken); + + @Transactional + AuthTokenDto authWithAppleUser(String identityToken); }