using MediatR; using Microsoft.AspNetCore.Http; using Modules.User.Application.Gateways; using Modules.User.Application.Models; namespace Modules.User.Application.Commands; public class RefreshTokensCommand : IRequest { public string? Ip { get; set; } public HttpResponse Response { get; set; } = default!; public string? CookiePath { get; set; } } public class RefreshTokensCommandHandler(UserContext userContext, IAccountGateway accountGateway, IUserGateway userGateway, TokenGenerator tokenGenerator) : IRequestHandler { public async Task Handle(RefreshTokensCommand request, CancellationToken cancellationToken) { var refreshToken = userContext.GetRefreshToken(); if (refreshToken == null) { return null; } else { var session = await accountGateway.TryGetSession(refreshToken); if (session == null) return null; var user = await userGateway.Get(session.AccountId); if (user == null) return null; var userAgent = userContext.GetUserAgent(); var location = await userContext.GetLocation(request.Ip); var jwtSettings = userContext.GetJwtSettings(); var newRefreshToken = user.Account.UpdateRefreshToken(session.Id, tokenGenerator, jwtSettings.RefreshTokenExpireTime, userAgent, location?.Country, location?.Region); await accountGateway.UpdateSessions(user.Account.Id, user.Account.Sessions.Select(q => new Session { Id = q.Id, RefreshToken = q.RefreshToken, ClientInfo = new ClientInfo { UserAgent = q.ClientInfo.UserAgent, Location = new Location { Country = q.ClientInfo.Country, Region = q.ClientInfo.Region, } }, AccountId = q.AccountId, ExpiredDate = q.ExpiredDate, })); if (newRefreshToken == null) return null; var accessToken = tokenGenerator.GenerateAccessToken(user, user.Account.Sessions.First(q => q.Id == session.Id)!, jwtSettings); TokenGenerator.SetRefreshTokenInCookie(request.Response, request.CookiePath, newRefreshToken, user.Account.Sessions.First(q => q.Id == session.Id).ExpiredDate); return new() { AccessToken = accessToken, SessionExpireDate = session.ExpiredDate, }; } } }