130 lines
4.9 KiB
C#

using Marco.Pms.Model.Authentication;
using Marco.Pms.Model.Dtos;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly JwtSettings _jwtSettings;
private readonly RefreshTokenService _refreshTokenService;
string tenentId = "1";
public AuthController(UserManager<IdentityUser> userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService)
{
_userManager = userManager;
_jwtSettings = jwtSettings;
_refreshTokenService = refreshTokenService;
}
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
{
var user = await _userManager.FindByEmailAsync(loginDto.Username);
var user1 = await _userManager.Users.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username);
if (user == null || !await _userManager.CheckPasswordAsync(user, loginDto.Password))
{
return Unauthorized("Invalid username or password.");
}
var token = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings);
//var refreshToken = GenerateRefreshToken();
var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings);
return Ok(new { token, refreshToken });
}
[HttpPost("logout")]
public async Task<IActionResult> Logout([FromBody] LogoutDto logoutDto)
{
if (string.IsNullOrEmpty(logoutDto.RefreshToken))
{
return BadRequest(new { Message = "Refresh token is required" });
}
try
{
// Revoke the refresh token
bool isRevoked = await _refreshTokenService.RevokeRefreshTokenAsync(logoutDto.RefreshToken);
if (!isRevoked)
return Unauthorized(new { Message = "Invalid or expired refresh token" });
// Optional: Blacklist the access token (JWT)
string jwtToken = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
if (!string.IsNullOrEmpty(jwtToken))
{
await _refreshTokenService.BlacklistJwtTokenAsync(jwtToken);
}
return Ok(new { Message = "Logged out successfully" });
}
catch (Exception ex)
{
// _logger.LogError(ex, "Error during logout");
return StatusCode(500, new { Message = "Internal server error" });
}
}
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] RegisterDto registerDto)
{
var user = new IdentityUser { UserName = registerDto.Username, Email = registerDto.Email };
var result = await _userManager.CreateAsync(user, registerDto.Password);
if (!result.Succeeded)
{
return BadRequest(result.Errors);
}
return Ok("User registered successfully.");
}
[HttpPost("refresh-token")]
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenDto refreshTokenDto)
{
var refreshToken = await _refreshTokenService.GetRefreshToken(refreshTokenDto.RefreshToken);
if (refreshToken == null || refreshToken.ExpiryDate < DateTime.UtcNow)
{
return Unauthorized("Invalid or expired refresh token.");
}
// Mark token as used
await _refreshTokenService.MarkRefreshTokenAsUsed(refreshToken);
// Generate new JWT token and refresh token
var user = await _userManager.FindByIdAsync(refreshToken.UserId);
var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, tenentId, _jwtSettings);
var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenentId, _jwtSettings);
return Ok(new { token = newJwtToken, refreshToken = newRefreshToken });
}
[HttpPost("forgot-password")]
public async Task<IActionResult> ForgotPassword([FromBody] ForgotPasswordDto forgotPasswordDto)
{
var user = await _userManager.FindByEmailAsync(forgotPasswordDto.Email);
if (user == null) return NotFound("User not found.");
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
// Send token via email (implementation omitted)
// ...
return Ok("Password reset link sent.");
}
}
}