Skip to content
Open
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
4 changes: 0 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,6 @@ dependencies {
implementation 'io.micrometer:micrometer-core:1.7.6'


//Mail
implementation 'javax.mail:mail:1.4.7'


}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ public class Member {
private Double diversified;
private String fcmToken;

private String authKey;
private int authStatus;

private List<MemberProduct> memberProducts;
private List<Goal> goals;
private List<Account> accounts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import woojooin.planit.domain.member.domain.Member;
import woojooin.planit.domain.member.api.dto.res.InvestScoreRes;

import javax.mail.MessagingException;

public interface MemberService {
Member findById(Long memberId);
Member findByEmail(String email);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
package woojooin.planit.domain.member.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import woojooin.planit.domain.member.domain.Member;
import woojooin.planit.domain.member.api.dto.req.RealInvestTypeReq;
import woojooin.planit.domain.member.api.dto.res.InvestScoreRes;
import woojooin.planit.domain.member.mapper.MemberMapper;
import woojooin.planit.domain.member.repository.MemberRepository;
import woojooin.planit.domain.openAi.dto.req.DefaultInvestTypeReq;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.UUID;

@Service
public class MemberServiceImpl implements MemberService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private MemberMapper memberMapper;
@Autowired
private JavaMailSender mailSender;

@Override
public Member findById(Long memberId) {
Expand Down Expand Up @@ -74,5 +65,4 @@ public InvestScoreRes getInvestScore(Long id) {
public String getInvestmentType(Long memberId) {
return memberRepository.findInvestTypeById(memberId);
}

}
39 changes: 0 additions & 39 deletions src/main/java/woojooin/planit/global/config/MailConfig.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ public enum ResponseCode {
DUPLICATE_EMAIL("AUTH-003", "이미 사용 중인 이메일입니다.", HttpStatus.BAD_REQUEST),
INVALID_LOGIN("AUTH-004", "유효하지 않은 이메일 또는 비밀번호입니다.", HttpStatus.UNAUTHORIZED),
REISSUE_FAILED("AUTH-005", "리프레시 토큰 재발급에 실패했습니다.", HttpStatus.UNAUTHORIZED),
AUTH_KEY_INVALID("AUTH-006", "유효하지 않은 인증 키입니다.", HttpStatus.BAD_REQUEST),
EMAIL_SEND_FAILED("AUTH-007", "이메일 전송에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),

// ISA Account Domain Errors
ISA_MEMBER_NOT_FOUND("ISA-001", "해당 회원을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import woojooin.planit.domain.member.domain.Member;
import woojooin.planit.domain.member.service.MemberService;
import woojooin.planit.global.exception.BusinessException;
Expand All @@ -21,7 +19,6 @@
import woojooin.planit.global.security.dto.response.LoginRes;
import woojooin.planit.global.security.service.AuthService;

import java.net.URI;
import java.util.Collections;

@Slf4j
Expand All @@ -44,41 +41,7 @@ public ResponseEntity<?> login(@RequestBody LoginReq request) {
@PostMapping("/signup")
public ResponseEntity<?> signup(@RequestBody SignUpReq request) {
authService.signup(request);
return ResponseEntity.ok("회원가입 요청이 완료되었습니다. 이메일을 확인해주세요.");
}

@GetMapping("/auth/confirm-email")
public ResponseEntity<?> confirmEmail(@RequestParam("email") String email, @RequestParam("authKey") String authKey) {
final String frontendCallbackUrl = "https://planit-murex.vercel.app";
URI redirectUri;

try {
authService.confirmEmail(email, authKey);

redirectUri = UriComponentsBuilder.fromUriString(frontendCallbackUrl)
.queryParam("success", "true")
.build().toUri();

} catch (AuthenticationException e) {
log.error("Email confirm failed: {}", e.getMessage());

redirectUri = UriComponentsBuilder.fromUriString(frontendCallbackUrl)
.queryParam("success", "false")
.queryParam("error", "AUTH_KEY_INVALID")
.build().toUri();

} catch (Exception e) {
log.error("An unexpected error occurred during email confirmation", e);
redirectUri = UriComponentsBuilder.fromUriString(frontendCallbackUrl)
.queryParam("success", "false")
.queryParam("error", "SERVER_ERROR")
.build().toUri();
}

HttpHeaders headers = new HttpHeaders();
headers.setLocation(redirectUri);

return new ResponseEntity<>(headers, HttpStatus.FOUND);
return ResponseEntity.ok().build();
}

@PostMapping("/reissue")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ protected void doFilterInternal(HttpServletRequest request,
log.info("Processing JWT authentication for request: {}", request.getRequestURI());


if ( request.getRequestURI().startsWith("/api")) {
log.info("Bypassing JWT filter for URI: {}", request.getRequestURI());
filterChain.doFilter(request, response);
return;
}
// if ( request.getRequestURI().startsWith("/api")) {
// log.info("Bypassing JWT filter for URI: {}", request.getRequestURI());
// filterChain.doFilter(request, response);
// return;
// }

String token = resolveToken(request);

Expand Down Expand Up @@ -102,10 +102,6 @@ protected void doFilterInternal(HttpServletRequest request,
sendErrorResponse(response, "UNEXPECTED_ERROR", "예상치 못한 오류가 발생했습니다.");
return;
}
} else
{
sendErrorResponse(response, "UNAUTHORIZED", "인증 토큰이 없습니다.");
return;
}
filterChain.doFilter(request, response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
Expand All @@ -15,7 +13,6 @@
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import woojooin.planit.domain.member.domain.Member;
import woojooin.planit.domain.member.service.MemberService;
import woojooin.planit.global.exception.BusinessException;
Expand All @@ -28,9 +25,6 @@
import woojooin.planit.global.security.dto.response.LoginRes;
import woojooin.planit.global.security.jwt.JwtTokenProvider;

import javax.mail.internet.MimeMessage;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
Expand All @@ -40,7 +34,6 @@ public class AuthService {
private final TokenRepository tokenRepository;
private final MemberService memberService;
private final PasswordEncoder passwordEncoder;
private final JavaMailSender mailSender;

@Value("${jwt.refresh-token-expiration-mills}")
private long refreshTokenExpirationMillis;
Expand Down Expand Up @@ -74,58 +67,17 @@ public ResponseEntity<String> signup(SignUpReq request) {
throw new BusinessException(ResponseCode.DUPLICATE_EMAIL);
}

String authKey = UUID.randomUUID().toString();

Member newMember = new Member();
newMember.setEmail(request.getEmail());
newMember.setPassword(passwordEncoder.encode(request.getPassword()));
newMember.setNickname(request.getNickname());
newMember.setRole(Role.SEMI_USER.name());
newMember.setIsAgreed(true);
newMember.setAuthKey(authKey);
newMember.setAuthStatus(0);

memberService.save(newMember);

try {
sendVerificationEmail(newMember.getEmail(), authKey);
} catch (Exception e) {
log.error("Failed to send verification email", e);
throw new BusinessException(ResponseCode.EMAIL_SEND_FAILED);
}
return null;
}

private void sendVerificationEmail(String email, String authKey) throws Exception {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

helper.setSubject("[PlanIt] 회원가입 인증 메일입니다.");
helper.setTo(email);

String url = "http://localhost:8080/api/auth/confirm-email?email=" + email + "&authKey=" + authKey;

String htmlContent = "<h2>회원가입을 완료하려면 아래 링크를 클릭하세요.</h2>"
+ "<p>인증 링크: <a href='" + url + "'>이메일 인증하기</a></p>";

helper.setText(htmlContent, true);

mailSender.send(message);
}

@Transactional
public void confirmEmail(String email, String authKey) throws AuthenticationException {
Member member = memberService.findByEmail(email);

if (member.getAuthStatus() == 1) {
log.warn("Email already verified: {}", email);
return;
}

member.setAuthStatus(1);
memberService.update(member);
}

public String reissueAccessToken(String refreshToken) {
if (!jwtTokenProvider.validateToken(refreshToken)) {
throw new BadCredentialsException("Invalid refresh token");
Expand Down
9 changes: 4 additions & 5 deletions src/main/resources/mapper/MemberMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@
<insert id="insert" parameterType="woojooin.planit.domain.member.domain.Member" useGeneratedKeys="true" keyProperty="memberId">
INSERT INTO member (
role, connected_id, reward_cnt, social_id, auth_vender,
invest_type, last_visit, email, password, benefit, nickname, auth_key, auth_status
invest_type, last_visit, email, password, benefit, nickname
) VALUES (
#{role}, #{connectedId}, #{rewardCnt}, #{socialId}, #{authVender},
#{investType}, #{lastVisit}, #{email}, #{password}, #{benefit}, #{nickname}, #{authKey}, 0
#{investType}, #{lastVisit}, #{email}, #{password}, #{benefit}, #{nickname}
)
</insert>

Expand All @@ -89,9 +89,8 @@
email = #{email},
password = #{password},
benefit = #{benefit},
nickname = #{nickname},
auth_status = 1
WHERE member_id = #{memberId} AND auth_key = #{authKey}
nickname = #{nickname}
WHERE member_id = #{memberId}
</update>

<delete id="delete" parameterType="long">
Expand Down