using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using FinControl.Domain.Repositories; namespace FinControl.API.Controllers; [ApiController] [Route("api/[controller]")] public class LoginController : ControllerBase { private readonly IUserRepository _userRepository; private readonly IConfiguration _configuration; private const string SecretKey = "your-super-secret-key-that-is-at-least-32-characters-long!!!"; public LoginController(IUserRepository userRepository, IConfiguration configuration) { _userRepository = userRepository; _configuration = configuration; } [HttpPost] public async Task Login([FromBody] LoginRequest request) { // Validar entrada if (string.IsNullOrEmpty(request.Email) || string.IsNullOrEmpty(request.Password)) return BadRequest(new { message = "Email e senha são obrigatórios" }); // Buscar usuário por email var users = await _userRepository.GetAllAsync(); var user = users.FirstOrDefault(u => u.Email == request.Email); if (user == null) return Unauthorized(new { message = "Email ou senha inválidos" }); // Validar senha if (!BCrypt.Net.BCrypt.Verify(request.Password, user.PasswordHash)) return Unauthorized(new { message = "Email ou senha inválidos" }); // Gerar token JWT var token = GenerateJwtToken(user.Id, user.Email, user.Name); return Ok(new { token = token, user = new { id = user.Id, name = user.Name, email = user.Email } }); } [HttpPost("register")] public async Task Register([FromBody] RegisterRequest request) { // Validar entrada if (string.IsNullOrEmpty(request.Name) || string.IsNullOrEmpty(request.Email) || string.IsNullOrEmpty(request.Password)) return BadRequest(new { message = "Nome, email e senha são obrigatórios" }); if (request.Password.Length < 6) return BadRequest(new { message = "A senha deve ter no mínimo 6 caracteres" }); // Verificar se email já existe var users = await _userRepository.GetAllAsync(); if (users.Any(u => u.Email == request.Email)) return BadRequest(new { message = "Este email já está cadastrado" }); // Criar novo usuário var newUser = new FinControl.Domain.Entities.User { Id = Guid.NewGuid(), Name = request.Name, Email = request.Email, PasswordHash = BCrypt.Net.BCrypt.HashPassword(request.Password), CreatedAt = DateTime.UtcNow }; await _userRepository.AddAsync(newUser); // Gerar token var token = GenerateJwtToken(newUser.Id, newUser.Email, newUser.Name); return Created(string.Empty, new { token = token, user = new { id = newUser.Id, name = newUser.Name, email = newUser.Email } }); } private string GenerateJwtToken(Guid userId, string email, string name) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId.ToString()), new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Name, name) }; var token = new JwtSecurityToken( issuer: "FinControl", audience: "FinControlUsers", claims: claims, expires: DateTime.UtcNow.AddDays(7), signingCredentials: creds ); return new JwtSecurityTokenHandler().WriteToken(token); } } public class LoginRequest { public string? Email { get; set; } public string? Password { get; set; } } public class RegisterRequest { public string? Name { get; set; } public string? Email { get; set; } public string? Password { get; set; } }