Skip to content

Commit dc91825

Browse files
authored
Merge pull request #107 from prgrms-web-devcourse-final-project/refactor#106
[refactor] 카카오 리다이렉트 url 매핑 수정 & 배포 설정 변경
2 parents 10e064b + be6f102 commit dc91825

File tree

11 files changed

+179
-19
lines changed

11 files changed

+179
-19
lines changed

src/main/java/com/back/domain/notification/controller/NotificationController.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import com.back.domain.notification.dto.NotificationGoResponseDto;
44
import com.back.domain.notification.dto.NotificationListResponseDto;
5+
import com.back.domain.notification.dto.NotificationSettingDto;
6+
import com.back.domain.notification.service.NotificationSettingService;
7+
import com.back.domain.notification.dto.NotificationSettingUpdateRequestDto;
8+
import jakarta.validation.Valid;
59
import com.back.domain.notification.service.NotificationService;
610
import com.back.global.rsData.RsData;
711
import jakarta.validation.constraints.Max;
@@ -21,6 +25,7 @@
2125
public class NotificationController {
2226

2327
private final NotificationService notificationService;
28+
private final NotificationSettingService notificationSettingService;
2429

2530
@GetMapping("/notifications")
2631
public RsData<NotificationListResponseDto> getNotifications(
@@ -33,6 +38,23 @@ public RsData<NotificationListResponseDto> getNotifications(
3338
return RsData.successOf(body);
3439
}
3540

41+
@GetMapping("/notification-setting")
42+
public RsData<NotificationSettingDto> getMyNotificationSetting(
43+
@AuthenticationPrincipal(expression = "id") Long userId
44+
) {
45+
NotificationSettingDto body = notificationSettingService.getMySetting(userId);
46+
return RsData.successOf(body);
47+
}
48+
49+
@PatchMapping("/notification-setting")
50+
public RsData<NotificationSettingDto> setMyNotificationSetting(
51+
@AuthenticationPrincipal(expression = "id") Long userId,
52+
@Valid @RequestBody NotificationSettingUpdateRequestDto req
53+
) {
54+
NotificationSettingDto body = notificationSettingService.setMySetting(userId, req.enabled());
55+
return RsData.successOf(body);
56+
}
57+
3658
@PostMapping("/notifications/{id}")
3759
public RsData<NotificationGoResponseDto> goPostLink(
3860
@AuthenticationPrincipal(expression = "id") Long userId,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.back.domain.notification.dto;
2+
3+
import com.back.domain.notification.entity.NotificationSetting;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@AllArgsConstructor
9+
public class NotificationSettingDto {
10+
private boolean enabled;
11+
12+
public static NotificationSettingDto from(NotificationSetting s) {
13+
return new NotificationSettingDto(s.isEnabled());
14+
}
15+
}
16+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.back.domain.notification.dto;
2+
3+
import jakarta.validation.constraints.NotNull;
4+
5+
public record NotificationSettingUpdateRequestDto(
6+
@NotNull Boolean enabled
7+
) {}
8+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.back.domain.notification.entity;
2+
3+
import com.back.domain.user.entity.User;
4+
import jakarta.persistence.*;
5+
import lombok.*;
6+
import org.springframework.data.annotation.CreatedDate;
7+
import org.springframework.data.annotation.LastModifiedDate;
8+
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
9+
10+
import java.time.LocalDateTime;
11+
12+
@Entity
13+
@EntityListeners(AuditingEntityListener.class)
14+
@Getter
15+
@Setter
16+
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
17+
@AllArgsConstructor
18+
@Builder
19+
public class NotificationSetting {
20+
21+
@Id
22+
@GeneratedValue(strategy = GenerationType.IDENTITY)
23+
private Long id;
24+
25+
@Setter
26+
@OneToOne(fetch = FetchType.LAZY)
27+
@JoinColumn(name = "user_id", nullable = false, unique = true)
28+
private User user;
29+
30+
@Setter
31+
@Builder.Default
32+
private boolean enabled = true;
33+
34+
@CreatedDate
35+
private LocalDateTime createdAt;
36+
37+
@LastModifiedDate
38+
private LocalDateTime updatedAt;
39+
40+
public void toggle() {
41+
this.enabled = !this.enabled;
42+
}
43+
44+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.back.domain.notification.repository;
2+
3+
import com.back.domain.notification.entity.NotificationSetting;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.data.repository.query.Param;
7+
import org.springframework.stereotype.Repository;
8+
9+
@Repository
10+
public interface NotificationSettingRepository extends JpaRepository<NotificationSetting, Long> {
11+
12+
@Query("""
13+
select ns from NotificationSetting ns
14+
where ns.user.id = :userId
15+
""")
16+
NotificationSetting findByUserId(@Param("userId") Long userId);
17+
}
18+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.back.domain.notification.service;
2+
3+
import com.back.domain.notification.dto.NotificationSettingDto;
4+
import com.back.domain.notification.entity.NotificationSetting;
5+
import com.back.domain.notification.repository.NotificationSettingRepository;
6+
import com.back.domain.user.entity.User;
7+
import com.back.domain.user.repository.UserRepository;
8+
import com.back.global.exception.ServiceException;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.stereotype.Service;
11+
import org.springframework.transaction.annotation.Transactional;
12+
13+
@Service
14+
@RequiredArgsConstructor
15+
public class NotificationSettingService {
16+
17+
private final NotificationSettingRepository notificationSettingRepository;
18+
private final UserRepository userRepository;
19+
20+
@Transactional(readOnly = true)
21+
public NotificationSettingDto getMySetting(Long userId) {
22+
NotificationSetting s = notificationSettingRepository.findByUserId(userId);
23+
if (s == null) {
24+
// Default when not created yet
25+
return new NotificationSettingDto(true);
26+
}
27+
return NotificationSettingDto.from(s);
28+
}
29+
30+
@Transactional
31+
public NotificationSettingDto setMySetting(Long userId, boolean enabled) {
32+
NotificationSetting s = notificationSettingRepository.findByUserId(userId);
33+
if (s == null) {
34+
User user = userRepository.findById(userId)
35+
.orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다."));
36+
s = NotificationSetting.builder()
37+
.user(user)
38+
.enabled(enabled)
39+
.build();
40+
} else {
41+
s.setEnabled(enabled);
42+
}
43+
NotificationSetting saved = notificationSettingRepository.save(s);
44+
return NotificationSettingDto.from(saved);
45+
}
46+
}

src/main/java/com/back/global/jwt/refreshToken/service/RefreshTokenService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class RefreshTokenService {
2525
private long refreshTokenExpiration;
2626

2727
// 기존 리프레시 토큰 삭제하고 생성
28+
@Transactional
2829
public String generateRefreshToken(Long userId, String email) {
2930
// 기존 토큰 삭제
3031
refreshTokenRepository.deleteByUserId(userId);
@@ -53,6 +54,7 @@ public boolean validateToken(String token) {
5354
}
5455

5556
//기존 토큰 지우고 발급(회전)
57+
@Transactional
5658
public String rotateToken(String oldToken) {
5759
Optional<RefreshToken> oldRefreshToken = refreshTokenRepository.findByToken(oldToken);
5860

@@ -67,6 +69,7 @@ public String rotateToken(String oldToken) {
6769
}
6870

6971
//삭제
72+
@Transactional
7073
public void revokeToken(String token) {
7174
refreshTokenRepository.deleteByToken(token);
7275
}

src/main/java/com/back/global/security/CustomOAuth2LoginSuccessHandler.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public class CustomOAuth2LoginSuccessHandler implements AuthenticationSuccessHan
2424
@Override
2525
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
2626
SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
27-
2827
// Access Token과 Refresh Token 발급
2928
userAuthService.issueTokens(response, securityUser.getId(), securityUser.getEmail(), securityUser.getNickname());
3029

src/main/java/com/back/global/security/SecurityConfig.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.back.global.security;
22

3+
import org.springframework.beans.factory.annotation.Value;
34
import org.springframework.context.annotation.Bean;
45
import org.springframework.context.annotation.Configuration;
56
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -18,6 +19,12 @@
1819
@EnableWebSecurity
1920
public class SecurityConfig {
2021

22+
@Value("${custom.site.frontUrl}")
23+
private String frontUrl;
24+
25+
@Value("${custom.site.backUrl}")
26+
private String backUrl;
27+
2128
private final CustomOAuth2UserService customOAuth2UserService;
2229
private final CustomOAuth2LoginSuccessHandler oauth2SuccessHandler;
2330
private final CustomOAuth2LoginFailureHandler oauth2FailureHandler;
@@ -46,18 +53,16 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
4653
.authorizeHttpRequests(auth -> auth
4754
.requestMatchers("/").permitAll()
4855
.requestMatchers("/h2-console/**").permitAll()
56+
.requestMatchers("/actuator/**").permitAll()
4957
.requestMatchers("/oauth2/**").permitAll()
5058
.requestMatchers("/login/oauth2/**").permitAll()
5159
.requestMatchers("/swagger-ui/**", "/api-docs/**").permitAll()
52-
.requestMatchers("/api/user/**").permitAll()
53-
.requestMatchers("/api/cocktail/**").permitAll()
54-
.requestMatchers("/api/chatbot/**").permitAll()
55-
.requestMatchers("/api/cocktails/**").permitAll()
56-
60+
.requestMatchers("/user/**").permitAll()
61+
.requestMatchers("/cocktails/**").permitAll()
62+
.requestMatchers("/chatbot/**").permitAll()
5763

5864
// 회원 or 인증된 사용자만 가능
59-
.requestMatchers("/api/admin/**").hasRole("ADMIN")
60-
// .requestMatchers("/api/cocktail/detail~~").authenticated()
65+
.requestMatchers("/admin/**").hasRole("ADMIN")
6166

6267
//그 외에는 인증해야함
6368
.anyRequest().authenticated()
@@ -95,9 +100,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
95100
public CorsConfigurationSource corsConfigurationSource() {
96101
CorsConfiguration configuration = new CorsConfiguration();
97102
configuration.setAllowedOrigins(Arrays.asList(
98-
"http://localhost:3000",
99-
"http://localhost:8080"
100-
//나중에 운영환경 추가
103+
frontUrl,
104+
backUrl
101105
));
102106
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
103107
configuration.setAllowedHeaders(Arrays.asList("*"));

src/main/resources/application-prod.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ spring:
1919
driver-class-name: com.mysql.cj.jdbc.Driver
2020
jpa:
2121
hibernate:
22-
ddl-auto: update
22+
ddl-auto: create-drop
2323
properties:
2424
hibernate:
2525
show_sql: false

0 commit comments

Comments
 (0)