diff --git a/.github/workflows/DOCKER-CD-STAGING.yml b/.github/workflows/DOCKER-CD-STAGING.yml index c6a03907..69ae64ad 100644 --- a/.github/workflows/DOCKER-CD-STAGING.yml +++ b/.github/workflows/DOCKER-CD-STAGING.yml @@ -70,8 +70,8 @@ jobs: - name: docker image 빌드 및 푸시 run: | - docker build -f Dockerfile-staging --platform linux/amd64 -t terningpoint/terning-staging . - docker push terningpoint/terning-staging + docker build -f Dockerfile-staging --platform linux/amd64 -t terningpoint/terning2025-staging . + docker push terningpoint/terning2025-staging working-directory: ${{ env.working-directory }} cd: diff --git a/.github/workflows/DOCKER-CD.yml b/.github/workflows/DOCKER-CD.yml index f9a786ee..a723f92f 100644 --- a/.github/workflows/DOCKER-CD.yml +++ b/.github/workflows/DOCKER-CD.yml @@ -65,8 +65,8 @@ jobs: - name: docker image 빌드 및 푸시 run: | - docker build --platform linux/amd64 -t terningpoint/terning-deploy . - docker push terningpoint/terning-deploy + docker build --platform linux/amd64 -t terningpoint/terning2025 . + docker push terningpoint/terning2025 working-directory: ${{ env.working-directory }} cd: diff --git a/README.md b/README.md index 97acbeaf..7b7cff8e 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,10 @@
+ ## Back-end (Spring 🌱) -| 서버/정정교 | 서버/신정윤 | 서버/권장순 +| 서버/정정교 | 서버/신정윤 | 서버/권장순 | :-----: | :-----: | :-----: | | [정정교/Junggyo1020](https://github.com/junggyo1020) | [신정윤/JungYoonShin](https://github.com/JungYoonShin) | [권장순/jsoonworld](https://github.com/jsoonworld) | diff --git a/src/main/java/org/terning/terningserver/auth/application/signin/AuthSignInServiceImpl.java b/src/main/java/org/terning/terningserver/auth/application/signin/AuthSignInServiceImpl.java index 6e9e56ad..8544ef00 100644 --- a/src/main/java/org/terning/terningserver/auth/application/signin/AuthSignInServiceImpl.java +++ b/src/main/java/org/terning/terningserver/auth/application/signin/AuthSignInServiceImpl.java @@ -5,7 +5,7 @@ import org.springframework.transaction.annotation.Transactional; import org.terning.terningserver.auth.application.social.SocialAuthProvider; import org.terning.terningserver.auth.application.social.SocialAuthServiceManager; -import org.terning.terningserver.external.notification.FcmTokenValidationClient; +import org.terning.terningserver.external.notification.NotificationUserClient; import org.terning.terningserver.jwt.application.JwtTokenManager; import org.terning.terningserver.domain.Token; import org.terning.terningserver.domain.User; @@ -21,7 +21,8 @@ public class AuthSignInServiceImpl implements AuthSignInService { private final SocialAuthServiceManager socialAuthServiceManager; private final JwtTokenManager jwtTokenManager; private final UserRepository userRepository; - private final FcmTokenValidationClient fcmTokenValidationClient; + private final NotificationUserClient notificationUserClient; +// private final FcmTokenValidationClient fcmTokenValidationClient; @Transactional @Override @@ -30,15 +31,21 @@ public SignInResponse signIn(String authAccessToken, SignInRequest request) { User user = findUserByAuthIdAndType(authId, request.authType()); if (user == null) { - return SignInResponse.of(null, authId, request.authType(), null, false); +// return SignInResponse.of(null, authId, request.authType(), null, false); + return SignInResponse.of(null, authId, request.authType(), null); } Token token = jwtTokenManager.generateToken(user); user.updateRefreshToken(token.getRefreshToken()); - boolean fcmReissueRequired = fcmTokenValidationClient.requestFcmTokenValidation(user.getId()); +// boolean fcmReissueRequired = fcmTokenValidationClient.requestFcmTokenValidation(user.getId()); - return SignInResponse.of(token, authId, request.authType(), user.getId(), fcmReissueRequired); + if (request.fcmToken() != null && !request.fcmToken().trim().isEmpty()) { + notificationUserClient.updateFcmToken(user.getId(), request.fcmToken()); + } + +// return SignInResponse.of(token, authId, request.authType(), user.getId(), fcmReissueRequired); + return SignInResponse.of(token, authId, request.authType(), user.getId()); } diff --git a/src/main/java/org/terning/terningserver/auth/application/social/apple/AppleAuthTokenValidator.java b/src/main/java/org/terning/terningserver/auth/application/social/apple/AppleAuthTokenValidator.java index 8cdab80c..ffae0342 100644 --- a/src/main/java/org/terning/terningserver/auth/application/social/apple/AppleAuthTokenValidator.java +++ b/src/main/java/org/terning/terningserver/auth/application/social/apple/AppleAuthTokenValidator.java @@ -133,8 +133,10 @@ private PublicKey getPublicKey(JsonObject object) { String modulus = object.get(MODULUS).getAsString(); String exponent = object.get(EXPONENT).getAsString(); - byte[] modulusBytes = Base64.getUrlDecoder().decode(modulus.substring(QUOTES, modulus.length() - QUOTES)); - byte[] exponentBytes = Base64.getUrlDecoder().decode(exponent.substring(QUOTES, exponent.length() - QUOTES)); +// byte[] modulusBytes = Base64.getUrlDecoder().decode(modulus.substring(QUOTES, modulus.length() - QUOTES)); + byte[] modulusBytes = Base64.getUrlDecoder().decode(modulus); +// byte[] exponentBytes = Base64.getUrlDecoder().decode(exponent.substring(QUOTES, exponent.length() - QUOTES)); + byte[] exponentBytes = Base64.getUrlDecoder().decode(exponent); BigInteger modulusValue = new BigInteger(POSITIVE_NUMBER, modulusBytes); BigInteger exponentValue = new BigInteger(POSITIVE_NUMBER, exponentBytes); diff --git a/src/main/java/org/terning/terningserver/auth/dto/request/SignInRequest.java b/src/main/java/org/terning/terningserver/auth/dto/request/SignInRequest.java index 1c2dce56..6e13dc54 100644 --- a/src/main/java/org/terning/terningserver/auth/dto/request/SignInRequest.java +++ b/src/main/java/org/terning/terningserver/auth/dto/request/SignInRequest.java @@ -3,8 +3,8 @@ import lombok.NonNull; import org.terning.terningserver.domain.enums.AuthType; -public record SignInRequest(@NonNull AuthType authType) { - public static SignInRequest of(AuthType authType){ - return new SignInRequest(authType); +public record SignInRequest(@NonNull AuthType authType, String fcmToken) { + public static SignInRequest of(AuthType authType, String fcmToken){ + return new SignInRequest(authType, fcmToken); } } diff --git a/src/main/java/org/terning/terningserver/auth/dto/response/SignInResponse.java b/src/main/java/org/terning/terningserver/auth/dto/response/SignInResponse.java index bd3e645d..a07756e7 100644 --- a/src/main/java/org/terning/terningserver/auth/dto/response/SignInResponse.java +++ b/src/main/java/org/terning/terningserver/auth/dto/response/SignInResponse.java @@ -10,17 +10,17 @@ public record SignInResponse( String refreshToken, Long userId, String authId, - AuthType authType, - boolean fcmTokenReissueRequired + AuthType authType +// boolean fcmTokenReissueRequired ) { - public static SignInResponse of(Token token, String authId, AuthType authType, Long userId, boolean fcmTokenReissueRequired) { + public static SignInResponse of(Token token, String authId, AuthType authType, Long userId) { return new SignInResponse( Optional.ofNullable(token).map(Token::getAccessToken).orElse(null), Optional.ofNullable(token).map(Token::getRefreshToken).orElse(null), userId, authId, - authType, - fcmTokenReissueRequired + authType +// fcmTokenReissueRequired ); } } diff --git a/src/main/java/org/terning/terningserver/config/SwaggerConfig.java b/src/main/java/org/terning/terningserver/config/SwaggerConfig.java index cc796a41..534c49da 100644 --- a/src/main/java/org/terning/terningserver/config/SwaggerConfig.java +++ b/src/main/java/org/terning/terningserver/config/SwaggerConfig.java @@ -14,7 +14,9 @@ @OpenAPIDefinition( servers = { @Server(url = "https://www.terning-official.p-e.kr", description = "Default Server url"), + @Server(url = "https://www.terning-official.n-e.kr", description = "Default Server url (2025 ver.)"), @Server(url = "http://15.165.242.132", description = "Staging Server URL"), + @Server(url = "http://54.180.215.35", description = "Staging Server URL (2025 ver.)"), @Server(url = "http://localhost:8080", description = "Local Development Server URL") } ) diff --git a/src/main/java/org/terning/terningserver/config/WebMvcConfig.java b/src/main/java/org/terning/terningserver/config/WebMvcConfig.java index 68e9fff2..1edd2142 100644 --- a/src/main/java/org/terning/terningserver/config/WebMvcConfig.java +++ b/src/main/java/org/terning/terningserver/config/WebMvcConfig.java @@ -15,7 +15,9 @@ public void addCorsMappings(CorsRegistry registry) { "http://localhost:8080", "http://localhost:3000", "https://www.terning-official.p-e.kr/", - "http://15.165.242.132") // 허용할 출처 : 특정 도메인만 받을 수 있음 + "https://www.terning-official.n-e.kr/", + "http://15.165.242.132", + "http://54.180.215.35") // 허용할 출처 : 특정 도메인만 받을 수 있음 .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH") // 허용할 HTTP method .allowCredentials(true); // 쿠키 인증 요청 허용 } diff --git a/src/main/java/org/terning/terningserver/domain/Scrap.java b/src/main/java/org/terning/terningserver/domain/Scrap.java index ee11ec14..9e281d58 100644 --- a/src/main/java/org/terning/terningserver/domain/Scrap.java +++ b/src/main/java/org/terning/terningserver/domain/Scrap.java @@ -34,7 +34,7 @@ public class Scrap extends BaseTimeEntity { private Color color; @Embedded - @AttributeOverride(name = "value", column = @Column(name = "synced", nullable = false)) + @AttributeOverride(name = "value", column = @Column(name = "synced")) private SyncStatus syncStatus; private Scrap(User user, InternshipAnnouncement internshipAnnouncement, Color color) { diff --git a/src/main/java/org/terning/terningserver/external/config/WebClientConfig.java b/src/main/java/org/terning/terningserver/external/config/WebClientConfig.java index 48fad821..b938c9fc 100644 --- a/src/main/java/org/terning/terningserver/external/config/WebClientConfig.java +++ b/src/main/java/org/terning/terningserver/external/config/WebClientConfig.java @@ -18,7 +18,7 @@ @Configuration public class WebClientConfig { - private static final int CONNECT_TIMEOUT_MILLIS = 2000; + private static final int CONNECT_TIMEOUT_MILLIS = 5000; private static final int READ_TIMEOUT_SECONDS = 2; private static final int WRITE_TIMEOUT_SECONDS = 2; diff --git a/src/main/java/org/terning/terningserver/external/notification/NotificationUserClient.java b/src/main/java/org/terning/terningserver/external/notification/NotificationUserClient.java index c4600f60..cbc1ee8e 100644 --- a/src/main/java/org/terning/terningserver/external/notification/NotificationUserClient.java +++ b/src/main/java/org/terning/terningserver/external/notification/NotificationUserClient.java @@ -50,6 +50,23 @@ public void createUserOnNotificationServer( log.info("User (id={}) created on notification server : ", userId); } + /** + * 알림서버에 새로운 fcm 토큰을 전달합니다. + * + * @param userId 사용자 ID + * @param newToken 새로운 fcm 토큰 + */ + public void updateFcmToken(Long userId, String newToken) { + notificationWebClient.put() + .uri("/api/v1/users/{userId}/fcm-tokens", userId) + .body(Mono.just(newToken), String.class) + .retrieve() + .bodyToMono(Void.class) + .block(); + + log.info("FCM tokens updated for user (id={}): {}", userId, newToken); + } + /** * 알림서버에 신규 사용자 정보를 전달하여 사용자 레코드를 생성합니다. * 운영서버에서는 pushStatus 값을 DB에 저장하지 않고, diff --git a/src/main/java/org/terning/terningserver/jwt/provider/JwtKeyProvider.java b/src/main/java/org/terning/terningserver/jwt/provider/JwtKeyProvider.java index 0603daaf..53ede881 100644 --- a/src/main/java/org/terning/terningserver/jwt/provider/JwtKeyProvider.java +++ b/src/main/java/org/terning/terningserver/jwt/provider/JwtKeyProvider.java @@ -1,6 +1,10 @@ package org.terning.terningserver.jwt.provider; +import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; import org.springframework.stereotype.Component; import org.terning.terningserver.config.ValueConfig; @@ -8,6 +12,7 @@ @Component public class JwtKeyProvider { + public static SecretKey getSigningKey(ValueConfig valueConfig) { return Keys.hmacShaKeyFor(valueConfig.getSecretKey().getBytes()); } diff --git a/src/main/java/org/terning/terningserver/service/UserServiceImpl.java b/src/main/java/org/terning/terningserver/service/UserServiceImpl.java index 431f7184..8d54666c 100644 --- a/src/main/java/org/terning/terningserver/service/UserServiceImpl.java +++ b/src/main/java/org/terning/terningserver/service/UserServiceImpl.java @@ -9,6 +9,7 @@ import org.terning.terningserver.dto.user.request.ProfileUpdateRequestDto; import org.terning.terningserver.exception.CustomException; import org.terning.terningserver.exception.enums.ErrorMessage; +import org.terning.terningserver.external.notification.NotificationUserClient; import org.terning.terningserver.external.user.application.UserSyncEventService; import org.terning.terningserver.repository.user.UserRepository; import org.terning.terningserver.dto.user.response.ProfileResponseDto; @@ -22,13 +23,15 @@ public class UserServiceImpl implements UserService { private final UserRepository userRepository; private final UserSyncEventService userSyncEventService; + private final NotificationUserClient notificationUserClient; @Override @Transactional public void deleteUser(User user) { try { userRepository.delete(user); - userSyncEventService.recordWithdraw(user.getId()); +// userSyncEventService.recordWithdraw(user.getId()); + notificationUserClient.deleteUser(user.getId()); } catch (Exception e) { throw new CustomException(FAILED_WITHDRAW); } @@ -54,7 +57,8 @@ public void updateProfile(Long userId, ProfileUpdateRequestDto request){ ProfileImage profileImage = ProfileImage.fromValue(request.profileImage()); if (!user.getName().equals(request.name())) { - userSyncEventService.recordNameChange(userId, request.name()); +// userSyncEventService.recordNameChange(userId, request.name()); + notificationUserClient.updateUserName(userId, request.name()); } //프로필 업데이트