using System.Security.Claims; using LctMonolith.Models; using LctMonolith.Services; using LctMonolith.Services.Contracts; using LctMonolith.Services.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.Data; using Microsoft.AspNetCore.Mvc; using RefreshRequest = LctMonolith.Services.Models.RefreshRequest; namespace LctMonolith.Controllers; /// /// Authentication endpoints (mocked local identity + JWT issuing). /// [ApiController] [Route("api/auth")] public class AuthController : ControllerBase { private readonly UserManager _userManager; private readonly SignInManager _signInManager; private readonly ITokenService _tokenService; public AuthController(UserManager userManager, SignInManager signInManager, ITokenService tokenService) { _userManager = userManager; _signInManager = signInManager; _tokenService = tokenService; } /// Registers a new user (simplified). [HttpPost("register")] [AllowAnonymous] public async Task> Register(AuthRequest req, CancellationToken ct) { var existing = await _userManager.FindByEmailAsync(req.Email); if (existing != null) return Conflict("Email already registered"); var user = new AppUser { UserName = req.Email, Email = req.Email, FirstName = req.FirstName, LastName = req.LastName }; var result = await _userManager.CreateAsync(user, req.Password); if (!result.Succeeded) return BadRequest(result.Errors); var tokens = await _tokenService.IssueAsync(user, ct); return Ok(tokens); } /// Login with email + password. [HttpPost("login")] [AllowAnonymous] public async Task> Login(AuthRequest req, CancellationToken ct) { var user = await _userManager.FindByEmailAsync(req.Email); if (user == null) return Unauthorized(); var passOk = await _signInManager.CheckPasswordSignInAsync(user, req.Password, lockoutOnFailure: false); if (!passOk.Succeeded) return Unauthorized(); var tokens = await _tokenService.IssueAsync(user, ct); return Ok(tokens); } /// Refresh access token by refresh token. [HttpPost("refresh")] [AllowAnonymous] public async Task> Refresh(RefreshRequest req, CancellationToken ct) { var pair = await _tokenService.RefreshAsync(req.RefreshToken, ct); return Ok(pair); } /// Revoke refresh token (logout). [HttpPost("revoke")] [Authorize] public async Task Revoke(RevokeRequest req, CancellationToken ct) { await _tokenService.RevokeAsync(req.RefreshToken, ct); return NoContent(); } /// Returns current user id (debug). [HttpGet("me")] [Authorize] public ActionResult Me() { var id = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue(ClaimTypes.Name); return Ok(new { userId = id }); } }