diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index f5d3350..e1be54c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -81,6 +81,15 @@ jobs: echo "${{ secrets.YML_OAUTH }}" > ./application-oauth.yml shell: bash + # 환경별 yml 파일 생성(5) - bucket + - name: make application-bucket.yml + if: contains(github.ref, 'develop') + run: | + cd ./src/main/resources + touch ./application-bucket.yml + echo "${{ secrets.YML_BUCKET }}" > ./application-bucket.yml + shell: bash + # gradle build - name: Build with Gradle run: ./gradlew build -x test diff --git a/build.gradle b/build.gradle index e387028..dffee5b 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,9 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + // S3 Bucket + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.0' } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java index 4d61d2d..829c1f5 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/controller/UserController.java @@ -1,37 +1,66 @@ package com.leets.xcellentbe.domain.user.controller; +import java.io.IOException; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.leets.xcellentbe.domain.user.domain.User; import com.leets.xcellentbe.domain.user.dto.UserLoginRequestDto; +import com.leets.xcellentbe.domain.user.dto.UserProfileRequestDto; +import com.leets.xcellentbe.domain.user.dto.UserProfileResponseDto; import com.leets.xcellentbe.domain.user.dto.UserSignUpRequestDto; +import com.leets.xcellentbe.domain.user.service.S3UploadService; import com.leets.xcellentbe.domain.user.service.UserService; +import com.leets.xcellentbe.global.auth.email.EmailRequestDto; import com.leets.xcellentbe.global.response.GlobalResponseDto; import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @RestController -@RequestMapping("/api/user") +@RequestMapping("/api/profile") @RequiredArgsConstructor public class UserController { - // private final UserService userService; - // - // @PostMapping("/auth/register") - // @Operation(summary = "회원가입", description = "회원가입을 합니다.") - // public ResponseEntity> register(@RequestBody UserSignUpRequestDto userSignUpRequestDto) { - // return ResponseEntity.status(HttpStatus.CREATED) - // .body(GlobalResponseDto.success(userService.register(userSignUpRequestDto), HttpStatus.CREATED.value())); - // } - // - // @Operation(summary = "로그인", description = "사용자의 이메일과 비밀번호로 로그인합니다.") - // @PostMapping("/auth/login") - // public String login(@RequestBody UserLoginRequestDto userLoginRequestDto) { - // // 로그인 로직 처리 - // return "로그인 성공"; - // } -} + private final UserService userService; + + @GetMapping("/info") + @Operation(summary = "프로필 조회", description = "사용자의 프로필 내용을 조회합니다.") + public ResponseEntity> getProfile(HttpServletRequest request) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.getProfile(request))); + } + + @PatchMapping("/info") + @Operation(summary = "프로필 수정", description = "사용자의 프로필을 수정합니다.") + public ResponseEntity> updateProfile(@RequestBody UserProfileRequestDto userProfileRequestDto, HttpServletRequest request) { + userService.updateProfile(request,userProfileRequestDto); + return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success()); + } + + @PatchMapping("/profile-image") + @Operation(summary = "프로필 이미지 수정", description = "사용자의 프로필 이미지를 수정합니다.") + public ResponseEntity> updateProfileImage(@RequestParam("file") MultipartFile file, HttpServletRequest request) { + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.updateProfileImage(file, request))); + + } + + @PatchMapping("/background-image") + @Operation(summary = "배경 이미지 수정", description = "사용자의 배경 이미지를 수정합니다.") + public ResponseEntity> updateBackgroundImage (@RequestParam("file") MultipartFile file, HttpServletRequest request){ + return ResponseEntity.status(HttpStatus.OK) + .body(GlobalResponseDto.success(userService.updateBackgroundProfileImage(file, request))); + } + } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index 89c7887..bf5669f 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -126,12 +126,24 @@ public static User create(String customId, String email, String userName, String .build(); } - public static User socialCreate(String email, String socialEmail) { - return User.builder() - .email(email) - .userRole(Role.GUEST) - .socialEmail(socialEmail) - .build(); + public void updateProfile(String userName, String phoneNumber, String customId, int userBirthYear, int userBirthDay, int userBirthMonth, String description, String websiteUrl, String location) { + this.userName = userName; + this.customId = customId; + this.description = description; + this.websiteUrl = websiteUrl; + this.location = location; + this.phoneNumber = phoneNumber; + this.userBirthYear = userBirthYear; + this.userBirthDay = userBirthDay; + this.userBirthMonth = userBirthMonth; + } + + public void updateProfileImage(String updateProfileImageUrl) { + this.profileImageUrl = updateProfileImageUrl; + } + + public void updateBackgroundImage(String updateBackgroundImageUrl) { + this.backgroundProfileImageUrl = updateBackgroundImageUrl; } public void updateRefreshToken(String updateRefreshToken) { diff --git a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java new file mode 100644 index 0000000..536209a --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileRequestDto.java @@ -0,0 +1,22 @@ +package com.leets.xcellentbe.domain.user.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter + +public class UserProfileRequestDto { + private String customId; + private String userName; + private String profileImageUrl; + private String backgroundProfileImageUrl; + private String phoneNumber; + private String description; + private String websiteUrl; + private String location; + private int userBirthYear; + private int userBirthMonth; + private int userBirthDay; +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java new file mode 100644 index 0000000..ca67739 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/user/dto/UserProfileResponseDto.java @@ -0,0 +1,59 @@ +package com.leets.xcellentbe.domain.user.dto; + +import com.leets.xcellentbe.domain.user.domain.User; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class UserProfileResponseDto { + private String email; + private String customId; + private String userName; + private String profileImageUrl; + private String backgroundProfileImageUrl; + private String phoneNumber; + private String description; + private String websiteUrl; + private String location; + private int userBirthYear; + private int userBirthMonth; + private int userBirthDay; + + @Builder + private UserProfileResponseDto(String email, String customId, String userName, String profileImageUrl, + String backgroundProfileImageUrl, String phoneNumber, String description, String websiteUrl, String location, + int userBirthYear, int userBirthMonth, int userBirthDay) { + this.email = email; + this.customId = customId; + this.userName = userName; + this.profileImageUrl = profileImageUrl; + this.backgroundProfileImageUrl = backgroundProfileImageUrl; + this.phoneNumber = phoneNumber; + this.description = description; + this.websiteUrl = websiteUrl; + this.location = location; + this.userBirthYear = userBirthYear; + this.userBirthMonth = userBirthMonth; + this.userBirthDay = userBirthDay; + } + + public static UserProfileResponseDto from(User user) { + return UserProfileResponseDto.builder() + .email(user.getEmail()) + .customId(user.getCustomId()) + .userName(user.getUserName()) + .profileImageUrl(user.getProfileImageUrl()) + .backgroundProfileImageUrl(user.getBackgroundProfileImageUrl()) + .phoneNumber(user.getPhoneNumber()) + .description(user.getDescription()) + .websiteUrl(user.getWebsiteUrl()) + .location(user.getLocation()) + .userBirthYear(user.getUserBirthYear()) + .userBirthMonth(user.getUserBirthMonth()) + .userBirthDay(user.getUserBirthDay()) + .build(); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/exception/InvalidFileFormat.java b/src/main/java/com/leets/xcellentbe/domain/user/exception/InvalidFileFormat.java new file mode 100644 index 0000000..911d157 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/user/exception/InvalidFileFormat.java @@ -0,0 +1,10 @@ +package com.leets.xcellentbe.domain.user.exception; + +import com.leets.xcellentbe.global.error.ErrorCode; +import com.leets.xcellentbe.global.error.exception.CommonException; + +public class InvalidFileFormat extends CommonException { + public InvalidFileFormat() { + super(ErrorCode.INVALID_FILE_FORMAT); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java new file mode 100644 index 0000000..66c38c9 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/S3UploadService.java @@ -0,0 +1,87 @@ +package com.leets.xcellentbe.domain.user.service; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.leets.xcellentbe.domain.user.exception.InvalidFileFormat; +import com.leets.xcellentbe.global.error.exception.custom.InternalServerErrorException; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +@Service +public class S3UploadService { + private final AmazonS3Client amazonS3Client; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + // MultipartFile을 전달받아 File로 전환한 후 S3에 업로드 + public String upload(MultipartFile multipartFile, String dirName) { // dirName의 디렉토리가 S3 Bucket 내부에 생성됨 + String fileName = multipartFile.getOriginalFilename(); + if ((fileName.endsWith(".png") || fileName.endsWith(".jpg"))) { + throw new InvalidFileFormat(); + } + + try { + File uploadFile = convert(multipartFile). + orElseThrow(() -> new RuntimeException()); + return upload(uploadFile, dirName); + } catch(IOException e) { + throw new InternalServerErrorException(); + } + + } + + private String upload(File uploadFile, String dirName) { + String fileName = dirName + "/" + uploadFile.getName(); + String uploadImageUrl = putS3(uploadFile, fileName); + + removeNewFile(uploadFile); // convert()함수로 인해서 로컬에 생성된 File 삭제 (MultipartFile -> File 전환 하며 로컬에 파일 생성됨) + + return uploadImageUrl; // 업로드된 파일의 S3 URL 주소 반환 + } + + private String putS3(File uploadFile, String fileName) { + amazonS3Client.putObject( + new PutObjectRequest(bucket, fileName, uploadFile) + .withCannedAcl(CannedAccessControlList.PublicRead) // PublicRead 권한으로 업로드 됨 + ); + return amazonS3Client.getUrl(bucket, fileName).toString(); + } + + private void removeNewFile(File targetFile) { + if(targetFile.delete()) { + log.info("파일이 삭제되었습니다."); + }else { + log.info("파일이 삭제되지 못했습니다."); + } + } + + private Optional convert(MultipartFile file) throws IOException { + File convertFile = new File(file.getOriginalFilename()); // 업로드한 파일의 이름 + if(convertFile.createNewFile()) { + try (FileOutputStream fos = new FileOutputStream(convertFile)) { + fos.write(file.getBytes()); + } + return Optional.of(convertFile); + } + return Optional.empty(); + } + + public void removeFile(String fileUrl, String filePath) { + String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1); + amazonS3Client.deleteObject(bucket, filePath + fileName); + } +} diff --git a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java index 91ab321..2d08c3e 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/service/UserService.java @@ -1,14 +1,25 @@ package com.leets.xcellentbe.domain.user.service; +import java.util.Optional; + +import org.hibernate.engine.transaction.jta.platform.internal.SunOneJtaPlatform; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.dto.UserProfileRequestDto; import com.leets.xcellentbe.domain.user.exception.UserAlreadyExistsException; import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; import com.leets.xcellentbe.domain.user.dto.UserSignUpRequestDto; +import com.leets.xcellentbe.domain.user.exception.UserNotFoundException; +import com.leets.xcellentbe.global.auth.jwt.JwtService; + +import jakarta.servlet.http.HttpServletRequest; + +import com.leets.xcellentbe.domain.user.dto.UserProfileResponseDto; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; @@ -19,7 +30,10 @@ public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; + private final JwtService jwtService; + private final S3UploadService s3UploadService; + // 회원가입 메소드 public String register(UserSignUpRequestDto userSignUpRequestDto) { if (userRepository.findByEmail(userSignUpRequestDto.getEmail()).isPresent()) { @@ -38,4 +52,58 @@ public String register(UserSignUpRequestDto userSignUpRequestDto) { return "회원가입이 완료되었습니다."; } + // 사용자 정보 조회 메소드 + public UserProfileResponseDto getProfile(HttpServletRequest request) { + User user = getUser(request); + return UserProfileResponseDto.from(user); + } + + + // 사용자 정보 수정 메소드 + public void updateProfile(HttpServletRequest request, UserProfileRequestDto userProfileRequestDto) { + User user = getUser(request); + user.updateProfile(userProfileRequestDto.getUserName(), userProfileRequestDto.getPhoneNumber(), userProfileRequestDto.getCustomId(), userProfileRequestDto.getUserBirthYear(), userProfileRequestDto.getUserBirthDay(), userProfileRequestDto.getUserBirthMonth(), userProfileRequestDto.getDescription(), userProfileRequestDto.getWebsiteUrl(), userProfileRequestDto.getLocation()); + } + + // 프로필 이미지 변경 메소드 + public String updateProfileImage(MultipartFile multipartFile, HttpServletRequest request) { + User user = getUser(request); + String priorUrl = user.getProfileImageUrl(); + String url = s3UploadService.upload(multipartFile, "profile-image"); + user.updateProfileImage(url); + if (priorUrl != null) { + s3UploadService.removeFile(priorUrl, "profile-image/"); + } + + return url; + } + + // 배경 이미지 변경 메소드 + public String updateBackgroundProfileImage(MultipartFile multipartFile, HttpServletRequest request) { + User user = getUser(request); + String priorUrl = user.getBackgroundProfileImageUrl(); + String url = s3UploadService.upload(multipartFile, "background-image"); + user.updateBackgroundImage(url); + + if (priorUrl != null) { + s3UploadService.removeFile(priorUrl, "background-image/"); + } + + return url; + } + + //JWT 토큰 해독하여 사용자 정보 반환 메소드 + private User getUser(HttpServletRequest request) { + Optional user = jwtService.extractAccessToken(request) + .filter(jwtService::isTokenValid) + .flatMap(accessToken -> jwtService.extractEmail(accessToken)) + .flatMap(email -> userRepository.findByEmail(email)); + + if (user.isEmpty()) { + throw new UserNotFoundException(); + } + + return user.get(); + } + } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index 104405b..f4f45b5 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -29,7 +29,7 @@ public void makeRandomNumber() { //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다. - public String joinEmail(String email) throws MessagingException { + public String joinEmail(String email) { makeRandomNumber(); String toMail = email; String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목 @@ -42,7 +42,7 @@ public String joinEmail(String email) throws MessagingException { } //이메일을 전송합니다. - public void mailSend(String toMail, String title, String content) throws MessagingException { + public void mailSend(String toMail, String title, String content) { if(redisService.getData(toMail)!=null){ throw new AuthCodeAlreadySentException(); diff --git a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java index 8047a7c..28132cb 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtService.java @@ -114,8 +114,8 @@ public Optional extractRefreshToken(HttpServletRequest request) { */ public Optional extractAccessToken(HttpServletRequest request) { return Optional.ofNullable(request.getHeader(accessHeader)) - .filter(refreshToken -> refreshToken.startsWith(BEARER)) - .map(refreshToken -> refreshToken.replace(BEARER, "")); + .filter(accessToken -> accessToken.startsWith(BEARER)) + .map(accessToken -> accessToken.replace(BEARER, "")); } /** @@ -135,6 +135,7 @@ public Optional extractEmail(String accessToken) { .asString()); } catch (Exception e) { log.error("액세스 토큰이 유효하지 않습니다."); + e.printStackTrace(); return Optional.empty(); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index e569b16..ec75fef 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -41,13 +41,14 @@ public String login(@RequestBody UserLoginRequestDto userLoginRequestDto) { return "로그인 성공"; } + @Operation(summary = "이메일 인증", description = "이메일 인증을 합니다.") @PostMapping("/email/send") - public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) throws - MessagingException { + public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) { emailService.joinEmail(emailRequestDto.getEmail()); return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success()); } + @Operation(summary = "이메일 인증 확인", description = "이메일 인증을 확인합니다.") @PostMapping("/email/check") public ResponseEntity> AuthCheck(@RequestBody EmailCheckDto emailCheckDto) { return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success(emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()))); diff --git a/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java b/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java new file mode 100644 index 0000000..44bb014 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/config/AwsConfig.java @@ -0,0 +1,35 @@ +package com.leets.xcellentbe.global.config; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AwsConfig { + + // S3를 등록한 사람이 전달받은 접속하기 위한 key 값 + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + + // S3를 등록한 사람이 전달받은 접속하기 위한 secret key 값 + @Value("${cloud.aws.credentials.secret-key}") + private String secretKey; + + // S3를 등록한 사람이 S3를 사용할 지역 + @Value("${cloud.aws.region.static}") + private String region; + + // 전달받은 Accesskey 와 SecretKey 로 아마존 서비스 실행 준비 + @Bean + public AmazonS3Client amazonS3Client() { + BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey); + return (AmazonS3Client) AmazonS3ClientBuilder.standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) + .build(); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java index 0074c62..aa94435 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java @@ -73,7 +73,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { authorize -> authorize .requestMatchers("/v3/api-docs", "/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", - "/swagger/**", "/api/auth/register", "/api/auth/login", "/index.html", "/api/auth/**").permitAll() + "/swagger/**", "/index.html", "/api/auth/**").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2.successHandler(oAuthLoginSuccessHandler)); diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java index b0d965f..1b023d3 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java @@ -8,6 +8,7 @@ public enum ErrorCode { INVALID_INPUT_VALUE(400, "INVALID_INPUT_VALUE", "유효하지 않은 입력값입니다."), + INVALID_FILE_FORMAT(400, "INVALID_FILE_FORMAT", "올바르지 않은 파일 형식입니다."), INVALID_TOKEN(401, "INVALID_TOKEN", "유효하지 않은 토큰입니다."), LOGIN_FAIL(401, "LOGIN_FAIL", "로그인에 실패하였습니다."), CHAT_ROOM_FORBIDDEN(403, "CHAT_ROOM_FORBIDDEN","권한이 없는 채팅방입니다."),