좌충우돌 개발공부

TIL(20240619) [아웃소싱프로젝트: 프로필기능(비밀번호변경)]


📌 Spring

💡 아웃소싱프로젝트 : 프로필 기능(비밀번호 변경)

이전에 구현했던 부분이라 비밀번호 변경 부분만 수정조건이 추가되어서 덧붙여 구현해보았다.

  • 프로필 관리
    • 비밀번호 수정 조건
      • 비밀번호 수정 시, 본인 확인을 위해 현재 비밀번호를 입력하여 올바른 경우에만 수정할 수 있습니다.
      • 비밀번호는 현재 비밀번호 및 최근 사용한 세 개의 비밀번호와 다르게 설정해야 합니다.
      • 예시) 현재 비밀번호가 ‘currentPass’이고 이전 비밀번호가 ‘password1’, ‘password2’, ‘password3’였다면 새로운 비밀번호는 이 네 개와 다른 새로운 비밀번호여야 합니다.
    • 프로필 수정 기능
      • 이름, 한 줄 소개와 같은 기본적인 정보를 볼 수 있어야 하며 수정할 수 있어야 합니다.

@Service
@RequiredArgsConstructor
public class UserService {

  private final UserRepository userRepository;
  private final PasswordEncoder passwordEncoder;
  private final PasswordHistoryRepository passwordHistoryRepository;

  // 사용자 프로필 조회
  public UserResponseDto getUser(Long userSeq) {
    User user = findByUserSeq(userSeq);
    return new UserResponseDto(user);
  }

  // 사용자 프로필 수정
  @Transactional
  public UserResponseDto updateUser(UserRequestDto requestDto, Long userSeq) {
    User user = findByUserSeq(userSeq);
    user.updateUser(requestDto);
    return new UserResponseDto(user);
  }

  // 비밀번호 변경
  @Transactional
  public void updatePassword(UserPwRequestDto requestDto, Long userSeq) {
    User user = findByUserSeq(userSeq);
    String password = requestDto.getPassword();
    String newPassword = requestDto.getNewPassword();

    if (!passwordEncoder.matches(password, user.getUserPassword())) {
      throw new CustomException(ErrorCode.CURRENT_PASSWORD_MATCH);
    }

    if (passwordEncoder.matches(newPassword, user.getUserPassword())) {
      throw new CustomException(ErrorCode.SAME_NEW_PASSWORD);
    }

    List<PasswordHistory> usedPasswords = passwordHistoryRepository.findTop3ByUserOrderByChangedAtDesc(
        user);
    for (PasswordHistory usedPassword : usedPasswords) {
      if (passwordEncoder.matches(newPassword, usedPassword.getPassword())) {
        throw new CustomException(ErrorCode.RECENT_PASSWORD_MATCH);
      }
    }

    if (usedPasswords.size() >= 3) {
      PasswordHistory oldPassword = usedPasswords.get(usedPasswords.size() - 1);
      passwordHistoryRepository.delete(oldPassword);
    }

    PasswordHistory newPasswordHistory = new PasswordHistory(user, passwordEncoder.encode(newPassword), LocalDateTime.now());
    passwordHistoryRepository.save(newPasswordHistory);

    user.updatePassword(passwordEncoder.encode(newPassword));

  }

  private User findByUserSeq(Long userSeq) {
    return userRepository.findById(userSeq).orElseThrow(() ->
        new CustomException(ErrorCode.USER_NOT_FOUND)
    );
  }
}