Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
16e1f21
[CHORE] 임시 커밋
paragon0107 Dec 2, 2024
7c6eda0
[FEAT] pr반영
paragon0107 Dec 16, 2024
b9231b5
Merge branch 'develop' of https://github.com/Team-Tiki/TIKI_SERVER in…
paragon0107 Dec 18, 2024
bd0dbb1
[FEAT] 팀원 불러오기 컨트롤러 구현
paragon0107 Dec 18, 2024
9e1956b
[FEAT] 팀원 불러오기 성공메세지 구현
paragon0107 Dec 18, 2024
8ad3ac3
[FEAT] 팀원 불러오기 dto 구현
paragon0107 Dec 18, 2024
d7ab446
[FEAT] 팀원 불러오기 서비스단 구현
paragon0107 Dec 18, 2024
2c328ed
[FEAT] 팀원 불러오기 어댑터단 구현
paragon0107 Dec 18, 2024
f9f7921
[FEAT] 팀원 불러오기 레포지토리 구현
paragon0107 Dec 18, 2024
16c0e5e
[FEAT] 팀원 불러오기 프로젝션 구현
paragon0107 Dec 18, 2024
0637d6f
[CHORE] 기존 패키지 경로 재설정
paragon0107 Dec 22, 2024
c5f2858
[CHORE] 기존 패키지 경로 재설정
paragon0107 Dec 22, 2024
2a1a208
[FEAT] 팀 초대 도메인 기초 셋팅
paragon0107 Dec 22, 2024
1294a16
Merge branch 'develop' of https://github.com/Team-Tiki/TIKI_SERVER in…
paragon0107 Dec 22, 2024
252f638
[FEAT] 임시 작업 반영
paragon0107 Dec 26, 2024
32dd292
[CHORE] 패키지 명 변경
paragon0107 Dec 26, 2024
fe848d0
[CHORE] 패키지 명 변경
paragon0107 Dec 26, 2024
62637b7
[CHORE] 팀 초대 로직 추가
paragon0107 Dec 26, 2024
4f038c2
[CHORE] 이메일 센더 상수 수정
paragon0107 Dec 31, 2024
c31a2b6
[FEAT] 팀원 초대 컨트롤러 부분 구현
paragon0107 Dec 31, 2024
8653046
[FEAT] 팀원 초대 서비스 부분 구현
paragon0107 Dec 31, 2024
35ffc00
[FEAT] 메일 템플릿 추가
paragon0107 Dec 31, 2024
1d3aea2
[CHORE] 중복 DTO 삭제
paragon0107 Dec 31, 2024
154612c
[FEAT] MailSender 팀원 초대 부분 구현
paragon0107 Dec 31, 2024
5a6c325
[FEAT] TeamIvitation 도메인 일분 구현
paragon0107 Dec 31, 2024
be115fd
[FEAT] 스케줄러 설정 어노테이션 추가
paragon0107 Jan 2, 2025
88d6995
[FEAT] TeamInvitation 레이어 구현
paragon0107 Jan 2, 2025
0b58688
[FEAT] TeamInvitation 어댑터 부분 구현
paragon0107 Jan 2, 2025
d2646c1
[FEAT] TeamInvitation 메세지 구현
paragon0107 Jan 2, 2025
154407a
[FEAT] TeamInvitation 엔티티 구현
paragon0107 Jan 2, 2025
02c36cb
[FEAT] TeamInvitation DTO 구현
paragon0107 Jan 2, 2025
7bd713f
[FEAT] 스케줄러 부분 구현
paragon0107 Jan 2, 2025
0907a10
[CHORE] PR반영
paragon0107 Jan 2, 2025
2899070
[CHORE] 사용처 없는 의존성 삭제
paragon0107 Jan 2, 2025
cf24c77
[CHORE] ResponseStatuse 어노테이션 적용
paragon0107 Jan 2, 2025
6e8a85b
[CHORE] ResponseStatuse 어노테이션 적용
paragon0107 Jan 2, 2025
f33f2ba
[FEAT] 초대 로직에 멤버 존재하는지 확인하는 메서드 추가
paragon0107 Jan 2, 2025
cde57af
[FEAT] 초대 로직에 멤버 존재하는지 확인하는 메서드 추가
paragon0107 Jan 2, 2025
4478a06
[CHORE] 컨벤션 적용
paragon0107 Jan 2, 2025
bcd118f
[CHORE] 팀원 존재시 에러메시지 추가
paragon0107 Jan 2, 2025
8eb7aa3
[FEAT] 이메일 엔티티 비교 메서드 추가
paragon0107 Jan 2, 2025
f358e6c
[FEAT] 파라미터 이름 수정
paragon0107 Jan 2, 2025
2e9272b
[FEAT] 파라미터 이름 수정
paragon0107 Jan 2, 2025
dbb89f0
[FEAT] TeamInvitation 에러 핸들러에 추가
paragon0107 Jan 2, 2025
bf1fd67
[CHORE] 초대 템플릿 수정
paragon0107 Jan 2, 2025
58e7ff4
[FEAT] 이메일 반환 메서드 추가
paragon0107 Jan 2, 2025
d59451e
[CHORE] 초대 수락 엔드포인트 수정
paragon0107 Jan 2, 2025
2c62295
[CHORE] 파라미터 이름 수정
paragon0107 Jan 2, 2025
4a13719
[CHORE] 반환 형식 수정
paragon0107 Jan 2, 2025
d634272
[CHORE] TeamInvitationException 문구 수정
paragon0107 Jan 2, 2025
6dcbfb2
[CHORE] 누락된 기능 추가
paragon0107 Jan 2, 2025
ca437d9
[CHORE] 리뷰 반영
paragon0107 Jan 4, 2025
b07d9b9
Merge branch 'develop' of https://github.com/Team-Tiki/TIKI_SERVER in…
paragon0107 Jan 4, 2025
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
8 changes: 5 additions & 3 deletions src/main/java/com/tiki/server/TikiServerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class TikiServerApplication {

public static void main(String[] args) {
SpringApplication.run(TikiServerApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(TikiServerApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class SecurityConfig {
"/api/v1/auth/reissue",
"/api/v1/members/password",
"/api/v1/members",
"/api/v1/email-verification/**",
"/api/v1/email/verification/**",
"/actuator/health"
};

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/tiki/server/auth/jwt/JwtProvider.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.tiki.server.auth.jwt;

import com.tiki.server.common.Constants;
import com.tiki.server.common.constants.Constants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.servlet.http.HttpServletRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.tiki.server.auth.token.adapter.TokenFinder;
import com.tiki.server.auth.token.adapter.TokenSaver;
import com.tiki.server.auth.token.entity.Token;
import com.tiki.server.common.entity.Email;
import com.tiki.server.email.Email;
import com.tiki.server.member.adapter.MemberFinder;
import com.tiki.server.member.entity.Member;
import com.tiki.server.member.exception.MemberException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.tiki.server.common;
package com.tiki.server.common.constants;

public class Constants {
public static final String AUTHORIZATION = "Authorization";
Expand Down
190 changes: 102 additions & 88 deletions src/main/java/com/tiki/server/common/handler/ErrorHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import com.tiki.server.auth.exception.AuthException;
import com.tiki.server.common.dto.ErrorCodeResponse;
import com.tiki.server.emailverification.exception.EmailVerificationException;
import com.tiki.server.email.emailsender.exception.EmailSenderException;
import com.tiki.server.email.teaminvitation.exception.TeamInvitationException;
import com.tiki.server.email.verification.exception.EmailVerificationException;
import com.tiki.server.folder.exception.FolderException;
import com.tiki.server.note.exception.NoteException;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
Expand All @@ -25,95 +26,108 @@
import lombok.val;

import static com.tiki.server.auth.message.ErrorCode.UNCAUGHT_SERVER_EXCEPTION;
import static com.tiki.server.common.Constants.WRONG_INPUT;
import static com.tiki.server.common.constants.Constants.WRONG_INPUT;

@Slf4j
@RestControllerAdvice
public class ErrorHandler {

@ExceptionHandler(MemberException.class)
public ResponseEntity<BaseResponse> memberException(final MemberException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(TeamException.class)
public ResponseEntity<BaseResponse> teamException(final TeamException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(MemberTeamManagerException.class)
public ResponseEntity<BaseResponse> memberTeamManagerException(final MemberTeamManagerException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(TimeBlockException.class)
public ResponseEntity<BaseResponse> timeBlockException(final TimeBlockException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(DocumentException.class)
public ResponseEntity<BaseResponse> documentException(final DocumentException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(NoteException.class)
public ResponseEntity<BaseResponse> noteException(final NoteException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(ExternalException.class)
public ResponseEntity<BaseResponse> externalException(final ExternalException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(EmailVerificationException.class)
public ResponseEntity<BaseResponse> mailException(final EmailVerificationException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(FolderException.class)
public ResponseEntity<BaseResponse> folderException(final FolderException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(AuthException.class)
public ResponseEntity<BaseResponse> authException(final AuthException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(
ErrorCodeResponse.of(errorCode.getCode(), errorCode.getMessage()));
}

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<BaseResponse> httpMessageNotReadableException(
final HttpMessageNotReadableException exception) {
log.error(exception.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
ErrorResponse.of(WRONG_INPUT));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<BaseResponse> exception(final Exception exception) {
log.error(exception.getMessage());
val errorCode = UNCAUGHT_SERVER_EXCEPTION;
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}
@ExceptionHandler(MemberException.class)
public ResponseEntity<BaseResponse> memberException(MemberException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(TeamException.class)
public ResponseEntity<BaseResponse> teamException(TeamException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(MemberTeamManagerException.class)
public ResponseEntity<BaseResponse> memberTeamManagerException(MemberTeamManagerException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(TimeBlockException.class)
public ResponseEntity<BaseResponse> timeBlockException(TimeBlockException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(DocumentException.class)
public ResponseEntity<BaseResponse> documentException(DocumentException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(NoteException.class)
public ResponseEntity<BaseResponse> noteException(NoteException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(ExternalException.class)
public ResponseEntity<BaseResponse> externalException(ExternalException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(EmailVerificationException.class)
public ResponseEntity<BaseResponse> mailVerificationException(EmailVerificationException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(EmailSenderException.class)
public ResponseEntity<BaseResponse> mailSenderException(EmailSenderException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(TeamInvitationException.class)
public ResponseEntity<BaseResponse> teamInvitationException(TeamInvitationException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(FolderException.class)
public ResponseEntity<BaseResponse> folderException(FolderException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}

@ExceptionHandler(AuthException.class)
public ResponseEntity<BaseResponse> authException(AuthException exception) {
log.error(exception.getMessage());
val errorCode = exception.getErrorCode();
return ResponseEntity.status(errorCode.getHttpStatus()).body(
ErrorCodeResponse.of(errorCode.getCode(), errorCode.getMessage()));
}

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<BaseResponse> httpMessageNotReadableException(HttpMessageNotReadableException exception) {
log.error(exception.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
ErrorResponse.of(WRONG_INPUT));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<BaseResponse> exception(Exception exception) {
log.error(exception.getMessage());
val errorCode = UNCAUGHT_SERVER_EXCEPTION;
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.of(errorCode.getMessage()));
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/tiki/server/email/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.tiki.server.email;

public class Constants {
public static final String MAIL_FORMAT_EDU = ".edu";
public static final String MAIL_FORMAT_AC_KR = ".ac.kr";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.tiki.server.common.entity;
package com.tiki.server.email;

import com.tiki.server.member.exception.MemberException;

Expand All @@ -7,8 +7,8 @@
import lombok.*;
import org.apache.commons.validator.routines.EmailValidator;

import static com.tiki.server.emailverification.constants.EmailConstants.MAIL_FORMAT_AC_KR;
import static com.tiki.server.emailverification.constants.EmailConstants.MAIL_FORMAT_EDU;
import static com.tiki.server.email.Constants.MAIL_FORMAT_AC_KR;
import static com.tiki.server.email.Constants.MAIL_FORMAT_EDU;
import static com.tiki.server.member.message.ErrorCode.INVALID_EMAIL;

@Getter
Expand All @@ -31,4 +31,12 @@ private static void checkMailFormat(final String email) {
throw new MemberException(INVALID_EMAIL);
}
}

@Override
public boolean equals(Object target) {
if (this == target) return true;
if (target == null || getClass() != target.getClass()) return false;
Email targetEmail = (Email) target;
return email.equals(targetEmail.email);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.tiki.server.emailverification.config;
package com.tiki.server.email.emailsender.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
Expand All @@ -8,7 +8,7 @@

import java.util.Properties;

import static com.tiki.server.emailverification.constants.EmailConstants.TIKI_EMAIL;
import static com.tiki.server.email.emailsender.constants.Constants.TIKI_EMAIL;

@Configuration
public class EmailConfig {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tiki.server.email.emailsender.constants;

public class Constants {

/* 공통 상수 */
public static final String TIKI_EMAIL = "[email protected]";
public static final String IMG_PATH = "images/mail_logo.png";

/* 이메일 인증 관련 상수 */
public static final String MAIL_VERIFICATION_CODE = "[Ti.Ki] 회원가입: 이메일 인증번호 안내";
public static final String MAIL_PASSWORD_CHANGING_CODE = "[Ti.Ki] 비밀번호 재설정: 이메일 인증번호 안내";
public static final String MAIL_INVITE_TEAM_MEMBER = "[Ti.Ki] 워크스페이스 초대 안내";
public static final String VERIFICATION_TEMPLATE_NAME = "signup";
public static final String CHANGE_PASSWORD_TEMPLATE_NAME = "changePassword";
public static final String INVITE_TEAM_MEMBER_TEMPLATE_NAME = "invitation";
public static final String PAGE_LOGO_IMAGE_VAR = "image";

/* 이메일 초대 관련 상수 */
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.tiki.server.email.emailsender.controller;

import com.tiki.server.common.dto.SuccessResponse;
import com.tiki.server.email.emailsender.controller.docs.EmailSenderControllerDocs;
import com.tiki.server.email.emailsender.controller.dto.request.EmailRequest;
import com.tiki.server.email.emailsender.message.SuccessMessage;
import com.tiki.server.email.emailsender.service.EmailSenderService;
import com.tiki.server.email.emailsender.service.dto.EmailServiceRequest;
import com.tiki.server.email.emailsender.service.dto.TeamInvitationCreateServiceRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/email")
public class EmailSenderController implements EmailSenderControllerDocs {

private final EmailSenderService emailSenderService;

@ResponseStatus(HttpStatus.OK)
@PostMapping("/verification/signup")
public SuccessResponse<?> sendSignUpMail(@RequestBody final EmailRequest mailRequest) {
emailSenderService.sendSignUp(EmailServiceRequest.from(mailRequest.email()));
return SuccessResponse.success(SuccessMessage.SUCCESS_SEND_EMAIL.getMessage());
}

@ResponseStatus(HttpStatus.OK)
@PostMapping("/verification/password")
public SuccessResponse<?> sendChangingPasswordMail(@RequestBody final EmailRequest mailRequest) {
emailSenderService.sendPasswordChanging(EmailServiceRequest.from(mailRequest.email()));
return SuccessResponse.success(SuccessMessage.SUCCESS_SEND_EMAIL.getMessage());
}

@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/invitation/team/{teamId}")
public SuccessResponse<?> sendInvitationMail(
final Principal principal,
@PathVariable final long teamId,
@RequestBody final EmailRequest targetEmailRequest
) {
long memberId = Long.parseLong(principal.getName());
emailSenderService.createTeamInvitation(
TeamInvitationCreateServiceRequest.of(targetEmailRequest.email(), teamId, memberId));
return SuccessResponse.success(SuccessMessage.SUCCESS_SEND_EMAIL.getMessage());
}
}
Loading
Loading