diff --git a/src/Dto/Auth/AuthRequest.cs b/src/Dto/Auth/AuthRequest.cs new file mode 100644 index 0000000..af99599 --- /dev/null +++ b/src/Dto/Auth/AuthRequest.cs @@ -0,0 +1,13 @@ + +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; + +namespace Dto.Auth; + +public class LoginRequestDto +{ + [Required(ErrorMessage = "Username is required")] + public string Username { get; set; } + [Required(ErrorMessage = "Password is required")] + public string Password { get; set; } +} diff --git a/src/HeartTrackAPI/Controllers/AuthController.cs b/src/HeartTrackAPI/Controllers/AuthController.cs new file mode 100644 index 0000000..3b796a0 --- /dev/null +++ b/src/HeartTrackAPI/Controllers/AuthController.cs @@ -0,0 +1,152 @@ +using System.Globalization; +using Dto.Auth; +using Dto.Tiny; +using Entities; +using HeartTrackAPI.Request; +using HeartTrackAPI.Services; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace HeartTrackAPI.Controllers; +[ApiController] +public class AuthController : Controller +{ + + private readonly UserManager _userManager; + private readonly ITokenService _tokenService; + private readonly SignInManager _signinManager; + + public AuthController(UserManager userManager,ITokenService tokenService, SignInManager signinManager) + { + _userManager = userManager; + _tokenService = tokenService; + _signinManager = signinManager; + } + [HttpPost("login")] + public async Task Login(LoginRequestDto loginDto) + { + if (!ModelState.IsValid) + return BadRequest(ModelState); + + var user = await _userManager.Users.FirstOrDefaultAsync(x => x.UserName == loginDto.Username.ToLower()); + + if (user == null) return Unauthorized("Invalid username!"); + + var result = await _signinManager.CheckPasswordSignInAsync(user, loginDto.Password, false); + + if (!result.Succeeded) return Unauthorized("Username not found and/or password incorrect"); + + return Ok(new AuthResponseDto + { + AccessToken = _tokenService.CreateToken(user), + ExpiresIn = DateTime.Now.AddDays(7).ToString(CultureInfo.InvariantCulture), + TokenType = "Bearer" + } + ); + } + + [HttpPost("register")] + public async Task Register([FromBody] RegisterRequestDto request) + { + try + { + if (!ModelState.IsValid) + return BadRequest(ModelState); + // just for testing + // the good way is to use the repository and give him the userManager + var user = new AthleteEntity + { + Email = request.Email, + UserName = request.Username, + LastName = request.LastName, + FirstName = request.FirstName, + Sexe = request.Sexe, + Length = request.Size, + Weight = request.Weight, + DateOfBirth = DateOnly.FromDateTime(request.DateOfBirth), + IsCoach = request.IsCoach + }; + var createdUser = _userManager.CreateAsync(user, request.Password).Result; + if (createdUser.Succeeded) + { + var roleResult = await _userManager.AddToRoleAsync(user, request.IsCoach ? "Coach" : "Athlete"); + if (roleResult.Succeeded) + { + return Ok( + new AuthResponseDto + { + AccessToken = _tokenService.CreateToken(user), + ExpiresIn = DateTime.Now.AddDays(7).ToString(), + TokenType = "Bearer" + } + ); + } + { + return StatusCode(500, roleResult.Errors); + } + } + { + return StatusCode(500, createdUser.Errors); + } + } + catch (Exception e) + { + return StatusCode(500, e.Message); + } + + + /* var user = _userRepository.GetByEmail(request.Email); + if (user != null) + { + return BadRequest("User already exists"); + } + var newUser = new User + { + Email = request.Email, + PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.PasswordHash), + FirstName = request.FirstName, + LastName = request.LastName + }; + _userRepository.Add(newUser); + return Ok();*/ + } + /* + [HttpPost("refresh")] + public IActionResult Refresh([FromBody] RefreshRequest request) + { + var user = _userRepository.GetByEmail(request.Email); + if (user == null) + { + return Unauthorized(); + } + if (!BCrypt.Net.BCrypt.Verify(request.PasswordHash, user.PasswordHash)) + { + return Unauthorized(); + } + var token = _jwtService.GenerateToken(user); + return Ok(new { token }); + } + */ + [HttpPost("logout")] + public IActionResult Logout() + { + return Ok(); + } + /* + + [HttpPost("forgot-password")] + public IActionResult ForgotPassword([FromBody] ForgotPasswordRequest request) + { + var user = _userRepository.GetByEmail(request.Email); + if (user == null) + { + return BadRequest("User not found"); + } + var token = _jwtService.GenerateToken(user); + // send email with token + return Ok(); + }*/ + + +} \ No newline at end of file