Backend: .NET 10 Clean Architecture + LiteCqrs.Net + EF Core/PostgreSQL + Identity/JWT. Frontend: React 19 + Vite + TanStack Query/Router + Tailwind v4 with a retro CRT theme. Docker/compose deployment mirroring PnvPanel's conventions, scoped down to the current base feature set.
45 lines
1.4 KiB
C#
45 lines
1.4 KiB
C#
using LiteCqrs;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Application.Common.Models;
|
|
|
|
namespace TeleWave.Application.Auth.Refresh;
|
|
|
|
public sealed class RefreshCommandHandler(
|
|
IRefreshTokenService refreshTokenService,
|
|
IIdentityService identityService,
|
|
IJwtTokenService jwtTokenService
|
|
) : ICommandHandler<RefreshCommand, Result<AuthResult>>
|
|
{
|
|
public async Task<Result<AuthResult>> Handle(
|
|
RefreshCommand command,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
var rotated = await refreshTokenService.RotateAsync(command.RawToken, cancellationToken);
|
|
if (!rotated.IsSuccess)
|
|
return Result.Failure<AuthResult>(rotated.Error);
|
|
|
|
var profile = await identityService.GetProfileAsync(
|
|
rotated.Value.UserId,
|
|
cancellationToken
|
|
);
|
|
if (profile is null || profile.IsBlocked)
|
|
return Result.Failure<AuthResult>(AuthErrors.Unauthorized);
|
|
|
|
var (accessToken, accessExpiresAt) = jwtTokenService.GenerateAccessToken(
|
|
new AuthenticatedUser(profile.Id, profile.UserName, profile.Role)
|
|
);
|
|
|
|
var dto = new CurrentUserDto(profile.Id, profile.UserName, profile.Role);
|
|
return Result.Success(
|
|
new AuthResult(
|
|
accessToken,
|
|
accessExpiresAt,
|
|
rotated.Value.RawToken,
|
|
rotated.Value.ExpiresAt,
|
|
dto
|
|
)
|
|
);
|
|
}
|
|
}
|