| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Cache;
- using Application.Abstractions.Messaging;
- using Application.Abstractions.Messaging.Email;
- using Application.Common;
- using Application.Helpers;
- using SharedKernel.Results;
- using Microsoft.EntityFrameworkCore;
- namespace Application.Features.Api.MyPage.ChangePassword;
- internal sealed class Handler(
- IAppDbContext db,
- ICacheService cache,
- IMailService mailService
- ) : ICommandHandler<Command, Result>
- {
- public async Task<Result> Handle(Command request, CancellationToken ct)
- {
- if (string.IsNullOrWhiteSpace(request.CurrentPassword))
- {
- return Result.Failure(Error.Problem("MyPage.CurrentPasswordRequired", "현재 비밀번호는 필수입니다."));
- }
- if (string.IsNullOrWhiteSpace(request.NewPassword))
- {
- return Result.Failure(Error.Problem("MyPage.NewPasswordRequired", "새 비밀번호는 필수입니다."));
- }
- if (request.NewPassword != request.ConfirmPassword)
- {
- return Result.Failure(Error.Problem("MyPage.PasswordMismatch", "새 비밀번호가 일치하지 않습니다."));
- }
- // Config 로드 + 비밀번호 복잡도 검증
- var accountConfig = await AccountConfigLoader.GetAccountConfigAsync(cache, db, ct);
- var passwordResult = PasswordPolicyValidator.Validate(request.NewPassword, accountConfig);
- if (!passwordResult.IsSuccess)
- {
- return passwordResult;
- }
- var member = await db.Member.FirstOrDefaultAsync(m => m.ID == request.MemberID, ct);
- if (member is null)
- {
- return Result.Failure(Error.NotFound("MyPage.MemberNotFound", "회원 정보를 찾을 수 없습니다."));
- }
- // 비밀번호 변경 주기 확인
- if (accountConfig.ChangePasswordDay is > 0)
- {
- var nextChangeDate = member.PasswordUpdatedAt.AddDays(accountConfig.ChangePasswordDay.Value);
- if (DateTime.UtcNow < nextChangeDate)
- {
- return Result.Failure(Error.Problem("MyPage.PasswordChangeTooSoon",
- $"비밀번호는 {accountConfig.ChangePasswordDay}일마다 변경 가능합니다."));
- }
- }
- if (!member.VerifyPassword(request.CurrentPassword))
- {
- return Result.Failure(Error.Problem("MyPage.InvalidPassword", "현재 비밀번호가 올바르지 않습니다."));
- }
- member.SetPassword(request.NewPassword);
- await db.SaveChangesAsync(ct);
- // 비밀번호 변경 완료 안내 메일
- var emailTpl = await AccountConfigLoader.GetEmailTemplateAsync(cache, db, ct);
- if (!string.IsNullOrWhiteSpace(emailTpl.ChangedPasswordEmailFormContent))
- {
- var subject = string.IsNullOrWhiteSpace(emailTpl.ChangedPasswordEmailFormTitle)
- ? "비밀번호가 변경되었습니다"
- : emailTpl.ChangedPasswordEmailFormTitle;
- var content = emailTpl.ChangedPasswordEmailFormContent.Render(
- ("Email", member.Email),
- ("CreatedAt", DateTime.UtcNow.AddHours(9).ToString("yyyy-MM-dd HH:mm")));
- await mailService.SendAsync(new SendData(member.Email, subject, content), ct);
- }
- return Result.Success();
- }
- }
|