79 lines
2.7 KiB
C#
79 lines
2.7 KiB
C#
using HashidsNet;
|
|
using JWT.Algorithms;
|
|
using JWT.Builder;
|
|
using JWT.Serializers;
|
|
using LanguageExt.Common;
|
|
using Security.Scheme;
|
|
using W542.GandalfReborn.Commands;
|
|
using W542.GandalfReborn.Data.Database.Repositories;
|
|
using W542.GandalfReborn.Data.Dto;
|
|
using W542.GandalfReborn.Data.Entities.Security;
|
|
using W542.GandalfReborn.Extensions;
|
|
using W542.GandalfReborn.Handlers.Commands;
|
|
|
|
namespace W542.GandalfReborn.Handlers.Security;
|
|
|
|
public class CreateTokensCommandHandler(TimeProvider timeProvider, IConfiguration configuration, IHashids hashids, ITokenMetadataRepository tokenMetadataRepository) : IGrCommandHandler<CreateTokensCommand, Result<TokenDto>>
|
|
{
|
|
public async Task<Result<TokenDto>> Handle(CreateTokensCommand command, CancellationToken cancellationToken)
|
|
{
|
|
var iat = timeProvider.GetUtcNow();
|
|
var accessExp = iat.AddMinutes(5);
|
|
var refreshExp = iat.AddDays(7);
|
|
|
|
var builder = JwtBuilder.Create()
|
|
.WithAlgorithm(new HMACSHA512Algorithm())
|
|
.WithSecret(configuration.GetValue<string>("JwtSecret"))
|
|
.WithJsonSerializer(new JsonNetSerializer());
|
|
|
|
var accessTokenMetadata = new TokenMetadataEntity
|
|
{
|
|
Expiration = accessExp,
|
|
IsRevoked = false,
|
|
TokenType = TokenType.User,
|
|
UsedBy = command.SubjectId
|
|
};
|
|
|
|
var refreshTokenMetadata = new TokenMetadataEntity
|
|
{
|
|
Expiration = refreshExp,
|
|
IsRevoked = false,
|
|
TokenType = TokenType.User,
|
|
UsedBy = command.SubjectId
|
|
};
|
|
|
|
var entities = await tokenMetadataRepository.Upsert([accessTokenMetadata, refreshTokenMetadata]);
|
|
|
|
if (entities.IsFaulted)
|
|
return entities.AsErrorResult<TokenDto, ICollection<TokenMetadataEntity>>();
|
|
|
|
var baseUrl = configuration.GetValue<string>("BaseUrl") ?? "https://localhost:7269";
|
|
|
|
var accessToken = builder.Encode(new GandalfRebornJwtBody
|
|
{
|
|
Id = hashids.EncodeLong(accessTokenMetadata.Id!.Value),
|
|
Sub = hashids.EncodeLong(command.SubjectId),
|
|
Iat = iat,
|
|
Exp = accessExp,
|
|
Iss = baseUrl,
|
|
Aud = baseUrl
|
|
|
|
});
|
|
|
|
var refreshToken = builder.Encode(new GandalfRebornJwtBody
|
|
{
|
|
Id = hashids.EncodeLong(refreshTokenMetadata.Id!.Value),
|
|
Sub = hashids.EncodeLong(command.SubjectId),
|
|
Iat = iat,
|
|
Exp = refreshExp,
|
|
Iss = baseUrl,
|
|
Aud = baseUrl
|
|
});
|
|
|
|
return new Result<TokenDto>(new TokenDto
|
|
{
|
|
AccessToken = accessToken,
|
|
RefreshToken = refreshToken
|
|
});
|
|
}
|
|
} |