feat: introduce Shared.Contracts for account management and refactor related services

This commit is contained in:
2025-12-13 13:48:05 +03:30
parent c059066b13
commit 9469a5f76e
50 changed files with 520 additions and 1622 deletions

View File

@@ -1,141 +0,0 @@
using GozareshgirProgramManager.Application._Common.Interfaces;
using GozareshgirProgramManager.Application._Common.Models;
using GozareshgirProgramManager.Application.Modules.Users.Commands.LoginUser;
using GozareshgirProgramManager.Application.Modules.Users.Commands.RefreshUserToken;
using GozareshgirProgramManager.Application.Modules.Users.Commands.SignOutUser;
using GozareshgirProgramManager.Application.Modules.Users.Commands.SsoLogin;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
namespace ServiceHost.Areas.Admin.Controllers.ProgramManager;
/// <summary>
/// کنترلر احراز هویت
/// </summary>
public class AuthController : ProgramManagerBaseController
{
private readonly IAuthHelper _authHelper;
private readonly IMediator _mediator;
public AuthController(IAuthHelper authHelper, IMediator mediator)
{
_authHelper = authHelper;
_mediator = mediator;
}
/// <summary>
/// ورود به سیستم با شناسه کاربری
/// </summary>
/// <param name="request">شناسه کاربر</param>
/// <returns>فقط Access Token - Refresh Token در سرور ذخیره می‌شود</returns>
[HttpPost("login")]
[AllowAnonymous]
public async Task<ActionResult<OperationResult<LoginResponse>>> Login([FromBody] LoginByIdRequest request)
{
var command = new LoginUserCommand(request.UserId);
var result = await _mediator.Send(command);
return result;
}
/// <summary>
/// ورود به سیستم از طریق SSO با استفاده از توکن JWT
/// توکن JWT از query string دریافت می‌شود و Claims آن استخراج می‌شود
/// سپس کاربر بر اساس AccountId موجود در Claims لاگین می‌شود
/// </summary>
/// <param name="token">JWT Token از سیستم خارجی</param>
/// <returns>Access Token و اطلاعات کاربر</returns>
[HttpGet("sso-login")]
[AllowAnonymous]
public async Task<ActionResult<OperationResult<LoginResponse>>> SsoLogin([FromQuery] string token)
{
if (string.IsNullOrWhiteSpace(token))
{
return BadRequest(OperationResult<LoginResponse>.Failure("توکن الزامی است", ErrorType.BadRequest));
}
var command = new SsoLoginCommand(token);
var result = await _mediator.Send(command);
return result;
}
/// <summary>
/// خروج از سیستم
/// </summary>
[HttpPost("signout")]
[Authorize]
public new async Task<ActionResult<OperationResult>> SignOut()
{
// دریافت Refresh Token از Header با استفاده از AuthHelper
var refreshToken = _authHelper.GetRefreshTokenFromCookie();
if (string.IsNullOrEmpty(refreshToken))
{
return OperationResult.Failure("توکن تازه‌سازی یافت نشد");
}
var command = new SignOutUserCommand(refreshToken);
var result = await _mediator.Send(command);
if (result.IsSuccess)
{
return Ok(result);
}
return StatusCode(result.ErrorType switch
{
ErrorType.Unauthorized => 401,
ErrorType.BadRequest => 400,
ErrorType.NotFound => 404,
_ => 500
}, result);
}
/// <summary>
/// تازه‌سازی توکن دسترسی
/// توکن منقضی شده را می‌گیرد و Access Token جدید برمی‌گرداند
/// Refresh Token از دیتابیس خوانده می‌شود و به فرانت داده نمی‌شود
/// </summary>
[HttpPost("refresh")]
[AllowAnonymous]
public async Task<ActionResult<OperationResult>> RefreshAccessToken()
{
var refreshTokenCommand = new RefreshUserTokenCommand();
var result = await _mediator.Send(refreshTokenCommand);
return result;
}
/// <summary>
/// دریافت اطلاعات کاربر جاری
/// </summary>
[HttpGet("current")]
public IActionResult GetCurrentUser()
{
if (!_authHelper.IsAuthenticated())
{
return Unauthorized(new { message = "کاربر احراز هویت نشده است" });
}
return Ok(new
{
userId = _authHelper.GetCurrentUserId(),
fullName= _authHelper.GetCurrentFullName(),
roles = _authHelper.GetCurrentUserRoles()
});
}
}
/// <summary>
/// درخواست ورود با شناسه کاربری
/// </summary>
public class LoginByIdRequest
{
public long UserId { get; set; }
}