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("[controller]")] public class AuthenticationController : Controller { private readonly UserManager _userManager; private readonly IConfiguration _configuration; private readonly ApplicationDbContext _db; public AuthenticationController(UserManager userManager, IConfiguration configuration, ApplicationDbContext db, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContext) { _userManager = userManager; _configuration = configuration; _db = db; } [AllowAnonymous] [HttpPost] [Route("login")] public async Task 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 { 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 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 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 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 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 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 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 } }