MyBookmark/Modules.User.Application/Commands/User/RefreshTokensCommand.cs

53 lines
2.5 KiB
C#

using MediatR;
using Microsoft.AspNetCore.Http;
using Modules.User.Application.Errors;
using Modules.User.Application.Gateways;
using Modules.User.Application.Models;
namespace Modules.User.Application.Commands;
public class RefreshTokensCommand : IRequest<AuthenticationResult?>
{
public string? Ip { get; set; }
public HttpResponse Response { get; set; } = default!;
public string? CookiePath { get; set; }
}
public class RefreshTokensCommandHandler(UserContext userContext, IUserRepository userRepository, IAccountAccessQueries accessQueries,
IUnitOfWork unitOfWork) : IRequestHandler<RefreshTokensCommand, AuthenticationResult?>
{
public async Task<AuthenticationResult?> Handle(RefreshTokensCommand request, CancellationToken cancellationToken)
{
var accountId = userContext.GetAccountId();
if (!accountId.HasValue) return null;
var oldRefreshToken = userContext.GetRefreshToken();
var user = await userRepository.GetByAccountIdAsync(accountId.Value, cancellationToken)
?? throw new AccountException();
var now = DateTime.UtcNow;
var status = user.Account.GetBanStatus(now);
if (status.IsBanned) throw new AccountBannedException(status.ReleaseDate);
var jwtSettings = userContext.GetJwtSettings();
var userAgent = userContext.GetUserAgent();
var location = await userContext.GetLocation(request.Ip);
var newRefreshToken = TokenGenerator.GenerateRefreshToken();
var expiresAt = now.Add(jwtSettings.RefreshTokenExpireTime);
var clientInfo = Domain.Entities.User.ClientInfo.Create(userAgent, location?.Country, location?.Region);
var session = user.AddOrUpdateSession(oldRefreshToken, newRefreshToken, expiresAt, clientInfo);
await userRepository.SaveAsync(user, cancellationToken);
await unitOfWork.SaveChangesAsync(cancellationToken);
var roleNames = await accessQueries.GetRoleNamesAsync(user.Account.Id, cancellationToken);
var permissionNames = await accessQueries.GetPermissionNamesAsync(user.Account.Id, cancellationToken);
var permissionCodes = await accessQueries.GetEffectivePermissionCodesAsync(user.Account.Id, cancellationToken);
var newAccessToken = TokenGenerator.GenerateAccessToken(user, session, jwtSettings,
roleNames, permissionNames, permissionCodes);
return new AuthenticationResult { AccessToken = newAccessToken, SessionExpireDate = session.ExpiredDateUtc, };
}
}