feat: 관리자 비밀번호 변경 API 구현 (#40) #41

Merged
seonkyu.kim merged 1 commits from feature/#40-change-password into develop 2026-02-09 14:24:14 +00:00
4 changed files with 61 additions and 0 deletions
Showing only changes of commit 9b9ca64b10 - Show all commits

View File

@ -63,4 +63,24 @@ public class AuthController : ControllerBase
await _authService.LogoutAsync(adminId); await _authService.LogoutAsync(adminId);
return Ok(ApiResponse.Success()); return Ok(ApiResponse.Success());
} }
[HttpPost("password/change")]
[Authorize]
[SwaggerOperation(
Summary = "비밀번호 변경",
Description = "현재 로그인된 관리자의 비밀번호를 변경합니다.")]
[SwaggerResponse(200, "비밀번호 변경 성공")]
[SwaggerResponse(400, "현재 비밀번호 불일치")]
[SwaggerResponse(401, "인증되지 않은 요청")]
public async Task<IActionResult> ChangePasswordAsync([FromBody] ChangePasswordRequestDto request)
{
var adminIdClaim = User.FindFirst("adminId")?.Value;
if (string.IsNullOrEmpty(adminIdClaim) || !long.TryParse(adminIdClaim, out var adminId))
{
return Unauthorized(ApiResponse<object>.Fail("101", "인증 정보가 유효하지 않습니다."));
}
await _authService.ChangePasswordAsync(adminId, request);
return Ok(ApiResponse.Success());
}
} }

View File

@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace SPMS.Application.DTOs.Auth;
public class ChangePasswordRequestDto
{
[Required(ErrorMessage = "현재 비밀번호를 입력해주세요.")]
public string CurrentPassword { get; set; } = string.Empty;
[Required(ErrorMessage = "새 비밀번호를 입력해주세요.")]
[MinLength(8, ErrorMessage = "비밀번호는 8자 이상이어야 합니다.")]
public string NewPassword { get; set; } = string.Empty;
}

View File

@ -7,4 +7,5 @@ public interface IAuthService
Task<LoginResponseDto> LoginAsync(LoginRequestDto request); Task<LoginResponseDto> LoginAsync(LoginRequestDto request);
Task<TokenRefreshResponseDto> RefreshTokenAsync(TokenRefreshRequestDto request); Task<TokenRefreshResponseDto> RefreshTokenAsync(TokenRefreshRequestDto request);
Task LogoutAsync(long adminId); Task LogoutAsync(long adminId);
Task ChangePasswordAsync(long adminId, ChangePasswordRequestDto request);
} }

View File

@ -146,4 +146,31 @@ public class AuthService : IAuthService
_adminRepository.Update(admin); _adminRepository.Update(admin);
await _unitOfWork.SaveChangesAsync(); await _unitOfWork.SaveChangesAsync();
} }
public async Task ChangePasswordAsync(long adminId, ChangePasswordRequestDto request)
{
// 1. 관리자 조회
var admin = await _adminRepository.GetByIdAsync(adminId);
if (admin is null)
{
throw new SpmsException(
ErrorCodes.NotFound,
"관리자를 찾을 수 없습니다.",
404);
}
// 2. 현재 비밀번호 검증
if (!BCrypt.Net.BCrypt.Verify(request.CurrentPassword, admin.Password))
{
throw new SpmsException(
ErrorCodes.PasswordValidationFailed,
"현재 비밀번호가 일치하지 않습니다.",
400);
}
// 3. 새 비밀번호 해싱 및 저장
admin.Password = BCrypt.Net.BCrypt.HashPassword(request.NewPassword);
_adminRepository.Update(admin);
await _unitOfWork.SaveChangesAsync();
}
} }