shoc-backend/Api.SeaHavenIndustries/Controllers/AuthenticationController.cs
2025-02-18 13:13:33 -06:00

253 lines
10 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.Net.Mail;
using System.Net;
using System.Security.Claims;
using System.Text;
using Api.SeaHavenIndustries.DTOs;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
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;
public AuthenticationController(UserManager<ApplicationUser> userManager, IConfiguration configuration, ApplicationDbContext db, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContext)
{
_userManager = userManager;
_configuration = configuration;
_db = db;
}
[AllowAnonymous]
[HttpPost]
[Route("login")]
public async Task<IActionResult> Login([FromBody] LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.Username ?? "");
if (user.IsDeleted != true && user != null && 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;
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 });
}
}
[HttpGet()]
public bool SendEMail(string emailid, string subject, string body)
{
try
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("infoesquall@codevoir.com"); //IMPORTANT: This must be same as your smtp authentication address.
mail.To.Add(emailid);
//set the content
mail.Subject = subject;
mail.Body = body;
mail.IsBodyHtml = true;
//send the message
SmtpClient smtp = new SmtpClient("mail.codevoir.com");
//IMPORANT: Your smtp login email MUST be same as your FROM address.
NetworkCredential Credentials = new NetworkCredential("infoesquall@codevoir.com", "Abc123!@#");
smtp.UseDefaultCredentials = false;
smtp.Credentials = Credentials;
smtp.Port = 8889; //25 alternative port number is 8889
smtp.EnableSsl = false;
smtp.Send(mail);
return true;
}
catch (Exception ex)
{
return false;
}
}
private Random _random = new Random();
private string GenerateRandomNo()
{
return _random.Next(0, 9999).ToString("D4");
}
#endregion
}
}