From cc36441317a30799baacafa62040d9cedfb43e98 Mon Sep 17 00:00:00 2001
From: JIMIN KIM <102471138+jimin-fundamental@users.noreply.github.com>
Date: Thu, 6 Feb 2025 23:19:37 +0900
Subject: [PATCH 01/24] =?UTF-8?q?Revert=20"[hotfix]=20driver:docker=20?=
=?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80=ED=95=B4=EC=84=9C=20mob?=
=?UTF-8?q?y/buildkit=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=A7=89?=
=?UTF-8?q?=EC=9D=8C"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/main.yml | 3 ---
.../java/learningFlow/learningFlow_BE/config/WebConfig.java | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 88dcfc35..3653a42a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -24,9 +24,6 @@ jobs:
# Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- with:
- install: true
- driver: docker
# Build and push Docker image
- name: Build and push
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
index d94dacbe..75a42b1d 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
@@ -10,7 +10,7 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
- .allowedOrigins("http://localhost:3000", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")
+ .allowedOrigins("http://localhost:3000", "http://localhost:8080", "http://onboarding.p-e.kr:8080")
// .allowedOrigins("http://localhost:3000") // 프론트엔드 주소
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
.allowedHeaders("*")
From ca6f0425b4863ecc1da09965a55ec61a053beea4 Mon Sep 17 00:00:00 2001
From: JungJaehoon0430 <80247965+JungJaehoon0430@users.noreply.github.com>
Date: Fri, 7 Feb 2025 01:31:15 +0900
Subject: [PATCH 02/24] =?UTF-8?q?CorsConfig,=20SecurityConfig=20=EB=A7=81?=
=?UTF-8?q?=ED=81=AC=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/learningFlow/learningFlow_BE/config/CorsConfig.java | 2 +-
.../learningFlow_BE/config/security/SecurityConfig.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
index 8f1b0568..b509d149 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
@@ -17,7 +17,7 @@ public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
- config.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8081")); // ✅ Swagger 포함
+ config.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8081", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")); // ✅ Swagger 포함
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
config.setAllowedHeaders(List.of("*"));
config.setMaxAge(3600L);
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index daff5cd2..810b7ecd 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -89,7 +89,7 @@ public PasswordEncoder passwordEncoder() {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
- configuration.setAllowedOrigins(List.of("http://localhost:3000")); // 프론트엔드 주소
+ configuration.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")); // 프론트엔드 주소
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
From 8191b0c5daadc21e0a44089564617e1b852f7a0b Mon Sep 17 00:00:00 2001
From: JungJaehoon0430 <80247965+JungJaehoon0430@users.noreply.github.com>
Date: Fri, 7 Feb 2025 12:10:11 +0900
Subject: [PATCH 03/24] =?UTF-8?q?Config=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. application.yml 에 코드 추가
2. SecurityConfig의 corsConfigurationSource메소드 수정
3. WebConfig 수정
4. CorsConfig 수정
---
.../learningFlow_BE/domain/uuid/QUuid.java | 47 +++++++++++++++++++
.../learningFlow_BE/config/CorsConfig.java | 24 ++++++++--
.../learningFlow_BE/config/WebConfig.java | 11 ++++-
.../config/security/SecurityConfig.java | 18 ++++++-
src/main/resources/application.yml | 1 +
5 files changed, 93 insertions(+), 8 deletions(-)
create mode 100644 src/main/generated/learningFlow/learningFlow_BE/domain/uuid/QUuid.java
diff --git a/src/main/generated/learningFlow/learningFlow_BE/domain/uuid/QUuid.java b/src/main/generated/learningFlow/learningFlow_BE/domain/uuid/QUuid.java
new file mode 100644
index 00000000..a5c6a6dc
--- /dev/null
+++ b/src/main/generated/learningFlow/learningFlow_BE/domain/uuid/QUuid.java
@@ -0,0 +1,47 @@
+package learningFlow.learningFlow_BE.domain.uuid;
+
+import static com.querydsl.core.types.PathMetadataFactory.*;
+
+import com.querydsl.core.types.dsl.*;
+
+import com.querydsl.core.types.PathMetadata;
+import javax.annotation.processing.Generated;
+import com.querydsl.core.types.Path;
+
+
+/**
+ * QUuid is a Querydsl query type for Uuid
+ */
+@Generated("com.querydsl.codegen.DefaultEntitySerializer")
+public class QUuid extends EntityPathBase {
+
+ private static final long serialVersionUID = 1905925310L;
+
+ public static final QUuid uuid1 = new QUuid("uuid1");
+
+ public final learningFlow.learningFlow_BE.domain.QBaseEntity _super = new learningFlow.learningFlow_BE.domain.QBaseEntity(this);
+
+ //inherited
+ public final DateTimePath createdAt = _super.createdAt;
+
+ public final NumberPath id = createNumber("id", Long.class);
+
+ //inherited
+ public final DateTimePath updatedAt = _super.updatedAt;
+
+ public final StringPath uuid = createString("uuid");
+
+ public QUuid(String variable) {
+ super(Uuid.class, forVariable(variable));
+ }
+
+ public QUuid(Path extends Uuid> path) {
+ super(path.getType(), path.getMetadata());
+ }
+
+ public QUuid(PathMetadata metadata) {
+ super(Uuid.class, metadata);
+ }
+
+}
+
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
index b509d149..9383e4cd 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
@@ -7,6 +7,7 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
+import java.util.Arrays;
import java.util.List;
@Configuration
@@ -16,11 +17,26 @@ public class CorsConfig {
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
+
+ config.setAllowedOrigins(Arrays.asList(
+ "http://localhost:3000",
+ "http://localhost:8081",
+ "http://onboarding.p-e.kr:8080",
+ "http://54.180.118.227",
+ "https://accounts.google.com"
+ ));
+
+ config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
+ config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowCredentials(true);
- config.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8081", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")); // ✅ Swagger 포함
- config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
- config.setAllowedHeaders(List.of("*"));
- config.setMaxAge(3600L);
+ config.setExposedHeaders(Arrays.asList(
+ "Authorization",
+ "Refresh-Token",
+ "Access-Control-Allow-Origin",
+ "Access-Control-Allow-Credentials"
+ ));
+ config.setMaxAge(86400L);
+
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
index d94dacbe..e8c22c70 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
@@ -10,8 +10,15 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
- .allowedOrigins("http://localhost:3000", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")
-// .allowedOrigins("http://localhost:3000") // 프론트엔드 주소
+ .allowedOriginPatterns("*") // 개발 중일 때만 사용
+ // 또는 특정 출처만 허용
+ .allowedOrigins(
+ "http://localhost:3000",
+ "http://localhost:8081",
+ "http://onboarding.p-e.kr:8080",
+ "http://54.180.118.227",
+ "https://accounts.google.com"
+ )
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index 810b7ecd..8af83159 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -89,10 +89,24 @@ public PasswordEncoder passwordEncoder() {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
- configuration.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8080", "http://onboarding.p-e.kr:8080", "http://54.180.118.227")); // 프론트엔드 주소
+
+ configuration.setAllowedOrigins(Arrays.asList(
+ "http://localhost:3000",
+ "http://localhost:8081",
+ "http://onboarding.p-e.kr:8080",
+ "http://54.180.118.227",
+ "https://accounts.google.com"
+ ));
+
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
- configuration.setAllowedHeaders(List.of("*"));
+ configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
+ configuration.setExposedHeaders(Arrays.asList(
+ "Authorization",
+ "Refresh-Token",
+ "Access-Control-Allow-Origin",
+ "Access-Control-Allow-Credentials"
+ ));
configuration.setMaxAge(86400L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index f74a6ea7..b5d5af40 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -24,6 +24,7 @@ spring:
client:
registration:
google:
+ redirect-uri: "http://onboarding.p-e.kr:8080/login/oauth2/code/google"
client-id: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_ID}
client-secret: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_SECRET}
scope:
From 2000e2d05aacea6dff75f2869408ebf321d2c362 Mon Sep 17 00:00:00 2001
From: LJYeon12
Date: Sat, 8 Feb 2025 00:31:29 +0900
Subject: [PATCH 04/24] =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../security/handler/OAuth2LoginSuccessHandler.java | 5 ++++-
src/main/resources/application.yml | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index dc3c8ff6..45d6c58e 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -10,6 +10,7 @@
import learningFlow.learningFlow_BE.web.dto.user.UserResponseDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@@ -26,6 +27,8 @@ public class OAuth2LoginSuccessHandler implements AuthenticationSuccessHandler {
private final JwtTokenProvider jwtTokenProvider;
+ @Value("${app.frontend-url}") // added
+ private String frontendUrl; // added
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
@@ -34,7 +37,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
// Principal 타입 확인, 첫 로그인인 경우 회원가입으로 이동
if (authentication.getPrincipal() instanceof OAuth2UserTemp oAuth2UserTemp) {
String temporaryToken = jwtTokenProvider.createTemporaryToken(oAuth2UserTemp);
- String redirectUrl = "/oauth2/additional-info?token=" + temporaryToken;
+ String redirectUrl = frontendUrl + "/oauth2/additional-info?token=" + temporaryToken;
response.sendRedirect(redirectUrl);
return;
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index b5d5af40..754e8491 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -57,7 +57,7 @@ custom:
refresh-token-validity-in-seconds: 604800 # Refresh Token 1주일
app:
- url: http://localhost:3000 #http://54.180.118.227:8080
+ frontend-url: http://localhost:3000 #http://54.180.118.227:8080
server:
From a99c315d8f76ad3bbd7d7c3d9fae4c1a439c0f25 Mon Sep 17 00:00:00 2001
From: Karen
Date: Sat, 8 Feb 2025 12:51:18 +0900
Subject: [PATCH 05/24] =?UTF-8?q?[hotfix]=20application.yml=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95=EC=97=90=20=EB=94=B0=EB=A5=B8=20app.url=20=EC=95=88?=
=?UTF-8?q?=EB=B0=94=EB=80=90=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/auth/common/UserVerificationEmailService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java b/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
index 05c4a4e2..793e0ef6 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
@@ -16,7 +16,7 @@ public class UserVerificationEmailService {
private final JavaMailSender emailSender;
- @Value("${app.url}")
+ @Value("${app.frontend-url}")
private String baseUrl;
public void sendVerificationEmail(String email, String token) {
From de8ba2a11b49b93ecc451b6ec3250b3d17899007 Mon Sep 17 00:00:00 2001
From: LJYeon12
Date: Sat, 8 Feb 2025 20:33:55 +0900
Subject: [PATCH 06/24] =?UTF-8?q?=EC=88=98=EA=B0=95=20=EC=83=81=ED=83=9C?=
=?UTF-8?q?=20=EC=A0=80=EC=9E=A5=20=EC=99=84=EB=A3=8C,=20home=20localdate?=
=?UTF-8?q?=20=EC=A7=81=EB=A0=AC=ED=99=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../domain/QUserEpisodeProgress.java | 2 +
.../converter/ResourceConverter.java | 26 +++++--
.../domain/UserCollection.java | 2 +-
.../domain/UserEpisodeProgress.java | 9 ++-
.../service/resource/ResourceService.java | 39 +++++++----
.../controller/ResourceRestController.java | 69 +++++++++++--------
.../dto/collection/CollectionResponseDTO.java | 6 ++
.../web/dto/resource/ResourceRequestDTO.java | 1 +
.../web/dto/resource/ResourceResponseDTO.java | 9 +++
9 files changed, 111 insertions(+), 52 deletions(-)
diff --git a/src/main/generated/learningFlow/learningFlow_BE/domain/QUserEpisodeProgress.java b/src/main/generated/learningFlow/learningFlow_BE/domain/QUserEpisodeProgress.java
index 6b9e370c..e7aba947 100644
--- a/src/main/generated/learningFlow/learningFlow_BE/domain/QUserEpisodeProgress.java
+++ b/src/main/generated/learningFlow/learningFlow_BE/domain/QUserEpisodeProgress.java
@@ -31,6 +31,8 @@ public class QUserEpisodeProgress extends EntityPathBase {
public final NumberPath episodeNumber = createNumber("episodeNumber", Integer.class);
+ public final BooleanPath isComplete = createBoolean("isComplete");
+
public final EnumPath resourceType = createEnum("resourceType", learningFlow.learningFlow_BE.domain.enums.ResourceType.class);
public final NumberPath totalProgress = createNumber("totalProgress", Integer.class);
diff --git a/src/main/java/learningFlow/learningFlow_BE/converter/ResourceConverter.java b/src/main/java/learningFlow/learningFlow_BE/converter/ResourceConverter.java
index d57c8197..49a0d5a3 100644
--- a/src/main/java/learningFlow/learningFlow_BE/converter/ResourceConverter.java
+++ b/src/main/java/learningFlow/learningFlow_BE/converter/ResourceConverter.java
@@ -2,12 +2,10 @@
import learningFlow.learningFlow_BE.domain.*;
import learningFlow.learningFlow_BE.domain.Collection;
-import learningFlow.learningFlow_BE.web.dto.collection.CollectionResponseDTO;
import learningFlow.learningFlow_BE.web.dto.resource.ResourceRequestDTO;
import learningFlow.learningFlow_BE.web.dto.resource.ResourceResponseDTO;
import learningFlow.learningFlow_BE.domain.CollectionEpisode;
import learningFlow.learningFlow_BE.domain.UserCollection;
-import learningFlow.learningFlow_BE.web.dto.home.HomeResponseDTO;
import java.util.*;
public class ResourceConverter {
@@ -23,10 +21,15 @@ public static ResourceResponseDTO.ResourceUrlDTO watchEpisode(Collection collect
.urlTitle(resource.getTitle())
.progress(userProgress.getCurrentProgress())
.memoContents(memoContents)
- .episodeInformationList(episodeInformationList(collection))
+ .episodeInformationList(episodeInformationList(collection,userProgress))
.build();
}
- public static ResourceResponseDTO.ResourceBlogUrlDTO watchBlogEpisode(Collection collection, UserEpisodeProgress userProgress, String pageResource, String resourceTitle, Optional memo){
+ public static ResourceResponseDTO.ResourceBlogUrlDTO watchBlogEpisode(
+ Collection collection,
+ UserEpisodeProgress userProgress,
+ String pageResource,
+ String resourceTitle,
+ Optional memo){
String memoContents = "작성하신 글의 첫 줄은 노트의 제목이 됩니다, 최대 2,000자까지 입력하실 수 있어요";
if (memo.isPresent())
memoContents = memo.get().getContents();
@@ -38,17 +41,20 @@ public static ResourceResponseDTO.ResourceBlogUrlDTO watchBlogEpisode(Collection
.urlTitle(resourceTitle)
.progress(userProgress.getCurrentProgress())
.memoContents(memoContents)
- .episodeInformationList(episodeInformationList(collection))
+ .episodeInformationList(episodeInformationList(collection, userProgress))
.build();
}
- public static List episodeInformationList(Collection collection) {
+ public static List episodeInformationList(
+ Collection collection, UserEpisodeProgress userEpisodeProgress
+ ) {
List episodeInformationList = new ArrayList<>();
for (CollectionEpisode episode : collection.getEpisodes()) {
episodeInformationList.add(new ResourceResponseDTO.episodeInformation(
episode.getEpisodeNumber(),
- episode.getResource().getTitle()
+ episode.getResource().getTitle(),
+ userEpisodeProgress.getIsComplete()
));
}
episodeInformationList.sort(Comparator.comparingInt(ResourceResponseDTO.episodeInformation::getEpisodeNumber));
@@ -62,6 +68,12 @@ public static ResourceResponseDTO.ProgressResponseDTO toSaveProgressResponse(Res
.build();
}
+ public static ResourceResponseDTO.changeEpisodeIsCompleteDTO toChangeEpisodeIsCompleteDTO(Boolean isComplete){
+ return ResourceResponseDTO.changeEpisodeIsCompleteDTO.builder()
+ .isComplete(isComplete)
+ .build();
+ }
+
public static ResourceResponseDTO.SearchResultResourceDTO convertToResourceDTO(CollectionEpisode episode) {
return ResourceResponseDTO.SearchResultResourceDTO.builder()
.resourceId(episode.getId())
diff --git a/src/main/java/learningFlow/learningFlow_BE/domain/UserCollection.java b/src/main/java/learningFlow/learningFlow_BE/domain/UserCollection.java
index d3208ce5..8fef140a 100644
--- a/src/main/java/learningFlow/learningFlow_BE/domain/UserCollection.java
+++ b/src/main/java/learningFlow/learningFlow_BE/domain/UserCollection.java
@@ -31,7 +31,7 @@ public class UserCollection extends BaseEntity{
private User user;
@Column(name = "user_collection_status", nullable = false)
- private Integer userCollectionStatus;
+ private Integer userCollectionStatus; // 가장 최신에 수강한 강의 저장
@Column(name = "completed_time", nullable = false)
private LocalDate completedTime;
diff --git a/src/main/java/learningFlow/learningFlow_BE/domain/UserEpisodeProgress.java b/src/main/java/learningFlow/learningFlow_BE/domain/UserEpisodeProgress.java
index 9e33dbd6..0767b2be 100644
--- a/src/main/java/learningFlow/learningFlow_BE/domain/UserEpisodeProgress.java
+++ b/src/main/java/learningFlow/learningFlow_BE/domain/UserEpisodeProgress.java
@@ -24,9 +24,16 @@ public class UserEpisodeProgress extends BaseEntity {
@Setter
private Integer currentProgress;
- @Column(nullable = false)
private Integer totalProgress;
+ @Column(nullable = false)
+ private Boolean isComplete = false;
+
@Column(nullable = false)
private ResourceType resourceType;
+
+ public Boolean setIsComplete(Boolean isComplete){
+ this.isComplete = isComplete;
+ return this.isComplete;
+ }
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/resource/ResourceService.java b/src/main/java/learningFlow/learningFlow_BE/service/resource/ResourceService.java
index 3934479c..5d6c0ceb 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/resource/ResourceService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/resource/ResourceService.java
@@ -3,7 +3,6 @@
import learningFlow.learningFlow_BE.apiPayload.code.status.ErrorStatus;
import learningFlow.learningFlow_BE.apiPayload.exception.handler.ResourceHandler;
import learningFlow.learningFlow_BE.domain.*;
-import learningFlow.learningFlow_BE.domain.enums.ResourceType;
import learningFlow.learningFlow_BE.repository.*;
import learningFlow.learningFlow_BE.web.dto.resource.ResourceRequestDTO;
import lombok.RequiredArgsConstructor;
@@ -38,7 +37,14 @@ public UserEpisodeProgress getUserEpisodeProgress(Long episodeId, String loginId
Integer resourceQuantity = episode.getResource().getResourceQuantity();
if (resourceQuantity == null) throw new ResourceHandler(ErrorStatus.QUANTITY_IS_NULL);
- UserEpisodeProgress userEpisodeProgress = new UserEpisodeProgress(userEpisodeProgressId, episode.getEpisodeNumber(), 0, episode.getResource().getResourceQuantity(), episode.getResource().getType());
+ UserEpisodeProgress userEpisodeProgress = new UserEpisodeProgress(
+ userEpisodeProgressId,
+ episode.getEpisodeNumber(),
+ 0,
+ episode.getResource().getResourceQuantity(),
+ false,
+ episode.getResource().getType()
+ );
log.info("resourceType", episode.getResource().getType());
@@ -86,22 +92,27 @@ public void updateUserCollection(CollectionEpisode episode, String loginId) {
userCollection = new UserCollection();
userCollection.setUserCollection(user, collection, episodeNumber);
}
- // 저장
- userCollectionRepository.save(userCollection);
}
@Transactional
public void saveProgress(ResourceRequestDTO.ProgressRequestDTO request, String userId, Long episodeId) {
- UserEpisodeProgressId progressId = new UserEpisodeProgressId(episodeId, userId);
- UserEpisodeProgress progress = userEpisodeProgressRepository.findById(progressId)
+ UserEpisodeProgressId userEpisodeId = new UserEpisodeProgressId(episodeId, userId);
+ UserEpisodeProgress userEpisode = userEpisodeProgressRepository.findById(userEpisodeId)
.orElseThrow(() -> new ResourceHandler(ErrorStatus.USER_PROGRESS_NOT_FOUND));
+ // 만약 진도가 80이상인 경우 완료로 저장
+ Integer requestProgress = request.getProgress();
+ if (requestProgress >= 80) userEpisode.setIsComplete(true);
+ userEpisode.setCurrentProgress(requestProgress);
+ }
- if (request.getResourceType() == ResourceType.VIDEO && request.getProgress() != null) {
- progress.setCurrentProgress(request.getProgress());
- } else if (request.getResourceType() == ResourceType.TEXT && request.getProgress() != null) {
- progress.setCurrentProgress(request.getProgress());
- } else {
- throw new ResourceHandler(ErrorStatus._BAD_REQUEST);
- }
- userEpisodeProgressRepository.save(progress);
+ @Transactional
+ public Boolean changeEpisodeComplete(Long episodeId, String loginId){
+ UserEpisodeProgressId userEpisodeId = new UserEpisodeProgressId(episodeId, loginId);
+ UserEpisodeProgress userEpisodeProgress = userEpisodeProgressRepository.findById(userEpisodeId)
+ .orElseThrow(() -> new ResourceHandler(ErrorStatus.USER_PROGRESS_NOT_FOUND));
+ Boolean isComplete = userEpisodeProgress.getIsComplete();
+ if (isComplete.equals(true)) isComplete = userEpisodeProgress.setIsComplete(false);
+ else isComplete = userEpisodeProgress.setIsComplete(true);
+ userEpisodeProgress.setCurrentProgress(0);
+ return isComplete;
}
}
\ No newline at end of file
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/ResourceRestController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/ResourceRestController.java
index 16b02cb6..85bdfcb0 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/ResourceRestController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/ResourceRestController.java
@@ -35,7 +35,7 @@
@RestController
@RequiredArgsConstructor
@Validated
-@RequestMapping("/resources")
+@RequestMapping("/resources/{episodeId}")
@Slf4j
@Tag(name = "Resource", description = "Collection 내에 특정 resource 관련해서 기능하는 API")
public class ResourceRestController {
@@ -45,7 +45,7 @@ public class ResourceRestController {
private final YoutubeUrlEmbedService youtubeUrlEmbedService;
private final LambdaService lambdaService;
- @GetMapping("/{episodeId}/youtube")
+ @GetMapping("/youtube")
@Operation(summary = "강의 시청, 강좌로 이동 API", description = """
영상 리소스 조회 및 시청 처리 API입니다.
@@ -76,11 +76,12 @@ public ApiResponse watchEpisode(
Collection collection = resourceService.getCollection(episodeId);
Optional memo = resourceService.getMemoContents(episodeId);
Resource resource = youtubeUrlEmbedService.getResource(episodeId);
-
- return ApiResponse.onSuccess(ResourceConverter.watchEpisode(collection, userEpisodeProgress, resource, memo));
+ ResourceResponseDTO.ResourceUrlDTO response =
+ ResourceConverter.watchEpisode(collection, userEpisodeProgress, resource, memo);
+ return ApiResponse.onSuccess(response);
}
- @GetMapping("/{episodeId}/blog")
+ @GetMapping("/blog")
@Operation(summary = "블로그 글 조회 API", description = """
텍스트(블로그) 리소스 조회 API입니다.
@@ -115,11 +116,11 @@ public ApiResponse watchBlogEpisode(
Optional memo = resourceService.getMemoContents(episodeId);
String resourceTitle = resourceService.getResource(episodeId).getTitle();
String blogSourceUrl = "/resources/" + episodeId + "/blog/content";
- return ApiResponse.onSuccess(ResourceConverter.watchBlogEpisode(collection, userEpisodeProgress, blogSourceUrl, resourceTitle, memo));
+ ResourceResponseDTO.ResourceBlogUrlDTO response = ResourceConverter.watchBlogEpisode(collection, userEpisodeProgress, blogSourceUrl, resourceTitle, memo);
+ return ApiResponse.onSuccess(response);
}
- // Gzip으로 HTML을 반환하는 API
- @GetMapping("{episodeId}/blog/content")
+ @GetMapping("/blog/content")
@Operation(summary = "blog HTML 반환 API", description = """
블로그 글의 HTML 컨텐츠를 반환하는 API입니다.
/resources/{episodeId}/blog 호출 이후 사용됩니다.
@@ -129,7 +130,7 @@ public ApiResponse watchBlogEpisode(
- HTML 컨텐츠 가공 및 반환
[응답 형식]
- - Gzip 압축된 HTML 문자열
+ - S3 객체 URL 반환
[파라미터]
- width: 컨텐츠 영역 너비 (기본값: 982)
@@ -139,20 +140,6 @@ public ApiResponse getBlogEpisodeContent(
@PathVariable("episodeId") Long episodeId,
@RequestParam(defaultValue = "982") int width,
@RequestParam(defaultValue = "552") int height) {
- /* CompletableFuture blogSource = blogEmbedService.getBlogSource(episodeId);
-
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 바이너리 파일 반환
- headers.add(HttpHeaders.CONTENT_ENCODING, "gzip"); // 올바르게 설정
-
- try {
- byte[] blogContent = blogSource.get(); // 예외 처리 추가
- headers.setContentLength(blogContent.length);
- return new ResponseEntity<>(blogContent, headers, HttpStatus.OK);
- } catch (InterruptedException | ExecutionException e) {
- log.error("블로그 데이터를 가져오는 중 오류 발생: {}", e.getMessage(), e);
- return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new byte[0]); // 빈 응답 반환
- }*/
Resource resource = resourceService.getResource(episodeId);
if (resource.getClientUrl() != null) {
return ApiResponse.onSuccess(resource.getClientUrl());
@@ -160,13 +147,13 @@ public ApiResponse getBlogEpisodeContent(
return ApiResponse.onSuccess(lambdaService.invokeLambda(resource.getUrl(), width, height, resource));
}
- @PostMapping("/{episodeId}/save-progress")
+ @PostMapping("/save-progress")
@Operation(summary = "강의 진도 저장 API", description = """
리소스 학습 진도를 저장하는 API입니다.
[입력 정보]
- resourceType: 리소스 유형 (VIDEO/TEXT)
- - progress:
+ - progress:
* VIDEO: 재생 시간(초)
* TEXT: 스크롤 위치(px)
@@ -185,11 +172,34 @@ public ApiResponse saveProgress(
@Valid @RequestBody ResourceRequestDTO.ProgressRequestDTO request) {
String loginId = principalDetails.getUser().getLoginId();
resourceService.saveProgress(request, loginId, episodeId);
-
- return ApiResponse.onSuccess(ResourceConverter.toSaveProgressResponse(request));
+ ResourceResponseDTO.ProgressResponseDTO response = ResourceConverter.toSaveProgressResponse(request);
+ return ApiResponse.onSuccess(response);
+ }
+ @PostMapping("/update-complete")
+ @Operation(summary = "에피소드 수강 상태 변환", description = """
+ episode 수강 완료일 경우 수강 초기화, 수강 완료 상태가 아닐 경우 수강 완료로 표기하는 API 입니다.
+
+ [처리 내용]
+ - 에피소드 수강 상태 확인 후 변경
+
+ [응답 정보]
+ - 바뀐 수강 상태
+ """)
+ @ApiResponses({
+ @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "COMMON200", description = "OK, 성공"),
+ @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "RESOURCE4001", description = "강의 에피소드를 찾을 수 없습니다."),
+ })
+ public ApiResponse updateEpisodeStatus(
+ @AuthenticationPrincipal PrincipalDetails principalDetails,
+ @Valid @PathVariable("episodeId") Long episodeId){
+ String loginId = principalDetails.getUser().getLoginId();
+ log.info("로그인 상태 확인 {}", loginId);
+ Boolean isComplete = resourceService.changeEpisodeComplete(episodeId, loginId);
+ ResourceResponseDTO.changeEpisodeIsCompleteDTO response = ResourceConverter.toChangeEpisodeIsCompleteDTO(isComplete);
+ return ApiResponse.onSuccess(response);
}
- @PostMapping("/{episodeId}/memo")
+ @PostMapping("/memo")
@Operation(summary = "강의 메모 생성 API", description = """
리소스에 대한 메모를 작성하는 API입니다.
@@ -211,6 +221,7 @@ public ApiResponse createMemo(
String loginId = principalDetails.getUser().getLoginId();
log.info("로그인 상태 확인 {}", loginId);
memoCommandService.saveMemo(loginId, episodeId, request);
- return ApiResponse.onSuccess(MemoConverter.createMemo(request)); // 성공 시 200 OK 반환
+ MemoResponseDTO.MemoInfoDTO response = MemoConverter.createMemo(request);
+ return ApiResponse.onSuccess(response); // 성공 시 200 OK 반환
}
}
\ No newline at end of file
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
index af0a7342..f77b9738 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
@@ -1,5 +1,8 @@
package learningFlow.learningFlow_BE.web.dto.collection;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import learningFlow.learningFlow_BE.domain.enums.InterestField;
import learningFlow.learningFlow_BE.web.dto.resource.ResourceResponseDTO;
import lombok.AllArgsConstructor;
@@ -45,7 +48,10 @@ public static class CollectionPreviewDTO {
Integer progressRatePercentage;
String progressRatio;
String learningStatus;
+
+ @JsonSerialize(using = LocalDateSerializer.class)
LocalDate startDate;
+ @JsonSerialize(using = LocalDateSerializer.class)
LocalDate completedDate;
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceRequestDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceRequestDTO.java
index f3ceb781..aeacf3ff 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceRequestDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceRequestDTO.java
@@ -10,6 +10,7 @@ public class ResourceRequestDTO {
public static class ProgressRequestDTO {
@NotNull
private ResourceType resourceType; // 강의 타입 (VIDEO or TEXT)
+ @NotNull
private Integer progress; // 유튜브 강의 && 블로그 픽셀
}
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceResponseDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceResponseDTO.java
index 59d34d3f..ca5824ea 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceResponseDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/resource/ResourceResponseDTO.java
@@ -51,6 +51,7 @@ public static class ResourceBlogUrlDTO {
public static class episodeInformation {
Integer episodeNumber;
String urlTitle;
+ Boolean isCompleted;
}
@Getter
@@ -89,4 +90,12 @@ public static class RecentlyWatchedEpisodeDTO {
Integer currentProgress;
Integer totalProgress;
}
+
+ @Getter
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class changeEpisodeIsCompleteDTO {
+ Boolean isComplete;
+ }
}
From 80154cfa3d7e7322d83b133325afb3d99a6fd7a1 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Mon, 10 Feb 2025 00:32:20 +0900
Subject: [PATCH 07/24] =?UTF-8?q?feat=20:=20=EC=98=A4=EB=A5=98=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=ED=95=84=EC=9A=94=EC=97=86=EB=8A=94=20?=
=?UTF-8?q?import?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../learningFlow_BE/LearningFlowBeApplication.java | 1 -
.../repository/collection/CollectionRepositoryImpl.java | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/LearningFlowBeApplication.java b/src/main/java/learningFlow/learningFlow_BE/LearningFlowBeApplication.java
index 3d9123a8..0bd7a76b 100644
--- a/src/main/java/learningFlow/learningFlow_BE/LearningFlowBeApplication.java
+++ b/src/main/java/learningFlow/learningFlow_BE/LearningFlowBeApplication.java
@@ -2,7 +2,6 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;
diff --git a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
index fc9ab29a..2a0f42eb 100644
--- a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
+++ b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
@@ -1,8 +1,8 @@
package learningFlow.learningFlow_BE.repository.collection;
-import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
+import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import learningFlow.learningFlow_BE.apiPayload.code.status.ErrorStatus;
import learningFlow.learningFlow_BE.apiPayload.exception.handler.CollectionHandler;
@@ -66,7 +66,7 @@ private OrderSpecifier>[] createOrderSpecifier(Integer sortType) { // 반환
}
private BooleanExpression createSearchConditions(SearchRequestDTO.SearchConditionDTO condition) {
- return (BooleanExpression) ExpressionUtils.allOf(
+ return Expressions.allOf(
createDynamicKeyword(condition.getKeyword()),
createDynamicInterestFields(condition.getInterestFields()),
createDynamicPreferMediaType(condition.getPreferMediaType()),
From e8c5eddbfd72c009057c800d1890c9dbe75e9679 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Mon, 10 Feb 2025 00:55:29 +0900
Subject: [PATCH 08/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=ED=95=A0=20=EB=95=8C=20=EC=9D=B4=EB=A6=84?=
=?UTF-8?q?=EC=9D=80=20=EB=94=B0=EB=A1=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90?=
=?UTF-8?q?=EC=97=90=EA=B2=8C=20=EC=B6=94=EA=B0=80=20=EC=9E=85=EB=A0=A5=20?=
=?UTF-8?q?=EB=B0=9B=EA=B2=8C=EB=81=94=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../security/handler/OAuth2LoginSuccessHandler.java | 5 +++--
.../auth/oauth/OAuth2UserRegistrationService.java | 5 ++---
.../learningFlow_BE/web/controller/LoginController.java | 9 +++++----
.../learningFlow_BE/web/dto/user/UserRequestDTO.java | 4 ++++
src/main/resources/application.yml | 2 --
5 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 45d6c58e..a5cd5cf4 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -27,8 +27,9 @@ public class OAuth2LoginSuccessHandler implements AuthenticationSuccessHandler {
private final JwtTokenProvider jwtTokenProvider;
- @Value("${app.frontend-url}") // added
- private String frontendUrl; // added
+ @Value("${app.frontend-url}")
+ private String frontendUrl;
+
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/auth/oauth/OAuth2UserRegistrationService.java b/src/main/java/learningFlow/learningFlow_BE/service/auth/oauth/OAuth2UserRegistrationService.java
index 6fb9a5b0..eadf7e2c 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/auth/oauth/OAuth2UserRegistrationService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/auth/oauth/OAuth2UserRegistrationService.java
@@ -44,7 +44,7 @@ public Map getAdditionalInfoRequirements() {
Map response = new HashMap<>();
response.put("message", "추가 정보 입력이 필요합니다");
response.put("requiredFields", Arrays.asList(
- "job", "interestFields", "gender", "preferType"
+ "name", "job", "interestFields", "preferType"
));
return response;
@@ -64,7 +64,6 @@ public UserResponseDTO.UserLoginResponseDTO updateAdditionalInfo(
Claims claims = jwtTokenProvider.getClaims(temporaryToken);
String email = claims.getSubject();
- String name = claims.get("name", String.class);
String providerId = claims.get("providerId", String.class);
SocialType socialType = SocialType.valueOf(claims.get("socialType", String.class));
@@ -72,7 +71,7 @@ public UserResponseDTO.UserLoginResponseDTO updateAdditionalInfo(
User newUser = User.builder()
.loginId(socialType.name() + "_" + providerId)
.email(email)
- .name(name)
+ .name(additionalInfo.getName())
.providerId(providerId)
.pw("OAUTH2_USER")
.socialType(socialType)
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
index 4452531a..ade22156 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
@@ -150,15 +150,16 @@ public ApiResponse> getAdditionalInfoPage() {
OAuth2 회원가입의 추가 정보를 입력받습니다.
[필수 입력]
- - 직업
- - 관심분야 (다중선택)
- - 선호 미디어 타입
+ - 이름: 실명 또는 닉네임
+ - 직업: STUDENT, ADULT, EMPLOYEE, JOB_SEEKER, OTHER
+ - 관심분야: 다중선택 (APP_DEVELOPMENT, WEB_DEVELOPMENT, PROGRAMMING_LANGUAGE, DEEP_LEARNING, STATISTICS, DATA_ANALYSIS, UI_UX, PLANNING, BUSINESS_PRODUCTIVITY, FOREIGN_LANGUAGE, CAREER)
+ - 선호 미디어: VIDEO, TEXT
[선택 입력]
- 프로필 이미지 URL
[주의사항]
- - 이메일/이름은 구글 계정 정보 사용
+ - 이메일은 구글 계정 정보 사용
- 이미지 미입력시 기본 이미지 사용
""")
public ApiResponse updateAdditionalInfo(
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/user/UserRequestDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/user/UserRequestDTO.java
index 8586980b..0cb3d5ef 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/user/UserRequestDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/user/UserRequestDTO.java
@@ -59,6 +59,10 @@ public static class UserLoginDTO {
@Getter
public static class AdditionalInfoDTO {
+
+ @NotBlank(message = "이름은 필수 입력값입니다")
+ String name;
+
@NotNull(message = "직업은 필수 선택값입니다")
Job job;
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 754e8491..39cf2cd8 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -24,7 +24,6 @@ spring:
client:
registration:
google:
- redirect-uri: "http://onboarding.p-e.kr:8080/login/oauth2/code/google"
client-id: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_ID}
client-secret: ${SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_GOOGLE_CLIENT_SECRET}
scope:
@@ -59,7 +58,6 @@ custom:
app:
frontend-url: http://localhost:3000 #http://54.180.118.227:8080
-
server:
port: 8080
compression:
From baeeedadaac04465e600a2cd3573f2cdcfc9dd87 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Mon, 10 Feb 2025 12:03:46 +0900
Subject: [PATCH 09/24] =?UTF-8?q?feat=20:=20=EC=BB=A4=EC=84=9C=20=EA=B8=B0?=
=?UTF-8?q?=EB=B0=98=20=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=82=AC=EC=9A=A9=20?=
=?UTF-8?q?=EC=8B=9C,=20=EB=8B=A4=EC=9D=8C=20=ED=8E=98=EC=9D=B4=EC=A7=80?=
=?UTF-8?q?=EB=A1=9C=20=EB=84=98=EC=96=B4=EA=B0=80=EA=B8=B0=20=EC=9C=84?=
=?UTF-8?q?=ED=95=B4=EC=84=9C=20lastId=EA=B0=80=20=EC=95=84=EB=8B=8C=20pag?=
=?UTF-8?q?e=EB=A5=BC=20=EC=9D=B8=EC=9E=90=EB=A1=9C=20=EC=A0=84=EB=8B=AC?=
=?UTF-8?q?=EB=B0=9B=EA=B2=8C=EB=81=94=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../converter/CollectionConverter.java | 6 +-
.../CollectionRepositoryCustom.java | 3 +-
.../collection/CollectionRepositoryImpl.java | 30 ++++----
.../service/collection/CollectionService.java | 19 +++--
.../service/user/UserService.java | 70 ++++++++++---------
.../web/controller/SearchRestController.java | 10 ++-
.../web/controller/UserRestController.java | 10 ++-
.../dto/collection/CollectionResponseDTO.java | 2 +-
8 files changed, 73 insertions(+), 77 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java b/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
index 870f6f0b..360c2151 100644
--- a/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
+++ b/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
@@ -47,12 +47,12 @@ public static SearchRequestDTO.SearchConditionDTO toSearchConditionDTO(
public static CollectionResponseDTO.SearchResultDTO toSearchResultDTO(
List collections,
- Long lastId,
boolean hasNext,
int totalPages,
int currentPage,
User currentUser,
- Map learningInfoMap
+ Map learningInfoMap,
+ int totalCount
) {
List list = collections.stream()
.map(collection -> toCollectionPreviewDTO(
@@ -63,10 +63,10 @@ public static CollectionResponseDTO.SearchResultDTO toSearchResultDTO(
return CollectionResponseDTO.SearchResultDTO.builder()
.searchResults(list)
- .lastId(lastId)
.hasNext(hasNext)
.currentPage(currentPage)
.totalPages(totalPages)
+ .totalCount(totalCount)
.build();
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryCustom.java b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryCustom.java
index 432c81a5..0ebb6103 100644
--- a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryCustom.java
+++ b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryCustom.java
@@ -9,9 +9,8 @@
import java.util.List;
public interface CollectionRepositoryCustom {
- List searchCollections(SearchRequestDTO.SearchConditionDTO condition, Long lastId, Pageable pageable);
+ List searchCollections(SearchRequestDTO.SearchConditionDTO condition, Pageable pageable);
Integer getTotalCount(SearchRequestDTO.SearchConditionDTO condition);
- List searchNextPage(SearchRequestDTO.SearchConditionDTO condition, Collection lastCollection, Pageable pageable);
Integer getCountGreaterThanBookmark(Integer bookmarkCount, Long lastId, SearchRequestDTO.SearchConditionDTO condition);
List findTopBookmarkedCollections(int limit);
List findByInterestFieldAndPreferType(List interestFields,
diff --git a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
index 2a0f42eb..8a3159e8 100644
--- a/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
+++ b/src/main/java/learningFlow/learningFlow_BE/repository/collection/CollectionRepositoryImpl.java
@@ -28,10 +28,13 @@ public class CollectionRepositoryImpl implements CollectionRepositoryCustom {
private final QCollection collection = QCollection.collection;
@Override
- public List searchCollections(SearchRequestDTO.SearchConditionDTO condition, Long lastId, Pageable pageable) {
+ public List searchCollections(SearchRequestDTO.SearchConditionDTO condition, Pageable pageable) {
+
+ int skip = pageable.getPageNumber() * pageable.getPageSize();
BooleanExpression searchConditions = createSearchConditions(condition);
+/*
if (lastId == 0L) {
return jpaQueryFactory
.select(episode.collection)
@@ -53,6 +56,16 @@ public List searchCollections(SearchRequestDTO.SearchConditionDTO co
}
return searchNextPage(condition, lastCollection, pageable);
+*/
+ return jpaQueryFactory
+ .select(episode.collection)
+ .from(episode)
+ .where(searchConditions)
+ .groupBy(episode.collection.id)
+ .orderBy(createOrderSpecifier(condition.getSortType()))
+ .offset(skip) // ✅ added: 시작 위치 설정
+ .limit(pageable.getPageSize())
+ .fetch();
}
private OrderSpecifier>[] createOrderSpecifier(Integer sortType) { // 반환 타입을 배열로 변경
@@ -86,21 +99,6 @@ public Integer getTotalCount(SearchRequestDTO.SearchConditionDTO condition) {
return count != null ? count.intValue() : 0;
}
- @Override
- public List searchNextPage(SearchRequestDTO.SearchConditionDTO condition, Collection lastCollection, Pageable pageable) {
- BooleanExpression searchConditions = createSearchConditions(condition);
- BooleanExpression cursorCondition = createCursorCondition(condition.getSortType(), lastCollection);
-
- return jpaQueryFactory
- .select(episode.collection)
- .from(episode)
- .where(searchConditions, cursorCondition)
- .groupBy(episode.collection.id)
- .orderBy(createOrderSpecifier(condition.getSortType()))
- .limit(pageable.getPageSize())
- .fetch();
- }
-
private BooleanExpression createCursorCondition(Integer sortType, Collection lastCollection) {
if (sortType == null || sortType == 0) {
return episode.collection.id.lt(lastCollection.getId());
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/collection/CollectionService.java b/src/main/java/learningFlow/learningFlow_BE/service/collection/CollectionService.java
index 8c0d0b0e..309d7fe0 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/collection/CollectionService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/collection/CollectionService.java
@@ -68,22 +68,23 @@ private List getAllResources(
.toList();
}
- public CollectionResponseDTO.SearchResultDTO search(SearchRequestDTO.SearchConditionDTO condition, Long lastId, PrincipalDetails principalDetails) {
+ public CollectionResponseDTO.SearchResultDTO search(SearchRequestDTO.SearchConditionDTO condition, Integer page, PrincipalDetails principalDetails) {
Authentication authentication = (principalDetails != null) ? SecurityContextHolder.getContext().getAuthentication() : null;
- PageRequest pageRequest = PageRequest.of(0, PAGE_SIZE);
- List collections = collectionRepository.searchCollections(condition, lastId, pageRequest);
+ PageRequest pageRequest = PageRequest.of(page - 1, PAGE_SIZE);
+ List collections = collectionRepository.searchCollections(condition, pageRequest);
if (collections.isEmpty()) {
- return CollectionConverter.toSearchResultDTO(collections, null, false, 0, 0, null, null);
+ return CollectionConverter.toSearchResultDTO(collections, false, 0, 0, null, null, 0);
}
Collection lastCollection = collections.getLast();
- boolean hasNext = hasNextPage(condition, lastCollection);
Integer totalCount = collectionRepository.getTotalCount(condition);
+
int totalPages = (int) Math.ceil((double) totalCount / PAGE_SIZE);
+ boolean hasNext = page < totalPages;
int currentPage = calculateCurrentPage(condition, lastCollection);
@@ -102,12 +103,12 @@ public CollectionResponseDTO.SearchResultDTO search(SearchRequestDTO.SearchCondi
return CollectionConverter.toSearchResultDTO(
collections,
- lastCollection.getId(),
hasNext,
totalPages,
currentPage,
currentUser,
- learningInfoMap
+ learningInfoMap,
+ totalCount
);
}
@@ -290,8 +291,4 @@ private CollectionResponseDTO.CollectionPreviewDTO getRecentLearning(User user)
private int calculateCurrentPage(SearchRequestDTO.SearchConditionDTO condition, Collection lastCollection) {
return collectionRepository.getCountGreaterThanBookmark(lastCollection.getBookmarkCount(),lastCollection.getId(), condition) / PAGE_SIZE + 1;
}
-
- private boolean hasNextPage(SearchRequestDTO.SearchConditionDTO condition, Collection lastCollection) {
- return !collectionRepository.searchNextPage(condition, lastCollection, PageRequest.of(0, 1)).isEmpty();
- }
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/user/UserService.java b/src/main/java/learningFlow/learningFlow_BE/service/user/UserService.java
index cc0e0ba7..3174a59d 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/user/UserService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/user/UserService.java
@@ -131,46 +131,52 @@ public BookmarkDTO.BookmarkResponseDTO toggleBookmark(String loginId, Long colle
return new BookmarkDTO.BookmarkResponseDTO(!isCurrentlyBookmarked);
}
- public CollectionResponseDTO.SearchResultDTO getBookmarkedCollections(String loginId, Long lastId) {
+ public CollectionResponseDTO.SearchResultDTO getBookmarkedCollections(String loginId, Integer page) {
User user = userRepository.findById(loginId)
.orElseThrow(() -> new UserHandler(ErrorStatus.USER_NOT_FOUND));
- // 북마크된 컬렉션 ID 목록 가져오기
List bookmarkedIds = user.getBookmarkedCollectionIds();
-
- if (bookmarkedIds.isEmpty()) {
- return CollectionConverter.toSearchResultDTO(new ArrayList<>(), null, false, 0, 0, user, new HashMap<>());
+ int totalCount = bookmarkedIds.size();
+
+ // 북마크가 없는 경우
+ if (totalCount == 0) {
+ return CollectionConverter.toSearchResultDTO(
+ new ArrayList<>(),
+ false,
+ 0,
+ page,
+ user,
+ new HashMap<>(),
+ 0
+ );
}
- // lastId 이후의 컬렉션만 필터링
- List collections;
- if (lastId == 0) {
- collections = collectionRepository.findByIdIn(
- bookmarkedIds.stream()
- .limit(BOOKMARK_PAGE_SIZE)
- .toList()
- );
- } else {
- int startIndex = bookmarkedIds.indexOf(lastId) + 1;
- if (startIndex == 0 || startIndex >= bookmarkedIds.size()) {
- return CollectionConverter.toSearchResultDTO(new ArrayList<>(), null, false, 0, 0, user, new HashMap<>());
- }
- collections = collectionRepository.findByIdIn(
- bookmarkedIds.stream()
- .skip(startIndex)
- .limit(BOOKMARK_PAGE_SIZE)
- .toList()
- );
+ int totalPages = (int) Math.ceil((double) totalCount / BOOKMARK_PAGE_SIZE);
+
+ // 페이지가 범위를 벗어나면 마지막 페이지 데이터 반환
+ if (page > totalPages) {
+ page = totalPages;
}
+ int startIndex = (page - 1) * BOOKMARK_PAGE_SIZE;
+ int endIndex = Math.min(startIndex + BOOKMARK_PAGE_SIZE, totalCount);
+
+ List pageBookmarkIds = bookmarkedIds.subList(startIndex, endIndex);
+ List collections = collectionRepository.findByIdIn(pageBookmarkIds);
+
if (collections.isEmpty()) {
- return CollectionConverter.toSearchResultDTO(collections, null, false, 0, 0, user, new HashMap<>());
+ return CollectionConverter.toSearchResultDTO(
+ collections,
+ false,
+ totalPages,
+ page,
+ user,
+ new HashMap<>(),
+ totalCount
+ );
}
- Long lastCollectionId = collections.getLast().getId();
- boolean hasNext = (bookmarkedIds.indexOf(lastCollectionId) + 1) < bookmarkedIds.size();
- int totalPages = (int) Math.ceil((double) bookmarkedIds.size() / BOOKMARK_PAGE_SIZE);
- int currentPage = (lastId == 0) ? 1 : (bookmarkedIds.indexOf(lastId) / BOOKMARK_PAGE_SIZE) + 2;
+ boolean hasNext = page < totalPages;
Map learningInfoMap = collections.stream()
.collect(Collectors.toMap(
@@ -180,12 +186,12 @@ public CollectionResponseDTO.SearchResultDTO getBookmarkedCollections(String log
return CollectionConverter.toSearchResultDTO(
collections,
- lastCollectionId,
hasNext,
totalPages,
- currentPage,
+ page,
user,
- learningInfoMap
+ learningInfoMap,
+ totalCount
);
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/SearchRestController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/SearchRestController.java
index 70960880..f85247bc 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/SearchRestController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/SearchRestController.java
@@ -71,9 +71,7 @@ public class SearchRestController {
- 1: 좋아요순
[페이지네이션]
- - 무한 스크롤 방식
- - lastId: 마지막으로 조회된 컬렉션 ID
- - 첫 페이지는 lastId=0
+ - 커서기반 페이징
- 8개씩 조회
[응답 정보]
@@ -101,7 +99,7 @@ public class SearchRestController {
@Parameter(name = "difficulties", description = "난이도 목록 (1:입문, 2:초급, 3:중급, 4:실무)", example = "[1, 2]"),
@Parameter(name = "amounts", description = "학습량 (SHORT, MEDIUM, LONG)", example = "[\"SHORT\", \"MEDIUM\"]"),
@Parameter(name = "sortType", description = "정렬 기준 (0:최신순, 1:좋아요순)", example = "0"),
- @Parameter(name = "lastId", description = "마지막 컬렉션 ID (첫 페이지: 0)", example = "0")
+ @Parameter(name = "page", description = "페이지 번호 (1부터 시작)")
})
public ApiResponse searchEpisodes(
@RequestParam(required = false) String keyword,
@@ -110,13 +108,13 @@ public ApiResponse searchEpisodes(
@RequestParam(required = false) List difficulties,
@RequestParam(required = false) List amounts,
@RequestParam(required = false, defaultValue = "0") Integer sortType,
- @RequestParam(required = false, defaultValue = "0") Long lastId,
+ @RequestParam(required = false, defaultValue = "1") Integer page,
@AuthenticationPrincipal PrincipalDetails principalDetails
) {
return ApiResponse.onSuccess(
collectionService.search(
CollectionConverter.toSearchConditionDTO(keyword, interestFields, preferMediaType, difficulties, amounts, sortType),
- lastId, principalDetails)
+ page, principalDetails)
);
}
}
\ No newline at end of file
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/UserRestController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/UserRestController.java
index 8121bc1e..9f653246 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/UserRestController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/UserRestController.java
@@ -202,9 +202,7 @@ public ApiResponse getMyPage(
- 본인의 좋아요 상태
[페이지네이션]
- - 무한 스크롤 방식
- - lastId: 마지막으로 조회된 컬렉션 ID
- - 첫 페이지는 lastId=0
+ - 커서 기반 페이징
- 한 페이지당 8개 조회
- 좋아요 시간 기준 내림차순 정렬
""")
@@ -213,14 +211,14 @@ public ApiResponse getMyPage(
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "AUTH4001", description = "로그인이 필요한 서비스입니다.")
})
@Parameters({
- @Parameter(name = "lastId", description = "마지막으로 조회된 컬렉션 ID (첫 페이지: 0)", example = "0")
+ @Parameter(name = "page", description = "페이지 번호 (1부터 시작)")
})
public ApiResponse getBookmarkedCollections(
- @RequestParam(required = false, defaultValue = "0") Long lastId,
+ @RequestParam(required = false, defaultValue = "1") Integer page,
@AuthenticationPrincipal PrincipalDetails principalDetails
) {
return ApiResponse.onSuccess(
- userService.getBookmarkedCollections(principalDetails.getUser().getLoginId(), lastId)
+ userService.getBookmarkedCollections(principalDetails.getUser().getLoginId(), page)
);
}
}
\ No newline at end of file
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
index f77b9738..3adc5bb2 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
@@ -21,10 +21,10 @@ public class CollectionResponseDTO {
@AllArgsConstructor
public static class SearchResultDTO {
List searchResults;
- Long lastId; // 마지막 컬렉션의 ID
Boolean hasNext; // 다음 페이지 존재 여부
Integer currentPage; //현재 페이지
Integer totalPages; //전체 페이지 수
+ int totalCount;
}
@Getter
From 383142a04e2107e75e6c33f32e8f701c683c45f3 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 05:13:50 +0900
Subject: [PATCH 10/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/learningFlow/learningFlow_BE/config/CorsConfig.java | 2 ++
.../java/learningFlow/learningFlow_BE/config/WebConfig.java | 2 ++
.../security/handler/OAuth2LoginSuccessHandler.java | 4 ++++
3 files changed, 8 insertions(+)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
index 9383e4cd..080ca919 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/CorsConfig.java
@@ -1,3 +1,4 @@
+/*
package learningFlow.learningFlow_BE.config;
//Spring Security까지 CORS 적용 목적
@@ -41,3 +42,4 @@ public CorsFilter corsFilter() {
return new CorsFilter(source);
}
}
+*/
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
index e8c22c70..b5040d3d 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/WebConfig.java
@@ -1,3 +1,4 @@
+/*
package learningFlow.learningFlow_BE.config;
import org.springframework.context.annotation.Configuration;
@@ -25,3 +26,4 @@ public void addCorsMappings(CorsRegistry registry) {
.maxAge(86400L);
}
}
+*/
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index a5cd5cf4..9dbb7dd9 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -11,6 +11,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@@ -62,6 +63,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
log.info("Authorization Header: {}", response.getHeader("Authorization"));
log.info("Refresh-Token Header: {}", response.getHeader("Refresh-Token"));
+/*
UserResponseDTO.UserLoginResponseDTO loginResponse =
toUserLoginResponseDTO(principalDetails.getUser());
@@ -69,5 +71,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
response.setCharacterEncoding("UTF-8");
String jsonResponse = new ObjectMapper().writeValueAsString(ApiResponse.onSuccess(loginResponse));
response.getWriter().write(jsonResponse);
+*/
+ response.setStatus(HttpStatus.OK.value());
}
}
From 212c386616aa5847ab0267ef20d4b4a9356056f0 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 05:48:09 +0900
Subject: [PATCH 11/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../learningFlow_BE/config/security/SecurityConfig.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index 8af83159..b99b3bfa 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -53,7 +53,8 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilte
"/search/**",
"/",
"/collections/{collectionId:[\\d]+}",
- "/image/upload" //이미지 업로드는 허용
+ "/image/upload", //이미지 업로드는 허용
+ "/favicon.ico"
).permitAll()
.requestMatchers(
"/register", "/register/complete", "/login", "/login/google", "/oauth2/**").permitAll()
@@ -105,7 +106,11 @@ public CorsConfigurationSource corsConfigurationSource() {
"Authorization",
"Refresh-Token",
"Access-Control-Allow-Origin",
- "Access-Control-Allow-Credentials"
+ "Access-Control-Allow-Credentials",
+ "Content-Type",
+ "Accept",
+ "Origin",
+ "X-Requested-With"
));
configuration.setMaxAge(86400L);
From bc195bf1d9668bee1182d458bb525ecb8c178fe2 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 05:59:40 +0900
Subject: [PATCH 12/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../security/handler/OAuth2LoginSuccessHandler.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 9dbb7dd9..7c4b5f6c 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -63,6 +63,12 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
log.info("Authorization Header: {}", response.getHeader("Authorization"));
log.info("Refresh-Token Header: {}", response.getHeader("Refresh-Token"));
+ // ✅ 임시: Access-Control-Allow-Origin 헤더 명시적 추가
+ response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); // 개발 환경
+ // response.setHeader("Access-Control-Allow-Origin", "http://your-frontend-domain.com"); // 배포 환경
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+
+
/*
UserResponseDTO.UserLoginResponseDTO loginResponse =
toUserLoginResponseDTO(principalDetails.getUser());
From 8e07833fef5095097471954148ea43dd755e10c3 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 06:08:36 +0900
Subject: [PATCH 13/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../learningFlow_BE/config/security/SecurityConfig.java | 6 ++----
.../security/handler/OAuth2LoginSuccessHandler.java | 6 ------
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index b99b3bfa..8ce9f190 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -53,11 +53,10 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilte
"/search/**",
"/",
"/collections/{collectionId:[\\d]+}",
- "/image/upload", //이미지 업로드는 허용
- "/favicon.ico"
+ "/image/upload" //이미지 업로드는 허용
).permitAll()
.requestMatchers(
- "/register", "/register/complete", "/login", "/login/google", "/oauth2/**").permitAll()
+ "/register", "/register/complete", "/login", "/login/google", "/oauth2/**", "/login/oauth2/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**", "/resources/**", "/collections/{collectionId:[\\d]+}/likes", "/logout/**").authenticated()
.anyRequest().permitAll()
@@ -73,7 +72,6 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilte
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling(exception ->
exception.authenticationEntryPoint(authenticationEntryPoint));
-
return http.build();
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 7c4b5f6c..9dbb7dd9 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -63,12 +63,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
log.info("Authorization Header: {}", response.getHeader("Authorization"));
log.info("Refresh-Token Header: {}", response.getHeader("Refresh-Token"));
- // ✅ 임시: Access-Control-Allow-Origin 헤더 명시적 추가
- response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); // 개발 환경
- // response.setHeader("Access-Control-Allow-Origin", "http://your-frontend-domain.com"); // 배포 환경
- response.setHeader("Access-Control-Allow-Credentials", "true");
-
-
/*
UserResponseDTO.UserLoginResponseDTO loginResponse =
toUserLoginResponseDTO(principalDetails.getUser());
From 58674dd5a022d7207c44d224f50b8c9ab4f80eee Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 06:50:44 +0900
Subject: [PATCH 14/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../security/handler/OAuth2LoginSuccessHandler.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 9dbb7dd9..3e4d9f7d 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -63,6 +63,8 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
log.info("Authorization Header: {}", response.getHeader("Authorization"));
log.info("Refresh-Token Header: {}", response.getHeader("Refresh-Token"));
+ response.addHeader("Access-Control-Expose-Headers", "Authorization, Refresh-Token");
+
/*
UserResponseDTO.UserLoginResponseDTO loginResponse =
toUserLoginResponseDTO(principalDetails.getUser());
From 4f9a8b2b573acfd57e53d5743230a97e952d22bc Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Tue, 11 Feb 2025 18:54:10 +0900
Subject: [PATCH 15/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../config/security/SecurityConfig.java | 3 ++-
.../handler/OAuth2LoginSuccessHandler.java | 8 +++++---
.../security/jwt/JwtAuthenticationFilter.java | 3 +--
.../web/controller/LoginController.java | 15 +++++++++++++--
4 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index 8ce9f190..59f7589d 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -53,7 +53,8 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilte
"/search/**",
"/",
"/collections/{collectionId:[\\d]+}",
- "/image/upload" //이미지 업로드는 허용
+ "/image/upload", //이미지 업로드는 허용
+ "/favicon.ico"
).permitAll()
.requestMatchers(
"/register", "/register/complete", "/login", "/login/google", "/oauth2/**", "/login/oauth2/**").permitAll()
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 3e4d9f7d..6c1accc6 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -53,17 +53,19 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
//Access Token 생성
String accessToken = jwtTokenProvider.createAccessToken(authentication);
log.info("Access 토큰 발급 : {}", accessToken);
- response.addHeader("Authorization", "Bearer " + accessToken);
+ response.setHeader("Authorization", "Bearer " + accessToken);
String refreshToken = jwtTokenProvider.createRefreshToken(authentication);
log.info("자동 로그인 활성화, Refresh Token 발급 : {}", refreshToken);
- response.addHeader("Refresh-Token", refreshToken);
+ response.setHeader("Refresh-Token", refreshToken);
// 헤더 설정 확인 로깅
log.info("Authorization Header: {}", response.getHeader("Authorization"));
log.info("Refresh-Token Header: {}", response.getHeader("Refresh-Token"));
- response.addHeader("Access-Control-Expose-Headers", "Authorization, Refresh-Token");
+ response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ response.setHeader("Access-Control-Expose-Headers", "Authorization, Refresh-Token");
/*
UserResponseDTO.UserLoginResponseDTO loginResponse =
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/jwt/JwtAuthenticationFilter.java b/src/main/java/learningFlow/learningFlow_BE/security/jwt/JwtAuthenticationFilter.java
index 3673a330..bf238174 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/jwt/JwtAuthenticationFilter.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/jwt/JwtAuthenticationFilter.java
@@ -134,11 +134,10 @@ private boolean isPermitAllUrl(String requestURI) {
requestURI.startsWith("/user/imgUpload"); // 이미지 업로드는 인증 없이 허용
}
-
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String path = request.getRequestURI();
- boolean shouldSkip = path.equals("/image/upload");
+ boolean shouldSkip = path.equals("/image/upload") || path.equals("/favicon.ico");
log.info("🛑 [JwtAuthenticationFilter] shouldNotFilter 실행: path={}, shouldSkip={}", path, shouldSkip);
return shouldSkip;
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
index ade22156..108f6539 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
@@ -20,7 +20,10 @@
import learningFlow.learningFlow_BE.web.dto.user.UserResponseDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -120,8 +123,16 @@ public ApiResponse login(
*/
@GetMapping("/login/google")
@Operation(summary = "구글 로그인 리다이렉트", description = "구글 로그인 페이지로 리다이렉트하는 API\n"+"리다이렉트해야하므로 swagger에서는 테스트 불가!")
- public void googleLogin(HttpServletResponse response) throws IOException {
- response.sendRedirect("/oauth2/authorization/google");
+ public ResponseEntity googleLogin(HttpServletResponse response) throws IOException {
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.setAccessControlAllowOrigin("*");
+ headers.setAccessControlAllowCredentials(true);
+ headers.set("Location", "/oauth2/authorization/google");
+
+ return new ResponseEntity<>(headers, HttpStatus.FOUND);
+
+// response.sendRedirect("/oauth2/authorization/google");
}
/**
From ba9a59df33e594f04e25f6eb0b7c99065da17947 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Wed, 12 Feb 2025 14:42:17 +0900
Subject: [PATCH 16/24] =?UTF-8?q?feat=20:=20=EA=B5=AC=EA=B8=80=20=EB=A1=9C?=
=?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../config/security/SecurityConfig.java | 10 +++++++---
.../web/controller/LoginController.java | 12 ++----------
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
index 59f7589d..3b1170b8 100644
--- a/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
+++ b/src/main/java/learningFlow/learningFlow_BE/config/security/SecurityConfig.java
@@ -54,10 +54,14 @@ public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthenticationFilte
"/",
"/collections/{collectionId:[\\d]+}",
"/image/upload", //이미지 업로드는 허용
- "/favicon.ico"
+ "/favicon.ico",
+ "/register",
+ "/register/complete",
+ "/login",
+ "/login/google",
+ "/oauth2/**",
+ "/login/oauth2/**"
).permitAll()
- .requestMatchers(
- "/register", "/register/complete", "/login", "/login/google", "/oauth2/**", "/login/oauth2/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**", "/resources/**", "/collections/{collectionId:[\\d]+}/likes", "/logout/**").authenticated()
.anyRequest().permitAll()
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
index 108f6539..01b8fa40 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/controller/LoginController.java
@@ -123,16 +123,8 @@ public ApiResponse login(
*/
@GetMapping("/login/google")
@Operation(summary = "구글 로그인 리다이렉트", description = "구글 로그인 페이지로 리다이렉트하는 API\n"+"리다이렉트해야하므로 swagger에서는 테스트 불가!")
- public ResponseEntity googleLogin(HttpServletResponse response) throws IOException {
-
- HttpHeaders headers = new HttpHeaders();
- headers.setAccessControlAllowOrigin("*");
- headers.setAccessControlAllowCredentials(true);
- headers.set("Location", "/oauth2/authorization/google");
-
- return new ResponseEntity<>(headers, HttpStatus.FOUND);
-
-// response.sendRedirect("/oauth2/authorization/google");
+ public void googleLogin(HttpServletResponse response) throws IOException {
+ response.sendRedirect("/oauth2/authorization/google");
}
/**
From 416fe0773aa1b864fe4c6732a9dc46bea12180bd Mon Sep 17 00:00:00 2001
From: LJYeon12
Date: Wed, 12 Feb 2025 18:11:26 +0900
Subject: [PATCH 17/24] =?UTF-8?q?youtube=20ad=20=EC=A0=9C=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../service/embed/YoutubeUrlEmbedService.java | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java b/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
index 2b18e3a2..b52a9823 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
@@ -41,27 +41,25 @@ public String EmbedUrl(String youtubeUrl){
String host = uri.getHost();
String query = uri.getQuery();
String path = uri.getPath();
+ String adExistUrl = null;
// 기본 형식: https://www.youtube.com/watch?v=
if (host.contains("youtube.com") && query != null && query.contains("v=")){
String[] params = query.split("&");
for (String param : params) {
if (param.startsWith("v=")){
String videoId = param.substring(2);
- return "https://www.youtube.com/embed/" + videoId;
+ return "https:///www.youtube-nocookie.com/embed" + videoId;
}
}
}
// 축약형: https://youtu.be/
if (host.contains("youtube.be") && path != null && path.length() > 1) {
String videoId = path.substring(1); // 맨 앞 "/" 제거
- return "https://youtu.be/embed/" + videoId;
+ return "https:///www.youtube-nocookie.com/embed/" + videoId;
}
-
throw new ResourceHandler(ErrorStatus.YOUTUBE_URI_SYNTAX_ERROR);
} catch (URISyntaxException e) {
throw new ResourceHandler(ErrorStatus.URI_SYNTAX_ERROR);
}
}
-
-
}
From af7b91872106dafb984353f623e6c593df0c7a31 Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Thu, 13 Feb 2025 10:57:02 +0900
Subject: [PATCH 18/24] =?UTF-8?q?feat=20:=20CollectionDTO=EC=97=90=20image?=
=?UTF-8?q?Url=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../learningFlow_BE/converter/CollectionConverter.java | 1 +
.../web/dto/collection/CollectionResponseDTO.java | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java b/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
index 360c2151..35a5fea8 100644
--- a/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
+++ b/src/main/java/learningFlow/learningFlow_BE/converter/CollectionConverter.java
@@ -82,6 +82,7 @@ public static CollectionResponseDTO.CollectionPreviewDTO toCollectionPreviewDTO(
return CollectionResponseDTO.CollectionPreviewDTO.builder()
.collectionId(collection.getId())
+ .imageUrl(collection.getCollectionImgUrl())
.interestField(collection.getInterestField())
.title(collection.getTitle())
.creator(collection.getCreator())
diff --git a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
index 3adc5bb2..b29e3a53 100644
--- a/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
+++ b/src/main/java/learningFlow/learningFlow_BE/web/dto/collection/CollectionResponseDTO.java
@@ -33,6 +33,7 @@ public static class SearchResultDTO {
@AllArgsConstructor
public static class CollectionPreviewDTO {
Long collectionId;
+ String imageUrl;
InterestField interestField;
String title;
String creator;
From 314618d30a46a810711112a1f31d87955d37b0e1 Mon Sep 17 00:00:00 2001
From: LJYeon12
Date: Thu, 13 Feb 2025 11:30:50 +0900
Subject: [PATCH 19/24] =?UTF-8?q?=EC=9C=A0=ED=8A=9C=EB=B8=8C=20=EA=B4=91?=
=?UTF-8?q?=EA=B3=A0=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../learningFlow_BE/service/embed/YoutubeUrlEmbedService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java b/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
index b52a9823..4de89a0e 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/embed/YoutubeUrlEmbedService.java
@@ -48,7 +48,7 @@ public String EmbedUrl(String youtubeUrl){
for (String param : params) {
if (param.startsWith("v=")){
String videoId = param.substring(2);
- return "https:///www.youtube-nocookie.com/embed" + videoId;
+ return "https:///www.youtube-nocookie.com/embed/" + videoId;
}
}
}
From 2aab6a1798884ed950d2b772f713ea222048482c Mon Sep 17 00:00:00 2001
From: MODUGGAGI
Date: Thu, 13 Feb 2025 17:06:14 +0900
Subject: [PATCH 20/24] =?UTF-8?q?feat=20:=20=EC=BF=BC=EB=A6=AC=20=EC=8A=A4?=
=?UTF-8?q?=ED=8A=B8=EB=A7=81=EC=97=90=20=EB=93=A4=EC=96=B4=EA=B0=80?=
=?UTF-8?q?=EB=8D=98=20token=20=EC=9D=B4=EB=9D=BC=EB=8A=94=20=EC=9D=B4?=
=?UTF-8?q?=EB=A6=84=EC=9D=84=20=EA=B0=81=20=EA=B2=BD=EC=9A=B0=EC=97=90=20?=
=?UTF-8?q?=EB=A7=9E=EB=8A=94=20=EC=9D=B4=EB=A6=84=EC=9C=BC=EB=A1=9C=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../handler/OAuth2LoginSuccessHandler.java | 2 +-
.../common/UserVerificationEmailService.java | 8 ++++----
.../auth/local/LocalUserAuthService.java | 16 +++++++--------
.../web/controller/LoginController.java | 20 +++++++++----------
4 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
index 6c1accc6..ccca6b8e 100644
--- a/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
+++ b/src/main/java/learningFlow/learningFlow_BE/security/handler/OAuth2LoginSuccessHandler.java
@@ -39,7 +39,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
// Principal 타입 확인, 첫 로그인인 경우 회원가입으로 이동
if (authentication.getPrincipal() instanceof OAuth2UserTemp oAuth2UserTemp) {
String temporaryToken = jwtTokenProvider.createTemporaryToken(oAuth2UserTemp);
- String redirectUrl = frontendUrl + "/oauth2/additional-info?token=" + temporaryToken;
+ String redirectUrl = frontendUrl + "/oauth2/additional-info?oauth2RegistrationCode=" + temporaryToken;
response.sendRedirect(redirectUrl);
return;
}
diff --git a/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java b/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
index 793e0ef6..83b56435 100644
--- a/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
+++ b/src/main/java/learningFlow/learningFlow_BE/service/auth/common/UserVerificationEmailService.java
@@ -73,7 +73,7 @@ public void sendVerificationEmail(String email, String token) {
버튼을 누르면 자동으로 인증 후 추가 정보 입력 페이지로 이동합니다.
-
이메일 인증하기
@@ -101,7 +101,7 @@ public void sendVerificationEmail(String email, String token) {
}
}
- public void sendPasswordResetEmail(String email, String token) {
+ public void sendPasswordResetEmail(String email, String passwordResetCode) {
try {
MimeMessage message = emailSender.createMimeMessage();
@@ -156,7 +156,7 @@ public void sendPasswordResetEmail(String email, String token) {
버튼을 누르면 자동으로 인증 후 비밀번호 재설정 페이지로 이동합니다.
-
이메일 인증하기
@@ -173,7 +173,7 @@ public void sendPasswordResetEmail(String email, String token) {