Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,31 @@ var options = Options.Create(new MiniJwtOptions
ExpirationMinutes = 60
});

var svc = new MiniJwtService(options, NullLogger<MiniJwtService>.Instance);
var svc = new MiniJwtService(options, NullLogger<MiniJwtService>.Instance, new JwtSecurityTokenHandler());
```

### Testing with TimeProvider

For testable time-dependent behavior, the library supports `TimeProvider` (built-in for .NET 8+ or via `Microsoft.Bcl.TimeProvider` for earlier versions). You can inject a `FakeTimeProvider` for deterministic testing:

```csharp
using Microsoft.Extensions.Time.Testing;

var fakeTimeProvider = new FakeTimeProvider();
fakeTimeProvider.SetUtcNow(new DateTimeOffset(2024, 1, 15, 10, 0, 0, TimeSpan.Zero));

var svc = new MiniJwtService(
options,
NullLogger<MiniJwtService>.Instance,
new JwtSecurityTokenHandler(),
fakeTimeProvider
);

// Generate token at the fixed time
var token = svc.GenerateToken(user);

// Advance time for further testing
fakeTimeProvider.Advance(TimeSpan.FromMinutes(5));
```

## Debugging tips
Expand Down
68 changes: 68 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,74 @@ public class JwtServiceTests
}
```

### Testing with TimeProvider for Deterministic Time

```csharp
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Time.Testing;
using System.IdentityModel.Tokens.Jwt;
using Xunit;

public class JwtServiceTimeTests
{
// Simple test helper for IOptionsMonitor
private class SimpleOptionsMonitor<T>(T value) : IOptionsMonitor<T>
{
public T CurrentValue => value;
public T Get(string? name) => value;
public IDisposable OnChange(Action<T, string> listener) => new NoOpDisposable();
}

private class NoOpDisposable : IDisposable
{
public void Dispose() { }
}

[Fact]
public void GenerateToken_WithFakeTimeProvider_UsesProvidedTime()
{
// Arrange: Set up a fake time provider at a specific time
var fakeTimeProvider = new FakeTimeProvider();
var fixedTime = new DateTimeOffset(2024, 1, 15, 10, 30, 0, TimeSpan.Zero);
fakeTimeProvider.SetUtcNow(fixedTime);

var options = new SimpleOptionsMonitor<MiniJwtOptions>(new MiniJwtOptions
{
SecretKey = "test-secret-key-at-least-32-bytes-long",
Issuer = "TestApp",
Audience = "TestClient",
ExpirationMinutes = 60
});

// Create service with fake time provider
var service = new MiniJwtService(
options,
NullLogger<MiniJwtService>.Instance,
new JwtSecurityTokenHandler { MapInboundClaims = false },
fakeTimeProvider
);

// Act: Generate a token
var token = service.GenerateToken(new { sub = "test-user" });

// Assert: Verify the token uses the fake time
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);

Assert.Equal(fixedTime.UtcDateTime, jwtToken.ValidFrom);
Assert.Equal(fixedTime.AddMinutes(60).UtcDateTime, jwtToken.ValidTo);

// Advance time and generate another token
fakeTimeProvider.Advance(TimeSpan.FromMinutes(10));
var token2 = service.GenerateToken(new { sub = "test-user2" });

var jwtToken2 = handler.ReadJwtToken(token2);
Assert.Equal(fixedTime.AddMinutes(10).UtcDateTime, jwtToken2.ValidFrom);
}
}
```

## Runnable Sample Applications

We provide complete, runnable sample applications in the repository:
Expand Down
3 changes: 3 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ See the [examples documentation](examples.md#unit-testing) for unit testing patt
- Create test instances with `NullLogger<MiniJwtService>.Instance`
- Use `Options.Create()` for test configurations
- Mock `IMiniJwtService` in your tests for isolation
- Use `FakeTimeProvider` from `Microsoft.Extensions.TimeProvider.Testing` for deterministic time-dependent testing

For time-dependent testing, inject a `FakeTimeProvider` into the service constructor to control token generation timestamps. See [Testing with TimeProvider](examples.md#testing-with-timeprovider-for-deterministic-time) for examples.

## Troubleshooting

Expand Down
5 changes: 5 additions & 0 deletions src/MiniJwt.Core/MiniJwt.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" />
</ItemGroup>

<!-- TimeProvider is built-in for .NET 8+, but needs a package for earlier versions -->
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>
Expand Down
9 changes: 8 additions & 1 deletion src/MiniJwt.Core/Services/MiniJwtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

namespace MiniJwt.Core.Services;

public class MiniJwtService : IMiniJwtService, IDisposable

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'

Check warning on line 14 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService'
{
private readonly ILogger _logger;
private readonly JwtSecurityTokenHandler _tokenHandler;
private readonly TimeProvider _timeProvider;
private readonly IDisposable? _optionsChangeRegistration;
private readonly object _sync = new object();

Expand All @@ -25,10 +26,16 @@

private const int MinimumKeyLengthBytes = 32; // 256 bits for HS256

public MiniJwtService(IOptionsMonitor<MiniJwtOptions> optionsMonitor, ILogger<MiniJwtService> logger, JwtSecurityTokenHandler tokenHandler)

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'

Check warning on line 29 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler)'
: this(optionsMonitor, logger, tokenHandler, TimeProvider.System)
{
}

public MiniJwtService(IOptionsMonitor<MiniJwtOptions> optionsMonitor, ILogger<MiniJwtService> logger, JwtSecurityTokenHandler tokenHandler, TimeProvider timeProvider)

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'

Check warning on line 34 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.MiniJwtService(IOptionsMonitor<MiniJwtOptions>, ILogger<MiniJwtService>, JwtSecurityTokenHandler, TimeProvider)'
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_tokenHandler = tokenHandler ?? throw new ArgumentNullException(nameof(tokenHandler));
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
_options = optionsMonitor.CurrentValue ?? throw new ArgumentNullException(nameof(optionsMonitor));

RefreshFromOptions(_options);
Expand Down Expand Up @@ -109,7 +116,7 @@

claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));

var now = DateTime.UtcNow;
var now = _timeProvider.GetUtcNow().UtcDateTime;
var expires = now.AddMinutes(currentOptions.ExpirationMinutes);

var jwt = new JwtSecurityToken(
Expand Down Expand Up @@ -234,7 +241,7 @@
}
}

public void Dispose()

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (macos-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (ubuntu-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 8.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 7.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 9.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 6.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'

Check warning on line 244 in src/MiniJwt.Core/Services/MiniJwtService.cs

View workflow job for this annotation

GitHub Actions / build-and-test (windows-latest, 10.0.x)

Missing XML comment for publicly visible type or member 'MiniJwtService.Dispose()'
{
_optionsChangeRegistration?.Dispose();
}
Expand Down
1 change: 1 addition & 0 deletions src/MiniJwt.Tests/MiniJwt.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.22" />
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.10.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
</ItemGroup>
Expand Down
94 changes: 94 additions & 0 deletions src/MiniJwt.Tests/MiniJwtTests.Service.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Time.Testing;
using MiniJwt.Core.Attributes;
using MiniJwt.Core.Models;
using MiniJwt.Core.Services;
Expand Down Expand Up @@ -285,4 +286,97 @@ public void Dispose_ShouldCleanupOptionsChangeSubscription()
// Assert
Assert.True(trackableDisposable.IsDisposed, "The options change subscription should be disposed when the service is disposed");
}

[Fact]
public void GenerateToken_WithFakeTimeProvider_ShouldUseProvidedTime()
{
// Arrange
var fakeTimeProvider = new FakeTimeProvider();
var fixedTime = new DateTimeOffset(2024, 1, 15, 10, 30, 0, TimeSpan.Zero);
fakeTimeProvider.SetUtcNow(fixedTime);

var options = new SimpleOptionsMonitor<MiniJwtOptions>(new MiniJwtOptions
{
SecretKey = "IntegrationTestSecretKey_LongEnough_For_HS256_0123456789",
Issuer = "MiniJwt.Tests",
Audience = "MiniJwt.Tests.Client",
ExpirationMinutes = 60
});

using var loggerFactory = new LoggerFactory();
var service = new MiniJwtService(
options,
loggerFactory.CreateLogger<MiniJwtService>(),
new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(),
fakeTimeProvider
);

var user = new TestUser { Id = 1, Email = "test@test.com", Name = "User Test" };

// Act
var token = service.GenerateToken(user);

// Assert
Assert.NotNull(token);

// Decode the token to verify it uses the fake time
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);

// The token's NotBefore should match the fixed time
Assert.Equal(fixedTime.UtcDateTime, jwtToken.ValidFrom);

// The token's expiration should be 60 minutes after the fixed time
var expectedExpiry = fixedTime.AddMinutes(60).UtcDateTime;
Assert.Equal(expectedExpiry, jwtToken.ValidTo);
}

[Fact]
public void GenerateToken_WithAdvancedTime_UsesUpdatedTime()
{
// Arrange
var fakeTimeProvider = new FakeTimeProvider();
var initialTime = new DateTimeOffset(2024, 1, 15, 10, 0, 0, TimeSpan.Zero);
fakeTimeProvider.SetUtcNow(initialTime);

var options = new SimpleOptionsMonitor<MiniJwtOptions>(new MiniJwtOptions
{
SecretKey = "IntegrationTestSecretKey_LongEnough_For_HS256_0123456789",
Issuer = "MiniJwt.Tests",
Audience = "MiniJwt.Tests.Client",
ExpirationMinutes = 10 // 10 minutes
});

using var loggerFactory = new LoggerFactory();
var service = new MiniJwtService(
options,
loggerFactory.CreateLogger<MiniJwtService>(),
new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(),
fakeTimeProvider
);

var user = new TestUser { Id = 1, Email = "test@test.com", Name = "User Test" };

// Generate token at initial time
var token = service.GenerateToken(user);
Assert.NotNull(token);

// Verify the token was generated with the fake time
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
Assert.Equal(initialTime.UtcDateTime, jwtToken.ValidFrom);
Assert.Equal(initialTime.AddMinutes(10).UtcDateTime, jwtToken.ValidTo);

// Advance the fake time by 5 minutes
fakeTimeProvider.Advance(TimeSpan.FromMinutes(5));

// Generate another token - it should use the new advanced time
var token2 = service.GenerateToken(user);
Assert.NotNull(token2);

var jwtToken2 = handler.ReadJwtToken(token2);
var expectedTime = initialTime.AddMinutes(5).UtcDateTime;
Assert.Equal(expectedTime, jwtToken2.ValidFrom);
Assert.Equal(expectedTime.AddMinutes(10), jwtToken2.ValidTo);
}
}
Loading