// Latest working register
[HttpPost]
[DisableRequestSizeLimit]
[Route("Register")]
public async Task<IActionResult> Register([FromForm] UserViewModel uvm)
{
try
{
var formCollection = await Request.ReadFormAsync();
var photo = formCollection.Files.FirstOrDefault();
var user = await _userManager.FindByEmailAsync(uvm.Email);
int lastUserID = _appDbContext.Users
.OrderByDescending(u => u.User_ID)
.Select(u => u.User_ID)
.FirstOrDefault();
// Validate Phone Number Pattern
var phoneNumberPattern = @"^\d{10}$";
bool isValidPhoneNumber = Regex.IsMatch(uvm.PhoneNumber, phoneNumberPattern);
if (!isValidPhoneNumber) return BadRequest("Enter valid 10-digit phone number.");
// Validate South African ID number
if (!IsValidSouthAfricanIDNumber(uvm.Id_Number, uvm.Date_of_Birth))
{
return BadRequest("Enter a valid South African ID number.");
}
if (user == null)
{
if (photo != null && photo.Length > 0)
{
using (var memoryStream = new MemoryStream())
{
await photo.CopyToAsync(memoryStream);
var fileBytes = memoryStream.ToArray();
string base64Image = Convert.ToBase64String(fileBytes);
user = new User
{
User_ID = lastUserID + 1,
Name = uvm.Name,
Surname = uvm.Surname,
UserName = uvm.Email,
Email = uvm.Email,
PasswordHash = _userManager.PasswordHasher.HashPassword(null, uvm.Password),
User_Status_ID = uvm.User_Status_ID,
User_Type_ID = uvm.User_Type_ID,
PhoneNumber = uvm.PhoneNumber,
Date_of_Birth = uvm.Date_of_Birth,
ID_Number = uvm.Id_Number,
Physical_Address = uvm.Physical_Address,
Photo = base64Image // Store the base64 string of the photo
};
IdentityResult result = await _userManager.CreateAsync(user);
if (result.Succeeded)
{
// Assign role based on User_Type_ID
string roleName = GetRoleNameByUserType(uvm.User_Type_ID);
if (!string.IsNullOrEmpty(roleName))
{
var roleResult = await _userManager.AddToRoleAsync(user, roleName);
if (!roleResult.Succeeded)
{
return BadRequest(new { Status = "Error", Errors = roleResult.Errors });
}
}
return Ok(new { Status = "Success", Message = "User created successfully!" });
}
else
{
return StatusCode(StatusCodes.Status500InternalServerError, result.Errors.FirstOrDefault()?.Description);
}
}
}
else
{
return BadRequest("Photo is required.");
}
}
else
{
return Forbid("Account already exists.");
}
}
catch (DbUpdateException dbEx)
{
return StatusCode(StatusCodes.Status500InternalServerError, dbEx.InnerException?.Message ?? "An error occurred while processing your request.");
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request.");
}
}
// Method to validate South African ID number
private bool IsValidSouthAfricanIDNumber(string idNumber, DateTime dateOfBirth)
{
// Check if the ID number is exactly 13 digits long
if (idNumber.Length != 13 || !long.TryParse(idNumber, out _))
{
return false;
}
// Validate date of birth (first six digits)
string dateOfBirthPart = idNumber.Substring(0, 6);
if (!DateTime.TryParseExact(dateOfBirthPart, "yyMMdd", null, System.Globalization.DateTimeStyles.None, out DateTime parsedDate))
{
return false;
}
// Check if the last two digits of the ID number match the last two digits of the year of birth
if (parsedDate.Year % 100 != dateOfBirth.Year % 100)
{
return false;
}
// If it passes the length, date of birth, and year checks, it is considered valid
return true;
}
private string GetRoleNameByUserType(int userTypeId)
{
return userTypeId switch
{
1 => "Administrator",
2 => "Employee",
3 => "Member",
_ => string.Empty,
};
}
//untested login
[HttpPost]
[Route("Login")]
public async Task<ActionResult> Login(LoginViewModel lv)
{
var user = await _userManager.FindByNameAsync(lv.Email);
if (user != null && await _userManager.CheckPasswordAsync(user, lv.Password))
{
try
{
var principal = await _claimsPrincipalFactory.CreateAsync(user);
return await GenerateJWTToken(user);
}
catch (Exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, "Internal Server Error. Please contact support.");
}
}
else
{
return NotFound("Incorrect email or password, Please Try Again");
}
}
[HttpGet]
private async Task<ActionResult> GenerateJWTToken(User user)
{
var role = await _userManager.GetRolesAsync(user);
IdentityOptions _identityOptions = new IdentityOptions();
// Create JWT Token
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
// Add user ID claim
new Claim("userId", user.Id.ToString()),
new Claim("User_Type_ID", user.User_Type_ID.ToString()),
};
if (role.Count() > 0)
{
claims.Add(new Claim(_identityOptions.ClaimsIdentity.RoleClaimType, role.FirstOrDefault()));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"]));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _configuration["Tokens:Issuer"],
audience: _configuration["Tokens:Audience"],
claims: claims,
signingCredentials: credentials,
expires: DateTime.UtcNow.AddHours(3)
);
return Created("", new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
user = user.UserName,
userTypeId = user.User_Type_ID,
// Include user ID in the response
userId = user.Id
});
}
//latest working editUser before base64
[HttpPut]
[Route("editUser/{id}")]
public async Task<IActionResult> EditUser(int id, UpdateUserViewModel uv)
{
try
{
var user = await _userManager.FindByIdAsync(id.ToString());
if (user == null)
{
return NotFound("User not found.");
}
user.Name = uv.Name;
user.Surname = uv.Surname;
user.Email = uv.Email;
user.Physical_Address = uv.Physical_Address;
user.PhoneNumber = uv.PhoneNumber;
user.Photo = uv.Photo;
// Update the user
var result = await _userManager.UpdateAsync(user);
if (result.Succeeded)
{
return Ok("User updated successfully.");
}
else
{
return BadRequest(result.Errors);
}
}
catch (Exception)
{
return BadRequest("An Error Occured, Please Try Again");
}
}
//latest working getUserById before base64
[HttpGet]
[Route("getUserById/{id}")]
public async Task<IActionResult> GetUserById(int id)
{
try
{
var user = await _userManager.FindByIdAsync(id.ToString());
if (user == null)
{
return NotFound("User not found.");
}
// Map User entity to UserViewModel or return the User entity directly
var userViewModel = new UserViewModel
{
Name = user.Name,
Surname = user.Surname,
Email = user.Email,
Physical_Address = user.Physical_Address,
PhoneNumber = user.PhoneNumber,
//Photo = user.Photo,
Date_of_Birth = user.Date_of_Birth,
User_Status_ID = user.User_Status_ID,
User_Type_ID = user.User_Type_ID,
Id_Number = user.ID_Number
};
return Ok(userViewModel);
}
catch (Exception)
{
return BadRequest("Try again");
}
}