mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 11:53:12 +00:00
- Reorder null check: check user != null before accessing user.IsDeleted - Increase password reset code from 4 digits to 6 digits (10K to 1M combinations)
221 lines
8.9 KiB
C#
221 lines
8.9 KiB
C#
using Data.SeaHavenIndustries;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
using Api.SeaHavenIndustries.DTOs;
|
|
using Api.SeaHavenIndustries.Helper;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Api.SeaHavenIndustries.Controllers
|
|
{
|
|
[ApiController]
|
|
[Route("api/Authentication")]
|
|
public class AuthenticationController : Controller
|
|
{
|
|
private readonly UserManager<ApplicationUser> _userManager;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly ApplicationDbContext _db;
|
|
private readonly SendMessage _sendMessage;
|
|
|
|
public AuthenticationController(UserManager<ApplicationUser> userManager, IConfiguration configuration, ApplicationDbContext db, SendMessage sendMessage)
|
|
{
|
|
_userManager = userManager;
|
|
_configuration = configuration;
|
|
_db = db;
|
|
_sendMessage = sendMessage;
|
|
}
|
|
|
|
[AllowAnonymous]
|
|
[HttpPost]
|
|
[Route("login")]
|
|
public async Task<IActionResult> Login([FromBody] LoginModel model)
|
|
{
|
|
var user = await _userManager.FindByNameAsync(model.Username ?? "");
|
|
if (user != null && user.IsDeleted != true && await _userManager.CheckPasswordAsync(user, model.Password ?? ""))
|
|
{
|
|
// Standard login without 2FA
|
|
var userRoles = await _userManager.GetRolesAsync(user);
|
|
var authClaims = new List<Claim>
|
|
{
|
|
new Claim(ClaimTypes.Name, user.UserName ?? ""),
|
|
new Claim(ClaimTypes.NameIdentifier, user.Id),
|
|
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
|
};
|
|
foreach (var userRole in userRoles)
|
|
{
|
|
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
|
|
}
|
|
var token = GetToken(authClaims);
|
|
return Ok(new
|
|
{
|
|
token = new JwtSecurityTokenHandler().WriteToken(token),
|
|
expiration = token.ValidTo,
|
|
email = user.Email,
|
|
userRoles = userRoles.FirstOrDefault(),
|
|
phoneNumber = user.PhoneNumber,
|
|
fullname = user.FirstName + " " + user.LastName,
|
|
id = user.Id
|
|
});
|
|
}
|
|
|
|
// Invalid credentials
|
|
return Unauthorized();
|
|
}
|
|
|
|
[Route("ChangePassword")]
|
|
[HttpPost]
|
|
public async Task<IActionResult> ChangePassword(ChangePasswords usermodel)
|
|
{
|
|
var userid = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? "";
|
|
var user = await _userManager.FindByIdAsync(userid);
|
|
var result = await _userManager.ChangePasswordAsync(user, usermodel.Currentpassword ?? "", usermodel.Confirmpassword ?? "");
|
|
if (result.Succeeded)
|
|
{
|
|
return Ok(new Response { Status = "Success ", Message = "Password successfully changed" });
|
|
}
|
|
else
|
|
return BadRequest(new Response { Status = "Old Password is incorrect" });
|
|
}
|
|
|
|
private JwtSecurityToken GetToken(List<Claim> authClaims)
|
|
{
|
|
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"] ?? ""));
|
|
var token = new JwtSecurityToken(
|
|
issuer: _configuration["JWT:ValidIssuer"],
|
|
audience: _configuration["JWT:ValidAudience"],
|
|
expires: DateTime.Now.AddDays(10),
|
|
claims: authClaims,
|
|
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
|
|
);
|
|
return token;
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("UpdateProfile")]
|
|
public async Task<IActionResult> UserProfileUpdate([FromForm] User_DTO model)
|
|
{
|
|
try
|
|
{
|
|
var userid = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? "";
|
|
ApplicationUser appuser = _db.Users.AsNoTracking().Where(u => u.Id == userid).FirstOrDefault() ?? new ApplicationUser();
|
|
appuser.FirstName = model.Name;
|
|
appuser.Email = model.Email;
|
|
appuser.Contact = model.Contact;
|
|
_db.Users.Update(appuser);
|
|
await _db.SaveChangesAsync();
|
|
|
|
return Ok(new DataResponse
|
|
{
|
|
Message = "Introduction Updated Successfully",
|
|
Status = "200",
|
|
Data = _db.Users.Where(u => u.Id == userid).Select(s => new
|
|
{
|
|
s.FirstName,
|
|
//s.Location,
|
|
s.Email,
|
|
s.Contact
|
|
}).FirstOrDefault()
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest(new Response { Status = "Error", Message = ex.Message });
|
|
}
|
|
}
|
|
|
|
#region Forget Password Area
|
|
|
|
[AllowAnonymous]
|
|
[HttpPost()]
|
|
[Route("ForgetPassword")]
|
|
public async Task<IActionResult> ForgetPassword(string Email)
|
|
{
|
|
var user = await _db.Users.Where(u => u.Email.ToLower().Trim() == Email.ToLower().ToLower()).FirstOrDefaultAsync();
|
|
if (user != null)
|
|
{
|
|
if (_db.ForgetPasswordCodes.Where(u => u.Email.ToLower().Trim() == Email.ToLower().Trim()).Any())
|
|
{
|
|
_db.ForgetPasswordCodes.Remove(_db.ForgetPasswordCodes.Where(u => u.Email.ToLower().Trim() == Email.ToLower().Trim()).FirstOrDefault());
|
|
_db.SaveChanges();
|
|
}
|
|
ForgetPasswordCode forgetPasswordCode = new ForgetPasswordCode();
|
|
forgetPasswordCode.Email = user.Email ?? "";
|
|
forgetPasswordCode.UserId = user.Id;
|
|
forgetPasswordCode.Code = GenerateRandomNo();
|
|
|
|
_db.ForgetPasswordCodes.Add(forgetPasswordCode);
|
|
_db.SaveChanges();
|
|
string body = $"Your Password Reset Code is: " + forgetPasswordCode.Code;
|
|
await _sendMessage.SendEMail(user.Email, "Forget Password Request.", body);
|
|
return Ok(new Response { Status = "Success ", Message = "Please check your email for code" });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest(new Response { Status = "Error", Message = "No such email is registered" });
|
|
}
|
|
}
|
|
//need email and code
|
|
[AllowAnonymous]
|
|
[HttpPost()]
|
|
[Route("VerificationCode")]
|
|
public async Task<IActionResult> VerificationCode(string code)
|
|
{
|
|
try
|
|
{
|
|
if (await _db.ForgetPasswordCodes.Where(u => u.Code == code).AnyAsync())
|
|
{
|
|
|
|
return Ok(new Response { Status = "Success ", Message = "Code Matched" });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest(new Response { Status = "Error", Message = "Code Not Matched" });
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest(new Response { Status = "Error", Message = "Error: " + ex.Message });
|
|
}
|
|
}
|
|
|
|
// need email, password and code
|
|
[AllowAnonymous]
|
|
[HttpPost()]
|
|
[Route("ResetPassword")]
|
|
public async Task<IActionResult> ResetPassword(ForgetPassword_Dto fpdto)
|
|
{
|
|
try
|
|
{
|
|
if (_db.ForgetPasswordCodes.Where(u => u.Email.ToLower().Trim() == fpdto.Email.ToLower().Trim() && u.Code == fpdto.Code.Trim()).Any())
|
|
{
|
|
var GetUser = _db.ForgetPasswordCodes.Where(u => u.Email.ToLower().Trim() == fpdto.Email.ToLower().Trim()).FirstOrDefault();
|
|
var user = await _userManager.FindByIdAsync(GetUser.UserId);
|
|
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
|
|
var result = await _userManager.ResetPasswordAsync(user, token, fpdto.Password);
|
|
return Ok(new Response { Status = "Success ", Message = "password changed" });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest(new Response { Status = "Error", Message = "Your email or code not found please check" });
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
return BadRequest(new Response { Status = "Error", Message = "Error: " + ex.Message });
|
|
|
|
}
|
|
}
|
|
|
|
private Random _random = new Random();
|
|
private string GenerateRandomNo()
|
|
{
|
|
return _random.Next(0, 999999).ToString("D6");
|
|
}
|
|
#endregion
|
|
}
|
|
}
|