diff --git a/TimetableDesigner.Backend.Services.Authentication.Core/Commands/AuthPassword/AuthPasswordHandler.cs b/TimetableDesigner.Backend.Services.Authentication.Core/Commands/AuthPassword/AuthPasswordHandler.cs index fca35bd..f56b20d 100644 --- a/TimetableDesigner.Backend.Services.Authentication.Core/Commands/AuthPassword/AuthPasswordHandler.cs +++ b/TimetableDesigner.Backend.Services.Authentication.Core/Commands/AuthPassword/AuthPasswordHandler.cs @@ -10,13 +10,13 @@ public class AuthPasswordHandler : IRequestHandler Handle(AuthPasswordCommand request, CancellationToken cancellationToken) @@ -33,10 +33,17 @@ public class AuthPasswordHandler : IRequestHandler { private readonly DatabaseContext _databaseContext; - private readonly IAccessTokenGenerator _accessTokenGenerator; + private readonly ITokenHelper _tokenHelper; - public AuthTokenHandler(DatabaseContext databaseContext, IAccessTokenGenerator accessTokenGenerator) + public AuthTokenHandler(DatabaseContext databaseContext, ITokenHelper tokenHelper) { _databaseContext = databaseContext; - _accessTokenGenerator = accessTokenGenerator; + _tokenHelper = tokenHelper; } public async Task Handle(AuthTokenCommand request, CancellationToken cancellationToken) { - RefreshToken? token = await _databaseContext.RefreshTokens + RefreshToken? refreshToken = await _databaseContext.RefreshTokens .Include(x => x.Account) .FirstOrDefaultAsync(x => x.Token == Guid.Parse(request.RefreshToken), cancellationToken); - if (token is null || token.ExpirationDate < DateTimeOffset.UtcNow || !_accessTokenGenerator.ValidateExpiredAccessToken(request.AccessToken)) + if (refreshToken is null || refreshToken.ExpirationDate < DateTimeOffset.UtcNow || !_tokenHelper.ValidateExpiredAccessToken(request.AccessToken)) { return AuthTokenResult.Failure(); } - string accessToken = _accessTokenGenerator.GenerateAccessToken(token.Account); - if (token.IsExtendable) - { - - } + string accessToken = _tokenHelper.GenerateAccessToken(refreshToken.Account.Id); + if (refreshToken.IsExtendable) + { + refreshToken.ExpirationDate = _tokenHelper.CalculateRefreshTokenExpirationDate(); + await _databaseContext.SaveChangesAsync(cancellationToken); + } - return AuthTokenResult.Success(refreshToken, accessToken); + return AuthTokenResult.Success(accessToken, refreshToken.Token.ToString()); } } \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/IAccessTokenGenerator.cs b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/ITokenHelper.cs similarity index 56% rename from TimetableDesigner.Backend.Services.Authentication.Core/Helpers/IAccessTokenGenerator.cs rename to TimetableDesigner.Backend.Services.Authentication.Core/Helpers/ITokenHelper.cs index 66fc148..b0078b2 100644 --- a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/IAccessTokenGenerator.cs +++ b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/ITokenHelper.cs @@ -2,9 +2,9 @@ namespace TimetableDesigner.Backend.Services.Authentication.Core.Helpers; -public interface IAccessTokenGenerator +public interface ITokenHelper { - string GenerateAccessToken(Account account); - RefreshToken GenerateRefreshToken(bool isExtendable); + string GenerateAccessToken(long accountId); bool ValidateExpiredAccessToken(string accessToken); + DateTimeOffset CalculateRefreshTokenExpirationDate(bool isExtendable = true); } \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHashData.cs b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHashData.cs deleted file mode 100644 index e3cc9c4..0000000 --- a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHashData.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace TimetableDesigner.Backend.Services.Authentication.Core.Helpers; - -public record PasswordHashData( - byte[] Hash, - string Salt -); \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHasher.cs b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHasher.cs index 7da724c..10ec3ee 100644 --- a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHasher.cs +++ b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/PasswordHasher.cs @@ -36,4 +36,9 @@ public class PasswordHasher : IPasswordHasher byte[] hash = hashFunction.GetBytes(32); return hash; } -} \ No newline at end of file +} + +public record PasswordHashData( + byte[] Hash, + string Salt +); \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/AccessTokenGenerator.cs b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/TokenHelper.cs similarity index 84% rename from TimetableDesigner.Backend.Services.Authentication.Core/Helpers/AccessTokenGenerator.cs rename to TimetableDesigner.Backend.Services.Authentication.Core/Helpers/TokenHelper.cs index 3c79d14..d336de4 100644 --- a/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/AccessTokenGenerator.cs +++ b/TimetableDesigner.Backend.Services.Authentication.Core/Helpers/TokenHelper.cs @@ -9,18 +9,16 @@ using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegiste namespace TimetableDesigner.Backend.Services.Authentication.Core.Helpers; -public class AccessTokenGenerator : IAccessTokenGenerator +public class TokenHelper : ITokenHelper { private readonly IConfiguration _configuration; - private readonly DatabaseContext _databaseContext; - public AccessTokenGenerator(IConfiguration configuration, DatabaseContext databaseContext) + public TokenHelper(IConfiguration configuration) { _configuration = configuration; - _databaseContext = databaseContext; } - public string GenerateAccessToken(Account account) + public string GenerateAccessToken(long accountId) { IConfigurationSection accessTokenSettings = _configuration.GetSection("Tokens") .GetSection("AccessToken"); @@ -40,7 +38,7 @@ public class AccessTokenGenerator : IAccessTokenGenerator Subject = new ClaimsIdentity( [ new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), - new Claim(JwtRegisteredClaimNames.Sub, account.Id.ToString()), + new Claim(JwtRegisteredClaimNames.Sub, accountId.ToString()), new Claim(JwtRegisteredClaimNames.Exp, expirationDate.UtcTicks.ToString()) ]), Issuer = accessTokenSettings.GetValue("Issuer"), @@ -56,25 +54,6 @@ public class AccessTokenGenerator : IAccessTokenGenerator return handler.WriteToken(token); } - public RefreshToken GenerateRefreshToken(bool isExtendable) - { - string lifetimeSection = isExtendable ? "Extended" : "Normal"; - int lifetime = _configuration.GetSection("Tokens") - .GetSection("RefreshToken") - .GetSection("Lifetime") - .GetValue(lifetimeSection); - - Guid guid = Guid.NewGuid(); - DateTimeOffset expirationDate = DateTimeOffset.UtcNow.AddMinutes(lifetime); - - return new RefreshToken - { - Token = guid, - ExpirationDate = expirationDate, - IsExtendable = isExtendable, - }; - } - public bool ValidateExpiredAccessToken(string accessToken) { IConfigurationSection accessTokenSettings = _configuration.GetSection("Tokens") @@ -104,4 +83,14 @@ public class AccessTokenGenerator : IAccessTokenGenerator return jwtSecurityToken is not null && jwtSecurityToken.Header.Alg.Equals(algorithm, StringComparison.InvariantCultureIgnoreCase); } + + public DateTimeOffset CalculateRefreshTokenExpirationDate(bool isExtendable = true) + { + string lifetimeSection = isExtendable ? "Extended" : "Normal"; + int lifetime = _configuration.GetSection("Tokens") + .GetSection("RefreshToken") + .GetSection("Lifetime") + .GetValue(lifetimeSection); + return DateTimeOffset.UtcNow.AddMinutes(lifetime); + } } \ No newline at end of file diff --git a/TimetableDesigner.Backend.Services.Authentication/Program.cs b/TimetableDesigner.Backend.Services.Authentication/Program.cs index 0f6185e..5b9056b 100644 --- a/TimetableDesigner.Backend.Services.Authentication/Program.cs +++ b/TimetableDesigner.Backend.Services.Authentication/Program.cs @@ -52,7 +52,7 @@ public static class Program private static IServiceCollection AddHelpers(this IServiceCollection services) { services.AddSingleton(); - services.AddScoped(); + services.AddScoped(); return services; }