Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dev_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ jobs:
utcOffset: "+09:00"
- name: Print Current Time
run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}"
shell: bash
shell: bash
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ dependencies {

// Jwt
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'

// CORS 설정
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

// S3 설정
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.649'

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package EatPic.spring.domain.notification.service;


import EatPic.spring.domain.card.entity.Card;
import EatPic.spring.domain.card.repository.CardRepository;
import EatPic.spring.domain.notification.converter.NotificationConverter;
Expand All @@ -9,9 +8,9 @@
import EatPic.spring.domain.notification.entity.NotificationType;
import EatPic.spring.domain.notification.repository.NotificationRepository;
import EatPic.spring.domain.user.entity.User;
import EatPic.spring.domain.user.exception.UserErrorCode;
import EatPic.spring.domain.user.repository.UserFollowRepository;
import EatPic.spring.domain.user.repository.UserRepository;
import EatPic.spring.global.common.code.status.ErrorStatus;
import EatPic.spring.global.common.exception.handler.ExceptionHandler;
import java.time.LocalDateTime;
import java.util.List;
Expand Down Expand Up @@ -65,15 +64,15 @@ private RecentNotificationResponse convertToDto(Notification notification, User

public void checkNotifications(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new ExceptionHandler(UserErrorCode.USER_NOT_FOUND));
.orElseThrow(() -> new ExceptionHandler(ErrorStatus.USER_NOT_FOUND));

user.updateLastNotificationCheckAt(LocalDateTime.now());
userRepository.save(user);
}

public boolean isUnreadNotification(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new ExceptionHandler(UserErrorCode.USER_NOT_FOUND));
.orElseThrow(() -> new ExceptionHandler(ErrorStatus.USER_NOT_FOUND));

LocalDateTime lastChecked = user.getLastNotificationCheckAt();
Notification latest = notificationRepository.findTopByReceiverOrderByCreatedAtDesc(user);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//// 계정 권환 확인용 Controller
//
//package EatPic.spring.domain.user.controller;
//
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import org.springframework.http.ResponseEntity;
//import org.springframework.security.access.prepost.PreAuthorize;
//import org.springframework.security.core.Authentication;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import java.util.Map;
//import java.util.stream.Collectors;
//
//@Tag(name = "Role Test")
//@RestController
//@RequestMapping("/api")
//public class RoleTestController {
//
// @Operation(summary = "ADMIN 권한 확인용")
// @PreAuthorize("hasRole('ADMIN')") // ADMIN만
// @GetMapping("/admin")
// public ResponseEntity<?> admin(Authentication auth) {
// return ResponseEntity.ok(Map.of(
// "who", auth.getName(),
// "authorities", auth.getAuthorities().stream().map(Object::toString).collect(Collectors.toList()),
// "message", "admin ok"
// ));
// }
//
// @Operation(summary = "USER 권한 확인용")
// @PreAuthorize("hasAnyRole('USER','ADMIN')") // USER 또는 ADMIN
// @GetMapping("/user")
// public ResponseEntity<?> user(Authentication auth) {
// return ResponseEntity.ok(Map.of(
// "who", auth.getName(),
// "authorities", auth.getAuthorities().stream().map(Object::toString).collect(Collectors.toList()),
// "message", "user ok"
// ));
// }
//
// @Operation(summary = "현재 토큰 정보 확인")
// @GetMapping("/me")
// public ResponseEntity<?> me(Authentication auth) {
// // 인증 안 되었으면 null일 수 있음
// if (auth == null) return ResponseEntity.status(401).body(Map.of("message", "unauthorized"));
// return ResponseEntity.ok(Map.of(
// "who", auth.getName(),
// "authorities", auth.getAuthorities().stream().map(Object::toString).collect(Collectors.toList())
// ));
// }
//}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package EatPic.spring.domain.user.controller;

import EatPic.spring.domain.user.entity.User;
import EatPic.spring.domain.user.dto.*;
import EatPic.spring.domain.user.dto.request.LoginRequestDTO;
import EatPic.spring.domain.user.dto.request.SignupRequestDTO;
import EatPic.spring.domain.user.dto.response.LoginResponseDTO;
import EatPic.spring.domain.user.dto.response.SignupResponseDTO;
import EatPic.spring.domain.user.entity.User;
import EatPic.spring.domain.user.service.UserBadgeService;
import EatPic.spring.domain.user.service.UserService;
import EatPic.spring.global.common.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -14,32 +20,29 @@
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class UserController {
public class UserController{

private final UserService userService;
private final UserBadgeService userBadgeService;

// 회원 가입 요청
@PostMapping("/signup")
@Operation(summary = "이메일 회원가입 요청")
public ResponseEntity<SignupResponseDTO> signup(@Valid @RequestBody SignupRequestDTO request) {
return ResponseEntity.ok(userService.signup(request));
}

User savedUser = userService.signup(request);

userBadgeService.initializeUserBadges(savedUser);

SignupResponseDTO response = SignupResponseDTO.builder()
.role(savedUser.getRole())
.userId(savedUser.getId())
.email(savedUser.getEmail())
.nameId(savedUser.getNameId())
.nickname(savedUser.getNickname())
.marketingAgreed(savedUser.getMarketingAgreed())
.notificationAgreed(savedUser.getNotificationAgreed())
.message("회원가입이 완료되었습니다.")
.build();

return ResponseEntity.ok(response);
@PostMapping("/login/email")
@Operation(summary = "이메일 로그인 요청")
public ApiResponse<LoginResponseDTO> login(@RequestBody @Valid LoginRequestDTO request) {
return ApiResponse.onSuccess(userService.loginUser(request));
}

@GetMapping("/users")
@Operation(summary = "유저 내 정보 조회 - 인증 필요",
security = { @SecurityRequirement(name = "JWT TOKEN") }
)
public ApiResponse<UserInfoDTO> getMyInfo(HttpServletRequest request) {
return ApiResponse.onSuccess(userService.getUserInfo(request));
}
}

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package EatPic.spring.domain.user.converter;

import EatPic.spring.domain.card.dto.response.SearchResponseDTO;
import EatPic.spring.domain.card.entity.Card;
import EatPic.spring.domain.reaction.dto.ReactionResponseDTO;
import EatPic.spring.domain.reaction.entity.ReactionType;
import EatPic.spring.domain.user.dto.request.SignupRequestDTO;
import EatPic.spring.domain.user.dto.UserInfoDTO;
import EatPic.spring.domain.user.dto.response.LoginResponseDTO;
import EatPic.spring.domain.user.dto.response.UserResponseDTO;
import EatPic.spring.domain.user.entity.User;
import EatPic.spring.domain.user.mapping.UserBlock;
Expand All @@ -13,6 +13,24 @@

public class UserConverter {

public static LoginResponseDTO toLoginResultDTO(User user, String accessToken, String refreshToken) {
return LoginResponseDTO.builder()
.role(user.getRole())
.userId(user.getId())
.email(user.getEmail())
.accessToken(accessToken)
.refreshToken(refreshToken)
.build();
}

public static UserInfoDTO toUserInfoDTO(User user){
return UserInfoDTO.builder()
.email(user.getEmail())
.nameId(user.getNameId())
.nickName(user.getNickname())
.build();
}

public static UserResponseDTO.UserIconListResponseDto toUserIconListResponseDto(Page<UserFollow> followingPage){
return UserResponseDTO.UserIconListResponseDto.builder()
.total((int)followingPage.getTotalElements())
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/EatPic/spring/domain/user/dto/UserInfoDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package EatPic.spring.domain.user.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserInfoDTO {
String email;
String nameId;
String nickName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package EatPic.spring.domain.user.dto.request;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class LoginRequestDTO {
@NotBlank(message = "이메일을 임력해 주세요.")
@Email(message = "이메일 형식이 올바르지 않습니다.")
private String email;

@NotBlank(message = "비밀번호를 입력해 주세요.")
private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package EatPic.spring.domain.user.dto.response;

import EatPic.spring.domain.user.entity.Role;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class LoginResponseDTO {
private Role role;
private Long userId; // DB에 저장된 유저 ID
private String email; // 회원가입 시 입력한 이메일
private String accessToken;
private String refreshToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ public class SignupResponseDTO {
private Boolean notificationAgreed; // 알림 수신 동의 여부
private String message; // 예: "회원가입이 완료되었습니다."
}

10 changes: 9 additions & 1 deletion src/main/java/EatPic/spring/domain/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import lombok.*;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Entity
Expand Down Expand Up @@ -48,9 +51,13 @@ public class User extends BaseEntity {
@Column(name = "social_type", nullable = true)
private SocialType socialType;

@Column(name = "refresh_token", length = 255)
@Column(name = "refresh_token", length = 512)
private String refreshToken;

public void updateRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

@Column(name = "profile_image_url", length = 500)
private String profileImageUrl;

Expand Down Expand Up @@ -82,3 +89,4 @@ public void updateLastNotificationCheckAt(LocalDateTime time) {
this.lastNotificationCheckAt = time;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@


public interface UserRepository extends JpaRepository<User,Long> {
boolean existsByEmail(String email);
boolean existsByEmail(String email); // 회원 가입 시, 이메일 중복 검사

boolean existsByNickname(String nickname);

boolean existsByNameId(String nameId);

Optional<User> findByEmail(String email);
Optional<User> findByEmail(String email); // 로그인 시, 이메일로 유저 찾기

User findUserById(Long id);

Expand Down
Loading
Loading