complete auth for mobile api
This commit is contained in:
parent
43efe23587
commit
1b738897d2
|
|
@ -718,4 +718,22 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models
|
||||||
[Description("Percentage Based Discount")]
|
[Description("Percentage Based Discount")]
|
||||||
ZDS2 = 3
|
ZDS2 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum UserPlatFormType : short
|
||||||
|
{
|
||||||
|
SAP=1,
|
||||||
|
AppUser =2,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UserRoleTypeEnum
|
||||||
|
{
|
||||||
|
[Description("SAP User")]
|
||||||
|
SapUser = 1,
|
||||||
|
[Description("Order Collector")]
|
||||||
|
OrderCollector = 2,
|
||||||
|
[Description("OrderValidator")]
|
||||||
|
OrderValidator = 3,
|
||||||
|
[Description("OrderApprover")]
|
||||||
|
OrderApprover =4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,9 +26,14 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems
|
||||||
public string SchemeName { get; set; }
|
public string SchemeName { get; set; }
|
||||||
public string MenuLayout { get; set; }
|
public string MenuLayout { get; set; }
|
||||||
public bool IsLocked { get; set; }
|
public bool IsLocked { get; set; }
|
||||||
|
|
||||||
|
public UserPlatFormType? UserPlatFormType { get; set; }
|
||||||
|
public UserRoleTypeEnum? UserRoleType { get; set; }
|
||||||
|
public string? EmployeeNumber { get; set; }
|
||||||
|
public string? DesignationCode { get; set; }
|
||||||
|
public string? DesignationName { get; set; }
|
||||||
public EnumLoginStatus LoginStatus { get; set; }
|
public EnumLoginStatus LoginStatus { get; set; }
|
||||||
public DateTime? NextLoginTime { get; set; }
|
public DateTime? NextLoginTime { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LoginHistory
|
public class LoginHistory
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
|
|
||||||
|
public class AuthLoginRequest
|
||||||
|
{
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 3, ErrorMessage = "Login Id must be between 4 and 30 characters.")]
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 5, ErrorMessage = "Password must be between 1 and 30 characters.")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,14 @@
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
|
|
||||||
public class IntegrationLoginRequest
|
public class IntegrationLoginRequest : AuthLoginRequest
|
||||||
{
|
{
|
||||||
[Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 3, ErrorMessage = "Login Id must be between 4 and 30 characters.")]
|
|
||||||
public string LoginId { get; set; }
|
|
||||||
|
|
||||||
[Required, NotNull, StringLength(maximumLength: 150, MinimumLength = 5, ErrorMessage = "Password must be between 1 and 30 characters.")]
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class IntegrationRefreshTokenRequest
|
public class IntegrationRefreshTokenRequest
|
||||||
{
|
{
|
||||||
public string RefreshToken { get; set; }
|
public string RefreshToken { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
||||||
|
|
||||||
|
public class MobileAppAuthRequest : AuthLoginRequest
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuthLogoutRequest
|
||||||
|
{
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class AppUserChangePasswordRequest
|
||||||
|
{
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
|
||||||
|
[Compare("NewPassword", ErrorMessage = "Password and Confirm Password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(NewPassword) &&
|
||||||
|
!string.IsNullOrWhiteSpace(ConfirmPassword) &&
|
||||||
|
Password != ConfirmPassword)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult(
|
||||||
|
"Password and Confirm Password do not match.",
|
||||||
|
[nameof(NewPassword), nameof(ConfirmPassword)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(LoginId) &&
|
||||||
|
!string.IsNullOrWhiteSpace(NewPassword) &&
|
||||||
|
Password.Equals(LoginId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
yield return new ValidationResult(
|
||||||
|
"Password must not be the same as your Login ID.",
|
||||||
|
[nameof(NewPassword)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
||||||
|
|
@ -219,3 +220,43 @@ public class PayslipRequest
|
||||||
[Required, NotNull]
|
[Required, NotNull]
|
||||||
public DateTime YearMonth { get; set; }
|
public DateTime YearMonth { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class AppUserCreateRequest
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "Login ID is required.")]
|
||||||
|
[MaxLength(100, ErrorMessage = "Login ID cannot exceed 100 characters.")]
|
||||||
|
public string LoginId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Username is required.")]
|
||||||
|
[MaxLength(150, ErrorMessage = "Username cannot exceed 150 characters.")]
|
||||||
|
public string UserName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int Status { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int AccessStatus { get; set; }
|
||||||
|
|
||||||
|
[Phone(ErrorMessage = "Invalid mobile number format.")]
|
||||||
|
[MaxLength(20, ErrorMessage = "Mobile number cannot exceed 20 characters.")]
|
||||||
|
public string? MobileNo { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Email address is required.")]
|
||||||
|
[EmailAddress(ErrorMessage = "Invalid email address format.")]
|
||||||
|
[MaxLength(200, ErrorMessage = "Email address cannot exceed 200 characters.")]
|
||||||
|
public string EmailAddress { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int IsLocked { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Password is required.")]
|
||||||
|
[MaxLength(500, ErrorMessage = "Password hash length cannot exceed 500 characters.")]
|
||||||
|
public string Password { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int? UserPlatformId { get; set; }
|
||||||
|
|
||||||
|
public int? UserRoleType { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(10,ErrorMessage = "EmployeeNumber hash length cannot exceed 10 characters")]
|
||||||
|
public string? EmployeeNumber { get; set; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ public class IntegrationRrefreshTokenResponse : ResponseBase
|
||||||
public string RefreshToken { get; set; } = string.Empty;
|
public string RefreshToken { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class RefreshTokenResponse : ResponseBase
|
public class RefreshTokenResponse : ResponseBase
|
||||||
{
|
{
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
|
|
||||||
|
public class AppAuthUserResponse : ResponseBase
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string? Email { get; set; }
|
||||||
|
public string? MobileNumber { get; set; }
|
||||||
|
public string EmployeeNumber { get; set; }
|
||||||
|
public string DesignationCode { get; set; }
|
||||||
|
public string DesignationName { get; set; }
|
||||||
|
public bool IsLocked { get; set; }
|
||||||
|
public UserRoleTypeEnum UserRole { get; set; }
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
public DateTime AccessTokenExpiryTime { get; set; }
|
||||||
|
public string RefreshToken { get; set; }
|
||||||
|
public DateTime RefreshTokenExpiryTime { get; set; }
|
||||||
|
public EnumLoginStatus LoginStatus { get; set; }
|
||||||
|
public bool IsAuthorized { get; set; }
|
||||||
|
public bool IsInitialPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class AuthLogoutResponse : ResponseBase
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
public bool IsSuccess { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AppChangePasswordResponse : ResponseBase
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public string LoginId { get; set; }
|
||||||
|
public bool IsSuccess { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
using Ease.NetCore.DataAccess;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -9,4 +10,5 @@ public interface IRefreshTokenService
|
||||||
Task<GenerateRefreshTokenResponse> GenerateRefreshTokenByUserAsync(GenerateRefreshTokenRequest request);
|
Task<GenerateRefreshTokenResponse> GenerateRefreshTokenByUserAsync(GenerateRefreshTokenRequest request);
|
||||||
Task<string> GenerateRefreshTokenAsync(string refreshToken, string ipAddress);
|
Task<string> GenerateRefreshTokenAsync(string refreshToken, string ipAddress);
|
||||||
Task<UserByRefreshTokenResponse> GetUserByRefreshTokenAsync(string refreshToken);
|
Task<UserByRefreshTokenResponse> GetUserByRefreshTokenAsync(string refreshToken);
|
||||||
|
Task<bool> InvalidRefreshTokenAsync(TransactionContext tc, int userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Setups;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Setups;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -13,10 +16,14 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems
|
||||||
{
|
{
|
||||||
Task<bool> ValidateAuthValueAsync(string authValue, int userId);
|
Task<bool> ValidateAuthValueAsync(string authValue, int userId);
|
||||||
Task<User> LoginAsync(LoginRequest request, string ipAddress, bool checkPwd);
|
Task<User> LoginAsync(LoginRequest request, string ipAddress, bool checkPwd);
|
||||||
|
Task<AppAuthUserResponse> LoginAsync(MobileAppAuthRequest request, string ipAddress);
|
||||||
Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd);
|
Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd);
|
||||||
|
|
||||||
Task<bool> LogoutAsync(string ipAddress, int userId, int logId, bool attendanceLogout, string loginId, string localIp, string macAddress, string hostName, string logoutRemarks);
|
Task<bool> LogoutAsync(string ipAddress, int userId, int logId, bool attendanceLogout, string loginId, string localIp, string macAddress, string hostName, string logoutRemarks);
|
||||||
|
|
||||||
|
Task<AuthLogoutResponse> LogoutAsync(AuthLogoutRequest request, string ipAddress);
|
||||||
|
Task<AppChangePasswordResponse> ChangePasswordAsync(AppUserChangePasswordRequest request, string ipAddress);
|
||||||
|
|
||||||
Task<bool> DeleteUserAsync(int userId, int deletedBy);
|
Task<bool> DeleteUserAsync(int userId, int deletedBy);
|
||||||
Task<bool> ForceLogoutNowAsync(List<int> userIds, string ipAddress);
|
Task<bool> ForceLogoutNowAsync(List<int> userIds, string ipAddress);
|
||||||
Task<bool> UnlockUserAsync(int userId, string loginId, int unlockedBy);
|
Task<bool> UnlockUserAsync(int userId, string loginId, int unlockedBy);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Ease.NetCore.DataAccess.SQL;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
||||||
|
|
@ -116,6 +117,22 @@ public class RefreshTokenService : IRefreshTokenService
|
||||||
return refreshTokenResponse;
|
return refreshTokenResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> InvalidRefreshTokenAsync( TransactionContext tc, int userId)
|
||||||
|
{
|
||||||
|
bool response = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RevokeRefreshTokenByUserIdAsync(tc, userId);
|
||||||
|
response = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
// ----- private helpers -----
|
// ----- private helpers -----
|
||||||
|
|
||||||
|
|
@ -145,7 +162,7 @@ public class RefreshTokenService : IRefreshTokenService
|
||||||
SqlHelperExtension.CreateInParam(pName: "@TokenHash", pType: SqlDbType.VarChar, pValue: refreshToken.TokenHash),
|
SqlHelperExtension.CreateInParam(pName: "@TokenHash", pType: SqlDbType.VarChar, pValue: refreshToken.TokenHash),
|
||||||
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: refreshToken.IpAddress),
|
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: refreshToken.IpAddress),
|
||||||
SqlHelperExtension.CreateInParam(pName: "@CreatedAt", pType: SqlDbType.DateTime, pValue: DateTime.Now),
|
SqlHelperExtension.CreateInParam(pName: "@CreatedAt", pType: SqlDbType.DateTime, pValue: DateTime.Now),
|
||||||
SqlHelperExtension.CreateInParam(pName: "@ExpiredAt", pType: SqlDbType.DateTime, pValue: DateTime.Now.AddMinutes(_settings.RefreshTokenDuration)),
|
SqlHelperExtension.CreateInParam(pName: "@ExpiredAt", pType: SqlDbType.DateTime, pValue: refreshToken.ExpiresAt),
|
||||||
];
|
];
|
||||||
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertRefreshToken", parameterValues: p);
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertRefreshToken", parameterValues: p);
|
||||||
|
|
||||||
|
|
@ -259,7 +276,7 @@ public class RefreshTokenService : IRefreshTokenService
|
||||||
return new GenerateRefreshTokenResponse
|
return new GenerateRefreshTokenResponse
|
||||||
{
|
{
|
||||||
RefreshToken = tokenHash,
|
RefreshToken = tokenHash,
|
||||||
ExpireTime = DateTime.UtcNow.AddMinutes(_settings.RefreshTokenDuration)
|
ExpireTime = DateTime.UtcNow.AddDays(_settings.RefreshTokenDuration)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,5 +294,7 @@ public class RefreshTokenService : IRefreshTokenService
|
||||||
return Convert.ToBase64String(bytes);
|
return Convert.ToBase64String(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
using Ease.NetCore.DataAccess;
|
using Ease.NetCore.DataAccess;
|
||||||
using Ease.NetCore.DataAccess.SQL;
|
using Ease.NetCore.DataAccess.SQL;
|
||||||
|
using Ease.NetCore.Utility;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
|
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
|
||||||
|
|
@ -16,10 +22,12 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Integrations;
|
||||||
public class IntegrationService : IIntegrationService
|
public class IntegrationService : IIntegrationService
|
||||||
{
|
{
|
||||||
private readonly AppSettings _settings;
|
private readonly AppSettings _settings;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
public IntegrationService(IOptions<AppSettings> options)
|
public IntegrationService(IOptions<AppSettings> options, IUserService userService)
|
||||||
{
|
{
|
||||||
_settings = options.Value;
|
_settings = options.Value;
|
||||||
|
_userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -142,6 +150,28 @@ public class IntegrationService : IIntegrationService
|
||||||
response.IsUpdated = false;
|
response.IsUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUserExist = await IsUserExistByEmployeeNumberAsync(tc, request.EmployeeVendorCode);
|
||||||
|
|
||||||
|
if (!isUserExist)
|
||||||
|
{
|
||||||
|
AppUserCreateRequest appUser = new()
|
||||||
|
{
|
||||||
|
LoginId = request.EmployeeVendorCode,
|
||||||
|
UserName = request.EmployeeVendorCode,
|
||||||
|
Status = (int)EnumStatus.Authorized,
|
||||||
|
AccessStatus = (int)EnumAccessStatus.FirstTime,
|
||||||
|
MobileNo = request.MobileNo,
|
||||||
|
EmailAddress = request.Mail,
|
||||||
|
IsLocked = 0,
|
||||||
|
Password ="12345",
|
||||||
|
UserRoleType = request.Designation == "01"? (int)UserRoleTypeEnum.OrderCollector : null,
|
||||||
|
UserPlatformId = (int)UserPlatFormType.AppUser,
|
||||||
|
EmployeeNumber = request.EmployeeVendorCode
|
||||||
|
};
|
||||||
|
|
||||||
|
await AddUserAsync(tc, appUser);
|
||||||
|
}
|
||||||
|
|
||||||
response.EmployeeVendorCode = request.EmployeeVendorCode;
|
response.EmployeeVendorCode = request.EmployeeVendorCode;
|
||||||
response.CompanyCode = request.CompanyCode;
|
response.CompanyCode = request.CompanyCode;
|
||||||
tc.End();
|
tc.End();
|
||||||
|
|
@ -717,6 +747,93 @@ public class IntegrationService : IIntegrationService
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<bool> AddUserAsync(TransactionContext tc, AppUserCreateRequest user)
|
||||||
|
{
|
||||||
|
bool returnValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int userId = 0;
|
||||||
|
user.Password = EncryptPassword(password: user.Password);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(user.EmailAddress))
|
||||||
|
user.EmailAddress = user.EmailAddress.Replace(" ", "");
|
||||||
|
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 100),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserName", pType: SqlDbType.VarChar, pValue: user.UserName, size: 150),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@Status", pType: SqlDbType.Int, pValue: user.Status),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@AccessStatus", pType: SqlDbType.Int, pValue: user.AccessStatus),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@MobileNo", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.MobileNo), size: 20),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@EmailAddress", pType: SqlDbType.VarChar, pValue: user.EmailAddress, size: 200),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@IsLocked", pType: SqlDbType.Int, pValue: user.IsLocked),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@Password", pType: SqlDbType.NVarChar, pValue: user.Password, size: 500),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserPlatformId", pType: SqlDbType.Int, pValue: DataReader.GetNullValue(user.UserPlatformId)),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserRoleType", pType: SqlDbType.Int, pValue: DataReader.GetNullValue(user.UserRoleType)),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.EmployeeNumber), size: 10),
|
||||||
|
SqlHelperExtension.CreateOutParam(pName: "@NewUserId", pType: SqlDbType.Int) // index 11 — output
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.InsertUser", parameterValues: p);
|
||||||
|
userId = (p[11]?.Value != null && p[11]?.Value != DBNull.Value)
|
||||||
|
? Convert.ToInt32(p[11].Value)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
returnValue = userId > 0;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string EncryptPassword(string password)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string pwdSecretKey = GlobalFunctions.ConvertFromBase64String(_settings.PwdSecretKey);
|
||||||
|
return Global.CipherFunctions.EncryptByAES(privateKey: pwdSecretKey, publicKey: pwdSecretKey, data: password);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> IsUserExistByEmployeeNumberAsync(TransactionContext tc, string employeeNumber)
|
||||||
|
{
|
||||||
|
bool response = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.NVarChar, pValue: employeeNumber)
|
||||||
|
];
|
||||||
|
|
||||||
|
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.IsUserExistByEmployeeNumber", parameterValues: p))
|
||||||
|
{
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
response = dr.GetInt32(0) > 0 ? true: false;
|
||||||
|
}
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw DBCustomError.GenerateCustomError(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
private bool InsertEmployee(TransactionContext tc, IntegrationEmployeeRequest request)
|
private bool InsertEmployee(TransactionContext tc, IntegrationEmployeeRequest request)
|
||||||
{
|
{
|
||||||
bool returnValue = false;
|
bool returnValue = false;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,33 @@
|
||||||
using Ease.NetCore.DataAccess;
|
using Ease.NetCore.DataAccess;
|
||||||
using Ease.NetCore.DataAccess.SQL;
|
using Ease.NetCore.DataAccess.SQL;
|
||||||
using Ease.NetCore.Utility;
|
using Ease.NetCore.Utility;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models;
|
using OnlineSalesAutoCrop.CoreAPI.Models;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
{
|
{
|
||||||
public class UserService(IOptions<AppSettings> settings, IOptions<MenuSettings> menuSettings) : IUserService
|
public class UserService(IOptions<AppSettings> settings, IOptions<MenuSettings> menuSettings, IRefreshTokenService refreshTokenService) : IUserService
|
||||||
{
|
{
|
||||||
private readonly AppSettings _settings = settings?.Value;
|
private readonly AppSettings _settings = settings?.Value;
|
||||||
private readonly MenuSettings _menuSettings = menuSettings?.Value;
|
private readonly MenuSettings _menuSettings = menuSettings?.Value;
|
||||||
|
private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|
@ -348,6 +353,192 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<AppAuthUserResponse> LoginAsync(MobileAppAuthRequest request, string ipAddress)
|
||||||
|
{
|
||||||
|
AppAuthUserResponse response = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string password = EncryptPassword(password: request.Password);
|
||||||
|
User user = null;
|
||||||
|
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DateTime sysDate = DateTime.Today.Date;
|
||||||
|
string appVer = string.Empty, alParams = string.Empty;
|
||||||
|
int maxTryCount = 5, lockTime = 1;
|
||||||
|
|
||||||
|
bool initialPassword = false;
|
||||||
|
|
||||||
|
#region Read User data using authentication data
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
|
||||||
|
];
|
||||||
|
|
||||||
|
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
|
||||||
|
{
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
user = new User();
|
||||||
|
{
|
||||||
|
user.UserId = dr.GetInt32(0);
|
||||||
|
user.Password = dr.GetString(1);
|
||||||
|
user.LoginId = dr.GetString(2);
|
||||||
|
user.UserName = dr.GetString(3);
|
||||||
|
user.Status = (EnumStatus)dr.GetInt32(4);
|
||||||
|
user.MobileNo = dr.GetString(5);
|
||||||
|
user.EmailAddress = dr.GetString(6);
|
||||||
|
user.AuthKey = dr.GetString(7);
|
||||||
|
user.AuthValue = dr.GetString(8);
|
||||||
|
user.IsLocked = dr.GetBoolean(9);
|
||||||
|
user.LoginStatus = EnumLoginStatus.Success;
|
||||||
|
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
|
||||||
|
user.EmployeeNumber = dr.GetString(11);
|
||||||
|
user.DesignationCode = dr.GetString(12);
|
||||||
|
user.DesignationName = dr.GetString(13);
|
||||||
|
};
|
||||||
|
|
||||||
|
initialPassword = dr.GetInt32(14) > 0;
|
||||||
|
}
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
tc.End();
|
||||||
|
throw new InvalidOperationException($"User not found with login: {request.LoginId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password.Equals(user.Password))
|
||||||
|
{
|
||||||
|
tc.End();
|
||||||
|
throw new InvalidOperationException($"Password mismatch for login: {request.LoginId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region If the user was locked, try set set unlock if Time expired
|
||||||
|
|
||||||
|
if (!request.LoginId.ToLower().Equals(User.SuperUser_LoginId) && user.IsLocked)
|
||||||
|
{
|
||||||
|
int isSuccessful = 0;
|
||||||
|
p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: request.LoginId, size: 30),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LockTime", pType: SqlDbType.Int, pValue: lockTime),
|
||||||
|
SqlHelperExtension.CreateOutParam(pName: "@IsSuccessful", pType: SqlDbType.Int, pValue: isSuccessful),
|
||||||
|
];
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.DoUnlockUser", parameterValues: p);
|
||||||
|
if (p[2] != null && p[2].Value != null && p[2].Value != DBNull.Value)
|
||||||
|
isSuccessful = Convert.ToInt32(p[2].Value);
|
||||||
|
|
||||||
|
if (isSuccessful == 1)
|
||||||
|
user.IsLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Keep log for unauthrise access and Set user lock if exceeds max try
|
||||||
|
|
||||||
|
if (!request.LoginId.ToLower().Equals(User.SuperUser_LoginId) && maxTryCount > 0 && user.LoginStatus == EnumLoginStatus.Unsuccessful)
|
||||||
|
{
|
||||||
|
int remainsTry = 0;
|
||||||
|
DateTime? nextLoginTime = null;
|
||||||
|
string tryLoginInfo = $"{request.LoginId}~{password}~13";
|
||||||
|
p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: request.LoginId, size: 30),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@TryLoginInfo", pType: SqlDbType.VarChar, pValue: tryLoginInfo, size: 100),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@MaxTryCount", pType: SqlDbType.SmallInt, pValue: maxTryCount),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LockTime", pType: SqlDbType.Int, pValue: lockTime),
|
||||||
|
SqlHelperExtension.CreateOutParam(pName: "@RemainingTry", pType: SqlDbType.SmallInt, pValue: remainsTry),
|
||||||
|
SqlHelperExtension.CreateOutParam(pName: "@NextLoginTime", pType: SqlDbType.DateTime, pValue: nextLoginTime),
|
||||||
|
];
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.LogUnauthorizeAccess", parameterValues: p);
|
||||||
|
if (p[5] != null && p[5].Value != null && p[5].Value != DBNull.Value)
|
||||||
|
remainsTry = Convert.ToInt32(p[5].Value);
|
||||||
|
|
||||||
|
if (p[6] != null && p[6].Value != null && p[6].Value != DBNull.Value)
|
||||||
|
nextLoginTime = Convert.ToDateTime(p[6].Value);
|
||||||
|
|
||||||
|
if (remainsTry <= 0)
|
||||||
|
{
|
||||||
|
user.IsLocked = true;
|
||||||
|
if (lockTime <= 0)
|
||||||
|
{
|
||||||
|
user.NextLoginTime = nextLoginTime;
|
||||||
|
user.UnsuccessfulMsg = "Please contact with Head office to Unlock";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.NextLoginTime = nextLoginTime;
|
||||||
|
user.UnsuccessfulMsg = $"You can Login after {user.NextLoginTime:dd-MMM-yyyy H:mm:ss}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.UnsuccessfulMsg = $"{remainsTry} More attempt{(remainsTry > 1 ? "s" : "")} remaining";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region If login successful and user is active read module id for this user
|
||||||
|
|
||||||
|
if (user.LoginStatus == EnumLoginStatus.Success && user.Status == EnumStatus.Authorized && !user.IsLocked)
|
||||||
|
{
|
||||||
|
p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 30),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: DateTime.Now),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LogoutTime", pType: SqlDbType.DateTime, pValue: null)
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.SaveAccessLog", parameterValues: p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
response = new()
|
||||||
|
{
|
||||||
|
UserId = user.UserId,
|
||||||
|
Name = user.UserName,
|
||||||
|
LoginId = user.LoginId,
|
||||||
|
Email = user.EmailAddress,
|
||||||
|
MobileNumber = user.MobileNo,
|
||||||
|
IsLocked = user.IsLocked,
|
||||||
|
UserRole = user.UserRoleType.Value,
|
||||||
|
LoginStatus = user.LoginStatus,
|
||||||
|
IsAuthorized = EnumStatus.Authorized == user.Status,
|
||||||
|
EmployeeNumber = user.EmployeeNumber,
|
||||||
|
DesignationCode = user.DesignationCode,
|
||||||
|
DesignationName = user.DesignationName,
|
||||||
|
IsInitialPassword = initialPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
tc.End();
|
||||||
|
}
|
||||||
|
catch (Exception ie)
|
||||||
|
{
|
||||||
|
tc?.HandleError();
|
||||||
|
|
||||||
|
throw DBCustomError.GenerateCustomError(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd)
|
public async Task<User> IntegrationLoginAsync(IntegrationLoginRequest request, string ipAddress, bool checkPwd)
|
||||||
{
|
{
|
||||||
User user = null;
|
User user = null;
|
||||||
|
|
@ -365,7 +556,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
#region Read User data using authentication data
|
#region Read User data using authentication data
|
||||||
|
|
||||||
string commandText = SQLParser.MakeSQL("SELECT UserId,Password,LoginId, UserName, Status, ISNULL(MobileNo,'')MobileNo ,ISNULL( EmailAddress,'')EmailAddress,"
|
string commandText = SQLParser.MakeSQL("SELECT UserId,Password,LoginId, UserName, Status, ISNULL(MobileNo,'')MobileNo ,ISNULL( EmailAddress,'')EmailAddress,"
|
||||||
+ " ISNULL(AuthKey,'') AuthKey, ISNULL(AuthValue,'')AuthValue, IsLocked FROM Users WHERE LoginID=%s", request.LoginId);
|
+ " ISNULL(AuthKey,'') AuthKey, ISNULL(AuthValue,'')AuthValue, IsLocked FROM Users WHERE LoginID=%s and UserPlatformId=1 ", request.LoginId);
|
||||||
|
|
||||||
using (IDataReader dr = tc.ExecuteReader(commandText: commandText))
|
using (IDataReader dr = tc.ExecuteReader(commandText: commandText))
|
||||||
{
|
{
|
||||||
|
|
@ -505,6 +696,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2231,6 +2424,206 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<AuthLogoutResponse> LogoutAsync(AuthLogoutRequest request, string ipAddress)
|
||||||
|
{
|
||||||
|
AuthLogoutResponse response = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
User user = null;
|
||||||
|
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DateTime sysDate = DateTime.Today.Date;
|
||||||
|
string appVer = string.Empty, alParams = string.Empty;
|
||||||
|
|
||||||
|
#region Read User data using authentication data
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
|
||||||
|
];
|
||||||
|
|
||||||
|
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
|
||||||
|
{
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
user = new User();
|
||||||
|
{
|
||||||
|
user.UserId = dr.GetInt32(0);
|
||||||
|
user.Password = dr.GetString(1);
|
||||||
|
user.LoginId = dr.GetString(2);
|
||||||
|
user.UserName = dr.GetString(3);
|
||||||
|
user.Status = (EnumStatus)dr.GetInt32(4);
|
||||||
|
user.MobileNo = dr.GetString(5);
|
||||||
|
user.EmailAddress = dr.GetString(6);
|
||||||
|
user.AuthKey = dr.GetString(7);
|
||||||
|
user.AuthValue = dr.GetString(8);
|
||||||
|
user.IsLocked = dr.GetBoolean(9);
|
||||||
|
user.LoginStatus = EnumLoginStatus.Success;
|
||||||
|
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
|
||||||
|
user.EmployeeNumber = dr.GetString(11);
|
||||||
|
user.DesignationCode = dr.GetString(12);
|
||||||
|
user.DesignationName = dr.GetString(13);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
tc.End();
|
||||||
|
throw new InvalidOperationException($"User not found with login: {request.LoginId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region If login successful and user is active read module id for this user
|
||||||
|
|
||||||
|
if (user.LoginStatus == EnumLoginStatus.Success && user.Status == EnumStatus.Authorized && !user.IsLocked)
|
||||||
|
{
|
||||||
|
p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.VarChar, pValue: user.LoginId, size: 30),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@IpAddress", pType: SqlDbType.VarChar, pValue: ipAddress, size: 20),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginTime", pType: SqlDbType.DateTime, pValue: null),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LogoutTime", pType: SqlDbType.DateTime, pValue: DateTime.Now)
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.SaveAccessLog", parameterValues: p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
await _refreshTokenService.InvalidRefreshTokenAsync(tc, user.UserId);
|
||||||
|
|
||||||
|
response = new()
|
||||||
|
{
|
||||||
|
UserId = user.UserId,
|
||||||
|
LoginId = user.LoginId,
|
||||||
|
IsSuccess = true
|
||||||
|
};
|
||||||
|
|
||||||
|
tc.End();
|
||||||
|
}
|
||||||
|
catch (Exception ie)
|
||||||
|
{
|
||||||
|
tc?.HandleError();
|
||||||
|
|
||||||
|
throw DBCustomError.GenerateCustomError(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AppChangePasswordResponse> ChangePasswordAsync(AppUserChangePasswordRequest request, string ipAddress)
|
||||||
|
{
|
||||||
|
AppChangePasswordResponse response = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string password = EncryptPassword(password: request.Password);
|
||||||
|
User user = null;
|
||||||
|
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DateTime sysDate = DateTime.Today.Date;
|
||||||
|
string appVer = string.Empty, alParams = string.Empty;
|
||||||
|
|
||||||
|
#region Read User data using authentication data
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LoginId", pType: SqlDbType.NVarChar, pValue: request.LoginId)
|
||||||
|
];
|
||||||
|
|
||||||
|
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserByLogin", parameterValues: p))
|
||||||
|
{
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
user = new User();
|
||||||
|
{
|
||||||
|
user.UserId = dr.GetInt32(0);
|
||||||
|
user.Password = dr.GetString(1);
|
||||||
|
user.LoginId = dr.GetString(2);
|
||||||
|
user.UserName = dr.GetString(3);
|
||||||
|
user.Status = (EnumStatus)dr.GetInt32(4);
|
||||||
|
user.MobileNo = dr.GetString(5);
|
||||||
|
user.EmailAddress = dr.GetString(6);
|
||||||
|
user.AuthKey = dr.GetString(7);
|
||||||
|
user.AuthValue = dr.GetString(8);
|
||||||
|
user.IsLocked = dr.GetBoolean(9);
|
||||||
|
user.LoginStatus = EnumLoginStatus.Success;
|
||||||
|
user.UserRoleType = (UserRoleTypeEnum)dr.GetInt32(10);
|
||||||
|
user.EmployeeNumber = dr.GetString(11);
|
||||||
|
user.DesignationCode = dr.GetString(12);
|
||||||
|
user.DesignationName = dr.GetString(13);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
tc.End();
|
||||||
|
throw new InvalidOperationException($"User not found with login: {request.LoginId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password.Equals(user.Password))
|
||||||
|
{
|
||||||
|
tc.End();
|
||||||
|
throw new InvalidOperationException($"Password mismatch for login: {request.LoginId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
string newPassword = EncryptPassword(request.ConfirmPassword);
|
||||||
|
|
||||||
|
|
||||||
|
p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: user.UserId),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@Password", pType: SqlDbType.VarChar, pValue: newPassword, size: 30),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LastPassword", pType: SqlDbType.VarChar, pValue: password, size: 20),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@LastPasswordChnageDate", pType: SqlDbType.DateTime, pValue: DateTime.Now)
|
||||||
|
];
|
||||||
|
|
||||||
|
_ = tc.ExecuteNonQuerySp(spName: "dbo.ChangePassword", parameterValues: p);
|
||||||
|
|
||||||
|
response = new()
|
||||||
|
{
|
||||||
|
UserId = user.UserId,
|
||||||
|
LoginId = user.LoginId,
|
||||||
|
IsSuccess = true
|
||||||
|
};
|
||||||
|
|
||||||
|
tc.End();
|
||||||
|
}
|
||||||
|
catch (Exception ie)
|
||||||
|
{
|
||||||
|
tc?.HandleError();
|
||||||
|
|
||||||
|
throw DBCustomError.GenerateCustomError(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -2636,11 +3029,6 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.Systems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class UserSearchResponse
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +230,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
loginReponse.AccessToken = userToken;
|
loginReponse.AccessToken = userToken;
|
||||||
loginReponse.RefreshToken = refreshToken.RefreshToken;
|
loginReponse.RefreshToken = refreshToken.RefreshToken;
|
||||||
loginReponse.AccessTokenExpiry = refreshToken.ExpireTime;
|
loginReponse.AccessTokenExpiry = refreshToken.ExpireTime;
|
||||||
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, loginReponse);
|
return StatusCode(StatusCodes.Status200OK, loginReponse);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -295,7 +295,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
response.AccessToken = userToken;
|
response.AccessToken = userToken;
|
||||||
response.RefreshToken = refreshToken;
|
response.RefreshToken = refreshToken;
|
||||||
|
|
||||||
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, response);
|
return StatusCode(StatusCodes.Status200OK, response);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -10,7 +10,7 @@ using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Controllers.IntegretionApi
|
namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|
@ -0,0 +1,334 @@
|
||||||
|
using Asp.Versioning;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Objects.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
||||||
|
using System;
|
||||||
|
using System.DirectoryServices;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="service"></param>
|
||||||
|
/// <param name="appSettings"></param>
|
||||||
|
/// <param name="cache"></param>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
/// <param name="refreshTokenService"></param>
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[ApiVersion("1.0")]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
[Route("api/mobile/v{version:apiVersion}/auth")]
|
||||||
|
public class MobileAuthController(IUserService service, IOptions<AppSettings> appSettings, IEaseCache cache, ILogger<IntegrationAuthController> logger,
|
||||||
|
IRefreshTokenService refreshTokenService) : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
private readonly IEaseCache _cache = cache;
|
||||||
|
private readonly IUserService _service = service;
|
||||||
|
private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
|
||||||
|
private readonly AppSettings _appSettings = appSettings?.Value;
|
||||||
|
private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login using your credential data retrieve from SqlServer
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns>If login successful ValidUser: true</returns>
|
||||||
|
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
|
||||||
|
[HttpPost("Login")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(MobileAppAuthRequest))]
|
||||||
|
public async Task<IActionResult> Login([FromBody] MobileAppAuthRequest request)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(request);
|
||||||
|
|
||||||
|
AppAuthUserResponse loginReponse = new();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(request.LoginId))
|
||||||
|
{
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status417ExpectationFailed;
|
||||||
|
loginReponse.ReturnMessage.Add("Login ID is required.");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(request.Password))
|
||||||
|
{
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status417ExpectationFailed;
|
||||||
|
loginReponse.ReturnMessage.Add("Password is required.");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string ipAddress = string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#region Decrypt LoginID
|
||||||
|
|
||||||
|
string cipherSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.CipherSecretKey);
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
bool checkPwd = true;
|
||||||
|
|
||||||
|
ipAddress = Request.HttpContext.GetIpAddress();
|
||||||
|
loginReponse = await _service.LoginAsync(request: request, ipAddress: ipAddress);
|
||||||
|
|
||||||
|
if (loginReponse == null || loginReponse.UserId == 0)
|
||||||
|
{
|
||||||
|
loginReponse.LoginStatus = EnumLoginStatus.Error;
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status403Forbidden;
|
||||||
|
loginReponse.ReturnMessage.Add(checkPwd ? "Login ID/Password is invalid." : "You are not Authorized to login into the System");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loginReponse.LoginStatus == EnumLoginStatus.Unsuccessful)
|
||||||
|
{
|
||||||
|
loginReponse.LoginStatus = loginReponse.LoginStatus;
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status403Forbidden;
|
||||||
|
loginReponse.ReturnMessage.Add(checkPwd ? $"Login ID/Password is invalid for {request.LoginId}." : "You are not Authorized to login into the System");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (loginReponse.IsLocked)
|
||||||
|
{
|
||||||
|
loginReponse.LoginStatus = loginReponse.LoginStatus;
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status403Forbidden;
|
||||||
|
loginReponse.ReturnMessage.Add($"Your Account is locked . Please try again after few minutes");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loginReponse.IsAuthorized )
|
||||||
|
{
|
||||||
|
loginReponse.LoginStatus = loginReponse.LoginStatus;
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status403Forbidden;
|
||||||
|
loginReponse.ReturnMessage.Add("You are not Authorized to Login into the System, Please contact with System Administrator.");
|
||||||
|
return StatusCode(StatusCodes.Status417ExpectationFailed, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status200OK;
|
||||||
|
string pwdSecretKey = GlobalFunctions.ConvertFromBase64String(_appSettings.PwdSecretKey);
|
||||||
|
string userPwd = Ease.NetCore.Utility.Global.CipherFunctions.EncryptByAES(privateKey: pwdSecretKey, publicKey: pwdSecretKey, data: request.Password);
|
||||||
|
byte[] key = Encoding.ASCII.GetBytes(_appSettings.JwtCryptoKey);
|
||||||
|
JwtSecurityTokenHandler tokenHandler = new();
|
||||||
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Subject = new ClaimsIdentity(
|
||||||
|
[
|
||||||
|
Helper.CreateClaim("LoginId", loginReponse.LoginId),
|
||||||
|
Helper.CreateClaim("Email", loginReponse.Email),
|
||||||
|
Helper.CreateClaim("Mobile", $"{loginReponse.MobileNumber}"),
|
||||||
|
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
||||||
|
]),
|
||||||
|
Expires = DateTime.UtcNow.AddHours(12),
|
||||||
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
|
||||||
|
};
|
||||||
|
|
||||||
|
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
|
string userToken = tokenHandler.WriteToken(token);
|
||||||
|
GenerateRefreshTokenRequest refreshTokenRequest = new GenerateRefreshTokenRequest()
|
||||||
|
{
|
||||||
|
UserId = loginReponse.UserId,
|
||||||
|
IpAddress = ipAddress,
|
||||||
|
RawRefreshToken = string.Empty
|
||||||
|
};
|
||||||
|
|
||||||
|
var refreshToken = await _refreshTokenService.GenerateRefreshTokenByUserAsync(refreshTokenRequest);
|
||||||
|
|
||||||
|
//If token length is greater than or equal to 4096 (4KB) then return error
|
||||||
|
//because cookie can not store more than 4KB data and we are storing this token in cookie for authentication
|
||||||
|
if (userToken.Length >= 4096) //4Kb
|
||||||
|
{
|
||||||
|
loginReponse.LoginStatus = loginReponse.LoginStatus;
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status431RequestHeaderFieldsTooLarge;
|
||||||
|
loginReponse.ReturnMessage.Add("Authentication Token is too large for cookie.");
|
||||||
|
return StatusCode(StatusCodes.Status431RequestHeaderFieldsTooLarge, loginReponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
loginReponse.ReturnStatus = loginReponse.ReturnStatus;
|
||||||
|
loginReponse.ReturnMessage = loginReponse.ReturnMessage;
|
||||||
|
loginReponse.LoginId = loginReponse.LoginId;
|
||||||
|
loginReponse.AccessToken = userToken;
|
||||||
|
loginReponse.RefreshToken = refreshToken.RefreshToken;
|
||||||
|
loginReponse.AccessTokenExpiryTime = DateTime.UtcNow.AddHours(12);
|
||||||
|
loginReponse.RefreshTokenExpiryTime = refreshToken.ExpireTime;
|
||||||
|
return StatusCode(StatusCodes.Status200OK, loginReponse);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = $"{request?.LoginId}~{ipAddress}";
|
||||||
|
_logger.LogError(exception: ex, message: msg);
|
||||||
|
loginReponse.ReturnStatus = StatusCodes.Status500InternalServerError;
|
||||||
|
loginReponse.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, loginReponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login using your credential data retrieve from SqlServer
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns>If login successful ValidUser: true</returns>
|
||||||
|
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
|
||||||
|
[HttpPost("RefreshToken")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IntegrationLoginResponse))]
|
||||||
|
public async Task<IActionResult> GetRefreshToken([FromBody] IntegrationRefreshTokenRequest request)
|
||||||
|
{
|
||||||
|
IntegrationRrefreshTokenResponse response = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userRefreshToken = await _refreshTokenService.GetUserByRefreshTokenAsync(request.RefreshToken);
|
||||||
|
if (!userRefreshToken.IsActive)
|
||||||
|
{
|
||||||
|
string msg = $"Refresh Token is not active: {request?.RefreshToken}";
|
||||||
|
_logger.LogError(message: msg);
|
||||||
|
response.ReturnStatus = StatusCodes.Status401Unauthorized;
|
||||||
|
response.ReturnMessage.Add(msg);
|
||||||
|
return StatusCode(StatusCodes.Status401Unauthorized, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] key = Encoding.ASCII.GetBytes(_appSettings.JwtCryptoKey);
|
||||||
|
JwtSecurityTokenHandler tokenHandler = new();
|
||||||
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Subject = new ClaimsIdentity(
|
||||||
|
[
|
||||||
|
Helper.CreateClaim("LoginId", userRefreshToken.LoginId),
|
||||||
|
Helper.CreateClaim("Email", userRefreshToken.EmailAddress),
|
||||||
|
Helper.CreateClaim("AuthKey", $"{userRefreshToken.AuthKey}"),
|
||||||
|
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
||||||
|
]),
|
||||||
|
Expires = DateTime.UtcNow.AddHours(12),
|
||||||
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
|
||||||
|
};
|
||||||
|
|
||||||
|
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
|
string userToken = tokenHandler.WriteToken(token);
|
||||||
|
|
||||||
|
string ipAddress = Request.HttpContext.GetIpAddress();
|
||||||
|
var refreshToken = await _refreshTokenService.GenerateRefreshTokenAsync(request.RefreshToken, ipAddress);
|
||||||
|
|
||||||
|
response.AccessToken = userToken;
|
||||||
|
response.RefreshToken = refreshToken;
|
||||||
|
|
||||||
|
return StatusCode(StatusCodes.Status200OK, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = $"{request?.RefreshToken}";
|
||||||
|
_logger.LogError(exception: ex, message: msg);
|
||||||
|
response.ReturnStatus = StatusCodes.Status500InternalServerError;
|
||||||
|
response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login using your credential data retrieve from SqlServer
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns>If login successful ValidUser: true</returns>
|
||||||
|
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
|
||||||
|
[HttpPost("Logout")]
|
||||||
|
[Authorize]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AuthLogoutResponse))]
|
||||||
|
public async Task<IActionResult> Logout([FromBody] AuthLogoutRequest request)
|
||||||
|
{
|
||||||
|
AuthLogoutResponse response = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string ipAddress = Request.HttpContext.GetIpAddress();
|
||||||
|
response = await _service.LogoutAsync(request, ipAddress);
|
||||||
|
|
||||||
|
response.ReturnStatus = StatusCodes.Status200OK;
|
||||||
|
response.ReturnMessage.Add("Successfully Logout");
|
||||||
|
return StatusCode(StatusCodes.Status200OK, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = $"Exception occur on logout {request?.LoginId}";
|
||||||
|
_logger.LogError(exception: ex, message: msg);
|
||||||
|
response.ReturnStatus = StatusCodes.Status500InternalServerError;
|
||||||
|
response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login using your credential data retrieve from SqlServer
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns>If login successful ValidUser: true</returns>
|
||||||
|
/// <response code="200">If login successful Return ValidUser: true and UserName: not empty</response>
|
||||||
|
[HttpPost("ChangePassword")]
|
||||||
|
[Authorize]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(AppChangePasswordResponse))]
|
||||||
|
public async Task<IActionResult> ChangePassword([FromBody] AppUserChangePasswordRequest request)
|
||||||
|
{
|
||||||
|
AppChangePasswordResponse response = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string ipAddress = Request.HttpContext.GetIpAddress();
|
||||||
|
response = await _service.ChangePasswordAsync(request, ipAddress);
|
||||||
|
|
||||||
|
response.ReturnStatus = StatusCodes.Status200OK;
|
||||||
|
response.ReturnMessage.Add("Successfully Changed the Password");
|
||||||
|
return StatusCode(StatusCodes.Status200OK, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = $"Exception occur on logout {request?.LoginId}";
|
||||||
|
_logger.LogError(exception: ex, message: msg);
|
||||||
|
response.ReturnStatus = StatusCodes.Status500InternalServerError;
|
||||||
|
response.ReturnMessage.Add(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user