diff --git a/Common/Dtos/Verification/ConfirmedCodeDto.cs b/Common/Dtos/Verification/ConfirmedCodeDto.cs new file mode 100644 index 0000000..73dd234 --- /dev/null +++ b/Common/Dtos/Verification/ConfirmedCodeDto.cs @@ -0,0 +1,13 @@ + +using Common.Enums; + +namespace Common.Dtos.Verification +{ + public class ConfirmedCodeDto + { + public int Id { get; set; } + public string code { get; set; } + public VerificationCodeType codeType { get; set; } + public string? value { get; set; } + } +} diff --git a/Common/Models/Auth/AuthResponse.cs b/Common/Models/Auth/AuthResponse.cs new file mode 100644 index 0000000..2e0dd3e --- /dev/null +++ b/Common/Models/Auth/AuthResponse.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Common.Models.Auth +{ + public class AuthResponse + { + public int Id { get; set; } + public string Fullname { get; set; } + public string MobileOrUserName { get; set; } + public string Token { get; set; } + } +} diff --git a/Common/Models/Auth/CompanySide/AuthRequestFromCompanySide.cs b/Common/Models/Auth/CompanySide/AuthRequestFromCompanySide.cs index 189e531..dd5f67d 100644 --- a/Common/Models/Auth/CompanySide/AuthRequestFromCompanySide.cs +++ b/Common/Models/Auth/CompanySide/AuthRequestFromCompanySide.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Common.Models.Auth.CompanySide { - class AuthRequestFromCompanySide + public class AuthRequestFromCompanySide { public string Username { get; set; } public string Password { get; set; } diff --git a/Common/Models/Auth/UserSide/AuthRequestFromUserSide.cs b/Common/Models/Auth/UserSide/AuthRequestFromUserSide.cs index 885d339..ee579ba 100644 --- a/Common/Models/Auth/UserSide/AuthRequestFromUserSide.cs +++ b/Common/Models/Auth/UserSide/AuthRequestFromUserSide.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Common.Models.Auth.UserSide { - class AuthRequestFromUserSide + public class AuthRequestFromUserSide { public string? FullName { get; set; } public string Mobile { get; set; } diff --git a/Common/Models/Auth/UserSide/AuthResponseFromUserSide.cs b/Common/Models/Auth/UserSide/AuthResponseFromUserSide.cs deleted file mode 100644 index e52b740..0000000 --- a/Common/Models/Auth/UserSide/AuthResponseFromUserSide.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Common.Models.Auth.UserSide -{ - class AuthRequestFromUserSide - { - } -} diff --git a/Hushian.Application/ApplicationServicesRegistration.cs b/Hushian.Application/ApplicationServicesRegistration.cs new file mode 100644 index 0000000..b71ef6b --- /dev/null +++ b/Hushian.Application/ApplicationServicesRegistration.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.IdentityModel.Tokens; +using System.Reflection; +using System.Text; + +namespace Hushian.Application +{ + public static class ApplicationServicesRegistration + { + public static void ConfigureApplicationServices(this IServiceCollection services, + IConfiguration configuration) + { + services.AddAutoMapper(Assembly.GetExecutingAssembly()); + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(o => + { + o.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ClockSkew = TimeSpan.Zero, + ValidIssuer = configuration["JwtSettings:Issuer"], + ValidAudience = configuration["JwtSettings:Audience"], + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtSettings:Key"])) + }; + }); + + } + } +} diff --git a/Common/Models/Auth/CompanySide/AuthResponseFromCompanySide.cs b/Hushian.Application/Constants/CustomClaimTypes.cs similarity index 52% rename from Common/Models/Auth/CompanySide/AuthResponseFromCompanySide.cs rename to Hushian.Application/Constants/CustomClaimTypes.cs index 808524d..b293c68 100644 --- a/Common/Models/Auth/CompanySide/AuthResponseFromCompanySide.cs +++ b/Hushian.Application/Constants/CustomClaimTypes.cs @@ -4,9 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Common.Models.Auth.CompanySide +namespace Hushian.Application.Constants { - class AuthRequestFromCompanySide + public static class CustomClaimTypes { + public const string Uid = "uid"; } } diff --git a/Hushian.Application/Hushian.Application.csproj b/Hushian.Application/Hushian.Application.csproj index dc59d4f..ed0ee54 100644 --- a/Hushian.Application/Hushian.Application.csproj +++ b/Hushian.Application/Hushian.Application.csproj @@ -6,6 +6,15 @@ enable + + + + + + + + + diff --git a/Hushian.Application/Models/JwtSettings.cs b/Hushian.Application/Models/JwtSettings.cs new file mode 100644 index 0000000..7c8e69a --- /dev/null +++ b/Hushian.Application/Models/JwtSettings.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hushian.Application.Models +{ + public class JwtSettings + { + public string Key { get; set; } + public string Issuer { get; set; } + public string Audience { get; set; } + public int DurationInMinutes { get; set; } + } +} diff --git a/Hushian.Application/Services/AuthService.cs b/Hushian.Application/Services/AuthService.cs new file mode 100644 index 0000000..9338106 --- /dev/null +++ b/Hushian.Application/Services/AuthService.cs @@ -0,0 +1,87 @@ +using Common.Models.Auth; +using Common.Models.Auth.CompanySide; +using Common.Models.Auth.UserSide; +using Hushian.Application.Constants; +using Hushian.Application.Contracts.Persistence; +using Hushian.Application.Models; +using Hushian.Domain.Entites; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; + +namespace Hushian.Application.Services +{ + public class AuthService + { + private readonly JwtSettings _jwtSettings; + private readonly IGenericRepository _CompanyRepository; + private readonly IGenericRepository _UserRepository; + private readonly IGenericRepository _ExperRepository; + private readonly VerificationService _verificationService; + public AuthService(IOptions jwtSettings) + { + _jwtSettings = jwtSettings.Value; + } + public async Task> AuthenticationFromCompanySide + (AuthRequestFromCompanySide auth) + { + ResponseBase Response = new(); + return Response; + } + public async Task> AuthenticationFromUserSide + (AuthRequestFromUserSide auth) + { + ResponseBase Response = new(); + if (!await _UserRepository.Get().AnyAsync(a => a.Mobile == auth.Mobile)) + { + if (!await _UserRepository.ADDBool(new User() { Mobile = auth.Mobile, FullName = auth.FullName })) + { + Response.Errors.Add("خطا در کاربری"); + } + } + + if (Response.Errors.Count==0) + { + + Response.Value = await _verificationService.GenerateCodeForLoginUser(auth.Mobile); + Response.Success = true; + } + return Response; + } + + public async Task GenerateToken(string UserName, int userId) + { + + + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Sub,UserName), + new Claim(CustomClaimTypes.Uid,userId.ToString()) + }; + + + var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Key)); + var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256); + + var jwtSecurityToken = new JwtSecurityToken( + issuer: _jwtSettings.Issuer, + audience: _jwtSettings.Audience, + claims: claims, + expires: DateTime.UtcNow.AddMinutes(_jwtSettings.DurationInMinutes), + signingCredentials: signingCredentials); + + //user.Token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); + //var resultupdateuser = await _userManager.UpdateAsync(user); + + return jwtSecurityToken; + } + } +} diff --git a/Hushian.Application/Services/VerificationService.cs b/Hushian.Application/Services/VerificationService.cs new file mode 100644 index 0000000..2cddfdd --- /dev/null +++ b/Hushian.Application/Services/VerificationService.cs @@ -0,0 +1,102 @@ +using Common.Contracts.Infrastructure; +using Common.Dtos.Verification; +using Common.Enums; +using Common.Models.Auth; +using Hushian.Application.Contracts.Persistence; +using Hushian.Application.Models; +using Hushian.Domain.Entites; +using Identity.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hushian.Application.Services +{ + public class VerificationService + { + private readonly IGenericRepository _VerificationCodeRepository; + private readonly IMessageSender _messageSender; + private readonly IGenericRepository _UserRepository; + private readonly AuthService _authService; + public async Task GenerateCodeForLoginUser(string Mobile) + { + string Code = await GenerateCode(); + var response= await _VerificationCodeRepository.ADD + (new Identity.Models.VerificationCode(VerificationCodeType.Login, Code, Mobile)); + await _messageSender.SendMassage(new Models.Message.Message() + { + msg = Code, + To = Mobile + }); + return response.ID; + } + public async Task> VerificationCode(ConfirmedCodeDto model) + { + var response = new ResponseBase(); + var resultConf=await _VerificationCodeRepository.Get() + .FirstOrDefaultAsync(w => w.ID == model.Id && w.Code == model.code && w.Type == model.codeType); + if (resultConf!=null) + { + if (resultConf.Type == VerificationCodeType.Login) + { + var User= await _UserRepository.Get().FirstOrDefaultAsync(w => w.Mobile == resultConf.Mobile); + if (User!=null) + { + response.Success = true; + response.Value = new AuthResponse() + { + Fullname = User.FullName, + Id = User.ID, + MobileOrUserName = User.Mobile, + Token = new JwtSecurityTokenHandler().WriteToken(await _authService.GenerateToken(User.Mobile, User.ID)) + }; + } + else + { + response.Errors.Add("کاربری یافت نشد"); + } + } + else if (resultConf.Type == VerificationCodeType.ForgetPassword) + { + if ((string.IsNullOrEmpty(model.value) || model.value.Length < 5)) + response.Errors.Add("کلمه عبور باید بیشتر از 5 کاراکتر باشد"); + else + { + + } + } + else if (resultConf.Type == VerificationCodeType.PhoneNumberConfirmed) + { + + } + else + { + response.Errors.Add("احراز صحیح نمی باشد"); + } + + await _VerificationCodeRepository.DELETE(resultConf); + } + else + { + response.Errors.Add("احراز یافت نشد"); + } + + return response; + + + + } + private async Task GenerateCode() + { + int Code = Random.Shared.Next(1000, 9000); + while (await _VerificationCodeRepository.Get().AnyAsync(w => w.Code == Code.ToString())) + Code = Random.Shared.Next(1000, 9000); + + return Code.ToString(); + } + } +} diff --git a/Hushian.Domain/Entites/Company.cs b/Hushian.Domain/Entites/Company.cs index 77c4a73..c5b5def 100644 --- a/Hushian.Domain/Entites/Company.cs +++ b/Hushian.Domain/Entites/Company.cs @@ -22,7 +22,7 @@ namespace Hushian.Domain.Entites public string Mobile { get; set; } public string? WebSite { get; set; } public string? Email { get; set; } - public byte[]? img { get; set; } + public byte[]? logo { get; set; } public bool Available { get; set; } = true; public bool allowBot { get; set; } = true; #endregion diff --git a/Hushian.Domain/Entites/VerificationCode.cs b/Hushian.Domain/Entites/VerificationCode.cs index 0ccc9c0..f82230c 100644 --- a/Hushian.Domain/Entites/VerificationCode.cs +++ b/Hushian.Domain/Entites/VerificationCode.cs @@ -5,19 +5,19 @@ namespace Identity.Models { public class VerificationCode : BaseEntity { - public VerificationCode(int companyIDorUserId, VerificationCodeType type, string code) + public VerificationCode( VerificationCodeType type, string code, string mobile) { - CompanyIDorUserId = companyIDorUserId; Type = type; Code = code; + Mobile = mobile; } public int ID { get; set; } - public int CompanyIDorUserId { get; set; } + ////CompanyIDorUserId + //public int? KeyId { get; set; } public VerificationCodeType Type { get; set; } public string Code { get; set; } - public string? newPassword { get; set; } - public string? Token { get; set; } + public string Mobile { get; set; } public DateTime Cdatetime { get; set; } = DateTime.Now; }