using System.Security.Claims; using HelpDesk.API.Services; using HelpDesk.Data.Repositories; using HelpDesk.Models.DTOs; using HelpDesk.Models.Entities; using HelpDesk.Models.Enums; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace HelpDesk.API.Controllers; [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { private readonly IUserRepository _userRepository; private readonly IJwtService _jwtService; private readonly IPasswordService _passwordService; public AuthController(IUserRepository userRepository, IJwtService jwtService, IPasswordService passwordService) { _userRepository = userRepository; _jwtService = jwtService; _passwordService = passwordService; } [HttpPost("login")] public async Task> Login([FromBody] LoginRequest request) { if (string.IsNullOrWhiteSpace(request.Email) || string.IsNullOrWhiteSpace(request.Password)) return BadRequest(new { error = "Email and password are required." }); var user = await _userRepository.GetByEmailAsync(request.Email); if (user == null || !_passwordService.VerifyPassword(request.Password, user.PasswordHash)) return Unauthorized(new { error = "Invalid email or password." }); if (!user.IsActive) return Unauthorized(new { error = "Account is deactivated." }); var token = _jwtService.GenerateToken(user.Id, user.Email, user.Role); return Ok(new AuthResponse { Token = token, Expiration = DateTime.UtcNow.AddMinutes(60), User = MapToDto(user) }); } [HttpPost("register")] public async Task> Register([FromBody] RegisterRequest request) { if (string.IsNullOrWhiteSpace(request.Email) || string.IsNullOrWhiteSpace(request.Password)) return BadRequest(new { error = "Email and password are required." }); if (string.IsNullOrWhiteSpace(request.FirstName) || string.IsNullOrWhiteSpace(request.LastName)) return BadRequest(new { error = "First name and last name are required." }); if (request.Password.Length < 6) return BadRequest(new { error = "Password must be at least 6 characters." }); if (await _userRepository.ExistsAsync(request.Email)) return Conflict(new { error = "Email is already registered." }); var user = new User { Email = request.Email, PasswordHash = _passwordService.HashPassword(request.Password), FirstName = request.FirstName, LastName = request.LastName, Role = UserRole.Customer, CreatedAt = DateTime.UtcNow }; var created = await _userRepository.CreateAsync(user); var token = _jwtService.GenerateToken(created.Id, created.Email, created.Role); return CreatedAtAction(nameof(GetMe), new AuthResponse { Token = token, Expiration = DateTime.UtcNow.AddMinutes(60), User = MapToDto(created) }); } [Authorize] [HttpGet("me")] public async Task> GetMe() { var userId = GetUserId(); if (userId == null) return Unauthorized(); var user = await _userRepository.GetByIdAsync(userId.Value); if (user == null) return NotFound(new { error = "User not found." }); return Ok(MapToDto(user)); } private Guid? GetUserId() { var claim = User.FindFirst("userId") ?? User.FindFirst(ClaimTypes.NameIdentifier); return claim != null && Guid.TryParse(claim.Value, out var id) ? id : null; } private static UserDto MapToDto(User user) => new() { Id = user.Id, Email = user.Email, FirstName = user.FirstName, LastName = user.LastName, Role = user.Role, IsActive = user.IsActive, CreatedAt = user.CreatedAt, PhoneNumber = user.PhoneNumber, AvatarUrl = user.AvatarUrl }; }