using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QuotifyBE.Data; using QuotifyBE.Entities; using QuotifyBE.DTOs; using System.Threading.Tasks; namespace QuotifyBE.Controllers; [ApiController] [Route("api/v1/auth")] [Produces("application/json")] public class AuthController : ControllerBase { private readonly IConfiguration _appsettings; private readonly ApplicationDbContext _db; private readonly GeneralUseHelpers guhf; public AuthController(IConfiguration appsettings, ApplicationDbContext db, GeneralUseHelpers GUHF) { _db = db; _appsettings = appsettings; guhf = GUHF; } // POST /api/v1/auth/login /// /// Log-in endpoint /// /// /// Allows to generate a JWT valid for 5 minutes. /// The token needs to be passed to other, secured endpoints /// in the Authorization header, e.g.: Authorization: bearer {jwt} /// /// User's credentials (email and password) /// JWT valid for 5 minutes. /// Returned on request with valid credentials /// Returned on request with missing form data (email, password or both) /// Returned on request with unknown pair of email and password (wrong password) /// Returned on request with unknwon email [HttpPost("login")] [ProducesResponseType(200)] [ProducesResponseType(typeof(ErrorDTO), 400)] [ProducesResponseType(typeof(ErrorDTO), 401)] [ProducesResponseType(typeof(ErrorDTO), 404)] public async Task Login([FromBody] UserLoginDTO formUser) { // Ensure the form is complete if (formUser.Email == null || formUser.Password == null) { return BadRequest(new {status = "error", error_msg = "Form contains missing data"}); } // Find the user with retrieved e-mail User? user = await guhf.GetUserFromEmail(formUser.Email); if (user == null) { return NotFound(new {status = "error", error_msg = "User not found"}); } // Hash the password and compare with the user-provided one string hashedFormPassword = guhf.HashWithSHA512(formUser.Password); if (hashedFormPassword == user.PasswordHash) { // All set - generate the token and return it var token = guhf.GenerateJwtToken(formUser.Email); return Ok(new { status = "ok", token }); } else return Unauthorized(new {status = "error", error_msg = "Unknown pair of email and password"}); } // GET /api/v1/auth/some_values /// /// Dummy, authed endpoint /// /// /// Dummy, authed endpoint used to test JWTs. /// Authed endpoints expect Authorization header, e.g.: /// Authorization: bearer {jwt} /// Dummy json /// Returned on request with valid credentials /// Returned on request with invalid JWT [HttpGet("some_values")] [Authorize] [ProducesResponseType(200)] [ProducesResponseType(401)] public IActionResult GetValues() { return Ok(new string[] { "value1", "value2" }); } }