Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,18 @@
import lombok.extern.slf4j.Slf4j;
import org.nmfw.foodietree.domain.auth.dto.EmailCodeDto;
import org.nmfw.foodietree.domain.auth.entity.EmailVerification;
import org.nmfw.foodietree.domain.auth.mapper.EmailMapper;
import org.nmfw.foodietree.domain.auth.security.TokenProvider;
import org.nmfw.foodietree.domain.auth.security.TokenProvider.TokenUserInfo;
import org.nmfw.foodietree.domain.auth.security.filter.AuthJwtFilter;
import org.nmfw.foodietree.domain.auth.service.EmailService;
import org.nmfw.foodietree.domain.auth.service.UserService;
import org.nmfw.foodietree.domain.customer.service.CustomerService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;
import java.util.Optional;

@RestController
@RequiredArgsConstructor
Expand All @@ -33,44 +26,20 @@ public class EmailController {

private final EmailService emailService;
private final UserService userService;
private final EmailMapper emailMapper;
private final TokenProvider tokenProvider;

@GetMapping("/send-reset-email")
public String sendVerificationCode(@RequestParam String to, String userType) {
try {
emailService.sendResetVerificationCode(to, userType, "reset");
return "Password reset email sent successfully";
} catch (Exception e) {
return "Failed to send password reset email: " + e.getMessage();
}
}

/*
@GetMapping("/verify-reset-code")
public String verifyResetCode(@RequestParam String email, @RequestParam String code) {
if (emailService.verifyCode(email, code)) {
return "Verification successful";
} else {
return "Verification failed or code expired";
}
@GetMapping("/check")
@CrossOrigin
@ResponseBody
public ResponseEntity<?> check(@RequestParam String email) {
log.info("이메일 중복체크 아이디 : {}", email);
boolean flag = emailService.existsByEmailInCustomerOrStore(email);
log.info("이메일 중복체크 결과 {}", flag);
return ResponseEntity
.ok()
.body(flag);
}

*/

// 인증 코드 전송
@PostMapping("/sendVerificationCode")
public ResponseEntity<?> sendVerificationCode(@RequestBody Map<String, String> request) {
String email = request.get("email");
String purpose = request.get("purpose");
String userType = request.get("userType");
try {
emailService.sendResetVerificationCode(email, purpose, userType);
return ResponseEntity.ok("Verification code sent");
} catch (MessagingException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to send verification code");
}
}

// 인증 리다이렉션 링크 메일 전송
@PostMapping("/sendVerificationLink")
Expand All @@ -97,115 +66,94 @@ public ResponseEntity<?> sendVerificationLink(@RequestBody Map<String, String> r
@PostMapping("/verifyEmail")
public ResponseEntity<?> verifyEmail(@RequestBody Map<String, String> request) {

log.info("Request Data: {}", request);

String token = request.get("token");
String refreshToken = request.get("refreshToken");
log.info("Request Data: {}", request);

log.info("access token 있는지 확인 {}", token);
log.info("refresh token 있는지 확인 {}", refreshToken);
String token = request.get("token");
String refreshToken = request.get("refreshToken");

try {
// access token 유효성 검사
TokenUserInfo accessTokenUserInfo = tokenProvider.validateAndGetTokenInfo(token);
log.info("access token 있는지 확인 {}", token);
log.info("refresh token 있는지 확인 {}", refreshToken);

log.info("Email extracted from token: {}", accessTokenUserInfo.getEmail());
log.info("user Role (type) extracted from token: {}", accessTokenUserInfo.getRole());
log.info("user access expire date : {}", accessTokenUserInfo.getTokenExpireDate().toString());

String email = accessTokenUserInfo.getEmail();
String userType = accessTokenUserInfo.getRole();
try {
// access token 유효성 검사
TokenUserInfo accessTokenUserInfo = tokenProvider.validateAndGetTokenInfo(token);

log.info("Email extracted from token: {}", accessTokenUserInfo.getEmail());
log.info("user Role (type) extracted from token: {}", accessTokenUserInfo.getRole());
log.info("user access expire date : {}", accessTokenUserInfo.getTokenExpireDate().toString());

String email = accessTokenUserInfo.getEmail();
log.info("유효성 검증 후 email : {}", email);
String userType = accessTokenUserInfo.getRole();
log.info("유효성 검증 후 userType : {}", userType);

// 이메일 dto 정보를 데이터베이스에서 조회
Optional<EmailVerification> emailVerificationOpt = emailService.findOneByEmail(email);

if (emailVerificationOpt.isPresent()) {
EmailVerification emailVerification = emailVerificationOpt.get();
EmailCodeDto emailCodeDto = EmailCodeDto.builder()
.email(emailVerification.getEmail())
.expiryDate(emailVerification.getExpiryDate())
.emailVerified(true)
.userType(userType)
.build();

// 이메일 dto 정보를 데이터베이스에서 조회
EmailCodeDto emailCodeDto = emailMapper.findOneByEmail(email);
log.info("EmailCodeDto retrieved from database: {}", emailCodeDto);


// 이메일 정보가 인증 테이블에 있을 경우
if (emailCodeDto != null) {

log.info("이메일 정보 테이블에 해당 이메일 있음 {}", email);
emailCodeDto.setUserType(userType);
emailCodeDto.setEmailVerified(true);

// 이메일 인증이 완료되지 않은 경우 - 실제 회원가입이 되지 않은 경우
if (!emailCodeDto.isEmailVerified()) {
// 이메일 재전송 페이지로 리다이렉션
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("success", false, "message", "Email link is not verified! Please resend verification email."));
}
if (!emailService.existsByEmailInCustomerOrStore(emailCodeDto.getEmail())) {

//실제 회원가입(테이블에 저장)이 되지 않은 경우 false
if (!(userService.findByEmail(emailCodeDto))) {
log.info("( customer, store 테이블에 저장)이 되지 않은 경우 {}", emailCodeDto);

log.info("실제 회원가입(테이블에 저장)이 되지 않은 경우 {}", emailCodeDto);
emailMapper.update(emailCodeDto); // 인증정보 true 업데이트
return userService.saveUserInfo(emailCodeDto);
emailService.updateEmailVerification(emailCodeDto); // 인증정보 true 업데이트

userService.saveUserInfo(emailCodeDto);
} else {
// 실제 회원가입이 되어있는 경우, 로그인 하는데 access token 기간이 종료된 경우
// 만료 기한 access, refresh 업데이트
log.info("email이 실제 회원가입 되어있는 경우 dto {}", emailCodeDto);
log.info("customer, store에 email이 실제 회원가입 되어있는 경우 dto {}", emailCodeDto);
return userService.updateUserInfo(emailCodeDto);
}
}
}
// email table에 인증정보가 없을 경우 즉, access token이 만료되었을경우
// 인증 정보는 상관없이 access token이 만료되었을 경우
} catch (JwtException e) {
log.warn("JWT parsing error: {}", e.getMessage(), e);
}
// 리프레시 토큰의 만료일자를 확인 - 서버에도 리프레시 토큰 저장
TokenUserInfo refreshTokenUserInfo = tokenProvider.validateAndGetRefreshTokenInfo(refreshToken);

// email table에 인증정보가 없을 경우 즉, access token이 만료되었을경우
// 인증 정보는 상관없이 access token이 만료되었을 경우
} catch (Exception e) {
log.info("access token 의 기한이 만료되었거나 위조되었습니다.");
log.info("JWT parsing error: {}", e.getMessage());

try {
// 리프레시 토큰의 만료일자를 확인 - 서버에도 리프레시 토큰 저장
TokenUserInfo refreshTokenUserInfo = tokenProvider.validateAndGetRefreshTokenInfo(refreshToken);

log.info("token provider tokenUserInfo로 리프레시토큰의 만료일자 확인하기 위한 값 : {} ", refreshTokenUserInfo);

String email = refreshTokenUserInfo.getEmail();
String userType = refreshTokenUserInfo.getRole();

LocalDateTime refreshTokenExpiryDate = userService.getRefreshTokenExpiryDate(email, userType);

log.info("리이이이이이이이이프레에에에에에시토오오오크크ㅡ으응으으응으ㅡㄴ!!! 서버 만료일자 {}", refreshTokenExpiryDate);

if (refreshTokenExpiryDate == null || refreshTokenExpiryDate.isBefore(LocalDateTime.now())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("success", false, "message", "Refresh token expired"));
}
log.info("token provider tokenUserInfo로 리프레시토큰의 만료일자 확인하기 위한 값 : {} ", refreshTokenUserInfo);

// 새로운 액세스 토큰 발급
EmailCodeDto emailCodeDto = EmailCodeDto.builder()
.email(email)
.userType(userType)
.build();
String email = refreshTokenUserInfo.getEmail();
String userType = refreshTokenUserInfo.getRole();

// Call updateUserInfo and capture its response
return userService.updateUserInfo(emailCodeDto);
LocalDateTime refreshTokenExpiryDate = userService.getUserRefreshTokenExpiryDate(email, userType);

log.info(" 서버에서 리프레시 토큰 만료일자 {}", refreshTokenExpiryDate);

} catch (Exception ex) {
log.error("Refresh token parsing error: {}", ex.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("success", false, "message", "Invalid refresh token"));
if (refreshTokenExpiryDate == null || refreshTokenExpiryDate.isBefore(LocalDateTime.now())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("success", false, "message", "Refresh token expired"));
}
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of("success", false, "message", "An unexpected error occurred"));
}
}

// 새로운 액세스 토큰 발급
EmailCodeDto emailCodeDto = EmailCodeDto.builder()
.email(email)
.userType(userType)
.build();

/*
@PostMapping("/verifyCode")
public ResponseEntity<?> verifyCode(@RequestBody Map<String, String> request, @RequestParam(required = false) String purpose) {
String email = request.get("email");
String code = request.get("code");
boolean isValid = false;
if (purpose != null && purpose.equals("signup")) {
isValid = emailService.verifyCodeForSignUp(email, code);
} else {
isValid = emailService.verifyCode(email, code);
}
if (isValid) {
return ResponseEntity.ok("success");
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("failure");
return userService.updateUserInfo(emailCodeDto);
}
}

*/


Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.*;
import org.nmfw.foodietree.domain.auth.entity.EmailVerification;

import javax.persistence.Entity;
import java.time.LocalDateTime;
import java.util.Date;

Expand All @@ -14,21 +15,8 @@
@Builder
public class EmailCodeDto{
private String email; //nullable
private String code; //추후 refresh token 도입예정
@Setter
private LocalDateTime expiryDate; // 인증번호 만료기간
@Setter
private boolean emailVerified;
private Boolean emailVerified;
private String userType;


public EmailVerification toEntity() {
return EmailVerification.builder()
.email(this.email)
.code(this.code)
.expiryDate(this.expiryDate)
.emailVerified(this.emailVerified)
.build();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ public class EmailCodeStoreDto {
private String storeId;
private String userType;
@Setter
private Date refreshTokenExpireDate;
}
private LocalDateTime refreshTokenExpireDate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import lombok.*;

import java.util.Date;
import java.time.LocalDateTime;

@Setter
@Getter
Expand All @@ -14,5 +14,5 @@ public class EmailCustomerDto {
private String customerId;
private String userType;
@Setter
private Date refreshTokenExpireDate;
}
private LocalDateTime refreshTokenExpireDate;
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
package org.nmfw.foodietree.domain.auth.entity;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;
import org.nmfw.foodietree.domain.auth.dto.EmailCodeDto;
import org.nmfw.foodietree.domain.customer.entity.Customer;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@EqualsAndHashCode(of = "id")
@Table(name = "tbl_verification_code")
public class EmailVerification {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;

@Column(name = "email", nullable = true, length = 50, unique = true)
private String email;

@Column(name = "code", nullable = true, length = 255)
private String code;
// @Column(name = "code", nullable = true, length = 255)
// private String code;

@Column(name = "expiry_date", nullable = false)
private LocalDateTime expiryDate;

@Column(name = "email_verified", nullable = true)
private boolean emailVerified;
private Boolean emailVerified;

@Column(name = "user_type", nullable = true, length = 50)
private String userType;


@Builder
public EmailVerification(Long id, String email, String code, LocalDateTime expiryDate, boolean emailVerified, String userType) {

this.id = id;
this.email = email;
this.code = code;
this.expiryDate = expiryDate;
this.emailVerified = emailVerified;
this.userType = userType;
public EmailCodeDto toDto() {
return EmailCodeDto.builder()
.email(this.email)
.expiryDate(this.expiryDate)
.emailVerified(this.emailVerified)
.userType(this.userType)
.build();
}
}
Loading