diff --git a/src/starterProject/Application/Application.csproj b/src/starterProject/Application/Application.csproj index aa55900..ff2144d 100644 --- a/src/starterProject/Application/Application.csproj +++ b/src/starterProject/Application/Application.csproj @@ -10,15 +10,15 @@ - - - + + + - + - + diff --git a/src/starterProject/Application/ApplicationServiceRegistration.cs b/src/starterProject/Application/ApplicationServiceRegistration.cs index 5bacc34..3d18d2c 100644 --- a/src/starterProject/Application/ApplicationServiceRegistration.cs +++ b/src/starterProject/Application/ApplicationServiceRegistration.cs @@ -19,6 +19,7 @@ using NArchitecture.Core.Mailing; using NArchitecture.Core.Mailing.MailKit; using NArchitecture.Core.Security.DependencyInjection; +using NArchitecture.Core.Security.JWT; namespace Application; @@ -28,7 +29,8 @@ public static IServiceCollection AddApplicationServices( this IServiceCollection services, MailSettings mailSettings, FileLogConfiguration fileLogConfiguration, - ElasticSearchConfig elasticSearchConfig + ElasticSearchConfig elasticSearchConfig, + TokenOptions tokenOptions ) { services.AddAutoMapper(Assembly.GetExecutingAssembly()); @@ -57,7 +59,7 @@ ElasticSearchConfig elasticSearchConfig services.AddYamlResourceLocalization(); - services.AddSecurityServices(); + services.AddSecurityServices(tokenOptions); return services; } diff --git a/src/starterProject/Application/Features/Auth/Profiles/MappingProfiles.cs b/src/starterProject/Application/Features/Auth/Profiles/MappingProfiles.cs index 37eb491..9c40e2d 100644 --- a/src/starterProject/Application/Features/Auth/Profiles/MappingProfiles.cs +++ b/src/starterProject/Application/Features/Auth/Profiles/MappingProfiles.cs @@ -8,7 +8,7 @@ public class MappingProfiles : Profile { public MappingProfiles() { - CreateMap, RefreshToken>().ReverseMap(); + CreateMap, RefreshToken>().ReverseMap(); CreateMap().ReverseMap(); } } diff --git a/src/starterProject/Application/Features/Auth/Rules/AuthBusinessRules.cs b/src/starterProject/Application/Features/Auth/Rules/AuthBusinessRules.cs index ba7e260..fa60268 100644 --- a/src/starterProject/Application/Features/Auth/Rules/AuthBusinessRules.cs +++ b/src/starterProject/Application/Features/Auth/Rules/AuthBusinessRules.cs @@ -70,13 +70,13 @@ public async Task RefreshTokenShouldBeExists(RefreshToken? refreshToken) public async Task RefreshTokenShouldBeActive(RefreshToken refreshToken) { - if (refreshToken.RevokedDate != null && DateTime.UtcNow >= refreshToken.ExpiresDate) + if (refreshToken.RevokedDate != null && DateTime.UtcNow >= refreshToken.ExpirationDate) await throwBusinessException(AuthMessages.InvalidRefreshToken); } public async Task UserEmailShouldBeNotExists(string email) { - bool doesExists = await _userRepository.AnyAsync(predicate: u => u.Email == email, enableTracking: false); + bool doesExists = await _userRepository.AnyAsync(predicate: u => u.Email == email); if (doesExists) await throwBusinessException(AuthMessages.UserMailAlreadyExists); } diff --git a/src/starterProject/Application/Services/AuthService/AuthManager.cs b/src/starterProject/Application/Services/AuthService/AuthManager.cs index 616b556..78021f7 100644 --- a/src/starterProject/Application/Services/AuthService/AuthManager.cs +++ b/src/starterProject/Application/Services/AuthService/AuthManager.cs @@ -10,7 +10,7 @@ namespace Application.Services.AuthService; public class AuthManager : IAuthService { private readonly IRefreshTokenRepository _refreshTokenRepository; - private readonly ITokenHelper _tokenHelper; + private readonly ITokenHelper _tokenHelper; private readonly TokenOptions _tokenOptions; private readonly IUserOperationClaimRepository _userOperationClaimRepository; private readonly IMapper _mapper; @@ -18,7 +18,7 @@ public class AuthManager : IAuthService public AuthManager( IUserOperationClaimRepository userOperationClaimRepository, IRefreshTokenRepository refreshTokenRepository, - ITokenHelper tokenHelper, + ITokenHelper tokenHelper, IConfiguration configuration, IMapper mapper ) @@ -81,7 +81,7 @@ public async Task RevokeRefreshToken( public async Task RotateRefreshToken(User user, RefreshToken refreshToken, string ipAddress) { - NArchitecture.Core.Security.Entities.RefreshToken newCoreRefreshToken = _tokenHelper.CreateRefreshToken( + NArchitecture.Core.Security.Entities.RefreshToken newCoreRefreshToken = _tokenHelper.CreateRefreshToken( user, ipAddress ); @@ -96,7 +96,7 @@ public async Task RevokeDescendantRefreshTokens(RefreshToken refreshToken, strin r.Token == refreshToken.ReplacedByToken ); - if (childToken?.RevokedDate != null && childToken.ExpiresDate <= DateTime.UtcNow) + if (childToken?.RevokedDate != null && childToken.ExpirationDate <= DateTime.UtcNow) await RevokeRefreshToken(childToken, ipAddress, reason); else await RevokeDescendantRefreshTokens(refreshToken: childToken!, ipAddress, reason); @@ -104,7 +104,7 @@ public async Task RevokeDescendantRefreshTokens(RefreshToken refreshToken, strin public Task CreateRefreshToken(User user, string ipAddress) { - NArchitecture.Core.Security.Entities.RefreshToken coreRefreshToken = _tokenHelper.CreateRefreshToken( + NArchitecture.Core.Security.Entities.RefreshToken coreRefreshToken = _tokenHelper.CreateRefreshToken( user, ipAddress ); diff --git a/src/starterProject/Domain/Domain.csproj b/src/starterProject/Domain/Domain.csproj index db6a970..89f59fc 100644 --- a/src/starterProject/Domain/Domain.csproj +++ b/src/starterProject/Domain/Domain.csproj @@ -9,7 +9,7 @@ - - + + \ No newline at end of file diff --git a/src/starterProject/Domain/Entities/RefreshToken.cs b/src/starterProject/Domain/Entities/RefreshToken.cs index 7db454e..8748620 100644 --- a/src/starterProject/Domain/Entities/RefreshToken.cs +++ b/src/starterProject/Domain/Entities/RefreshToken.cs @@ -1,6 +1,6 @@ namespace Domain.Entities; -public class RefreshToken : NArchitecture.Core.Security.Entities.RefreshToken +public class RefreshToken : NArchitecture.Core.Security.Entities.RefreshToken { public virtual User User { get; set; } = default!; } diff --git a/src/starterProject/Domain/Entities/UserOperationClaim.cs b/src/starterProject/Domain/Entities/UserOperationClaim.cs index c1ce57c..ae0237c 100644 --- a/src/starterProject/Domain/Entities/UserOperationClaim.cs +++ b/src/starterProject/Domain/Entities/UserOperationClaim.cs @@ -1,6 +1,6 @@ namespace Domain.Entities; -public class UserOperationClaim : NArchitecture.Core.Security.Entities.UserOperationClaim +public class UserOperationClaim : NArchitecture.Core.Security.Entities.UserOperationClaim { public virtual User User { get; set; } = default!; public virtual OperationClaim OperationClaim { get; set; } = default!; diff --git a/src/starterProject/Infrastructure/Infrastructure.csproj b/src/starterProject/Infrastructure/Infrastructure.csproj index 77ee3f8..c267fb7 100644 --- a/src/starterProject/Infrastructure/Infrastructure.csproj +++ b/src/starterProject/Infrastructure/Infrastructure.csproj @@ -5,7 +5,7 @@ enable - + diff --git a/src/starterProject/Persistence/EntityConfigurations/RefreshTokenConfiguration.cs b/src/starterProject/Persistence/EntityConfigurations/RefreshTokenConfiguration.cs index 7b332bb..c930d8c 100644 --- a/src/starterProject/Persistence/EntityConfigurations/RefreshTokenConfiguration.cs +++ b/src/starterProject/Persistence/EntityConfigurations/RefreshTokenConfiguration.cs @@ -13,7 +13,7 @@ public void Configure(EntityTypeBuilder builder) builder.Property(rt => rt.Id).HasColumnName("Id").IsRequired(); builder.Property(rt => rt.UserId).HasColumnName("UserId").IsRequired(); builder.Property(rt => rt.Token).HasColumnName("Token").IsRequired(); - builder.Property(rt => rt.ExpiresDate).HasColumnName("ExpiresDate").IsRequired(); + builder.Property(rt => rt.ExpirationDate).HasColumnName("ExpiresDate").IsRequired(); builder.Property(rt => rt.CreatedByIp).HasColumnName("CreatedByIp").IsRequired(); builder.Property(rt => rt.RevokedDate).HasColumnName("RevokedDate"); builder.Property(rt => rt.RevokedByIp).HasColumnName("RevokedByIp"); diff --git a/src/starterProject/Persistence/Persistence.csproj b/src/starterProject/Persistence/Persistence.csproj index 1bf937c..6b3cc35 100644 --- a/src/starterProject/Persistence/Persistence.csproj +++ b/src/starterProject/Persistence/Persistence.csproj @@ -8,10 +8,10 @@ - - + + - - + + \ No newline at end of file diff --git a/src/starterProject/Persistence/Repositories/RefreshTokenRepository.cs b/src/starterProject/Persistence/Repositories/RefreshTokenRepository.cs index b93ec3b..aa120d3 100644 --- a/src/starterProject/Persistence/Repositories/RefreshTokenRepository.cs +++ b/src/starterProject/Persistence/Repositories/RefreshTokenRepository.cs @@ -18,7 +18,7 @@ public async Task> GetOldRefreshTokensAsync(Guid userId, int .Where(r => r.UserId == userId && r.RevokedDate == null - && r.ExpiresDate >= DateTime.UtcNow + && r.ExpirationDate >= DateTime.UtcNow && r.CreatedDate.AddDays(refreshTokenTtl) <= DateTime.UtcNow ) .ToListAsync(); diff --git a/src/starterProject/WebAPI/Controllers/BaseController.cs b/src/starterProject/WebAPI/Controllers/BaseController.cs index 086e522..ae70b4d 100644 --- a/src/starterProject/WebAPI/Controllers/BaseController.cs +++ b/src/starterProject/WebAPI/Controllers/BaseController.cs @@ -24,7 +24,7 @@ protected string getIpAddress() protected Guid getUserIdFromRequest() //todo authentication behavior? { - var userId = Guid.Parse(HttpContext.User.GetUserId().ToString()!); + var userId = Guid.Parse(HttpContext.User.GetIdClaim()!); return userId; } } diff --git a/src/starterProject/WebAPI/Program.cs b/src/starterProject/WebAPI/Program.cs index f2602af..2419e70 100644 --- a/src/starterProject/WebAPI/Program.cs +++ b/src/starterProject/WebAPI/Program.cs @@ -27,7 +27,9 @@ .Get() ?? throw new InvalidOperationException("FileLogConfiguration section cannot found in configuration."), elasticSearchConfig: builder.Configuration.GetSection("ElasticSearchConfig").Get() - ?? throw new InvalidOperationException("ElasticSearchConfig section cannot found in configuration.") + ?? throw new InvalidOperationException("ElasticSearchConfig section cannot found in configuration."), + tokenOptions: builder.Configuration.GetSection("TokenOptions").Get() + ?? throw new InvalidOperationException("TokenOptions section cannot found in configuration.") ); builder.Services.AddPersistenceServices(builder.Configuration); builder.Services.AddInfrastructureServices(); diff --git a/src/starterProject/WebAPI/WebAPI.csproj b/src/starterProject/WebAPI/WebAPI.csproj index 713e5e0..18263b6 100644 --- a/src/starterProject/WebAPI/WebAPI.csproj +++ b/src/starterProject/WebAPI/WebAPI.csproj @@ -6,13 +6,13 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tests/StarterProject.Application.Tests/Features/Auth/Commands/Login/LoginTests.cs b/tests/StarterProject.Application.Tests/Features/Auth/Commands/Login/LoginTests.cs index 34b9507..e873b0c 100644 --- a/tests/StarterProject.Application.Tests/Features/Auth/Commands/Login/LoginTests.cs +++ b/tests/StarterProject.Application.Tests/Features/Auth/Commands/Login/LoginTests.cs @@ -52,7 +52,9 @@ UserFakeData userFakeData IUserRepository _userRepository = new MockUserRepository(userFakeData).GetUserMockRepository(); #endregion #region Mock Helpers - ITokenHelper tokenHelper = new JwtHelper(_configuration); + TokenOptions tokenOptions = + _configuration.GetSection("TokenOptions").Get() ?? throw new Exception("Token options not found."); + ITokenHelper tokenHelper = new JwtHelper(tokenOptions); IEmailAuthenticatorHelper emailAuthenticatorHelper = new EmailAuthenticatorHelper(); MailSettings mailSettings = _configuration.GetSection("MailSettings").Get() ?? throw new Exception("Mail settings not found."); diff --git a/tests/StarterProject.Application.Tests/StarterProject.Application.Tests.csproj b/tests/StarterProject.Application.Tests/StarterProject.Application.Tests.csproj index 019c08b..dbd0fdd 100644 --- a/tests/StarterProject.Application.Tests/StarterProject.Application.Tests.csproj +++ b/tests/StarterProject.Application.Tests/StarterProject.Application.Tests.csproj @@ -7,19 +7,19 @@ - + - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - +