Skip to content

Commit 4a272db

Browse files
Align MCP token creation reference time
Agent-Logs-Url: https://github.com/IntelliTect/EssentialCSharp.Web/sessions/bc3c4ad5-6f8e-47fe-a4e4-dd78459a3763 Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com>
1 parent d1819fe commit 4a272db

4 files changed

Lines changed: 32 additions & 3 deletions

File tree

EssentialCSharp.Web.Tests/McpApiTokenServiceTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,24 @@ await Assert.That(() => tokenService.CreateTokenAsync(userId, "too-long", reques
5151
.Throws<ArgumentOutOfRangeException>()
5252
.WithMessageContaining(McpApiTokenService.MaxExpiryValidationMessage);
5353
}
54+
55+
[Test]
56+
public async Task CreateTokenAsync_WithExplicitCreatedAt_UsesReferenceTimeForDefaultExpiry()
57+
{
58+
string userId = await McpTestHelper.CreateUserAsync(factory, "mcp-explicit-created-at");
59+
60+
using var scope = factory.Services.CreateScope();
61+
var tokenService = scope.ServiceProvider.GetRequiredService<McpApiTokenService>();
62+
DateTime createdAtUtc = new(2026, 4, 30, 23, 59, 59, DateTimeKind.Utc);
63+
64+
(_, var entity) = await tokenService.CreateTokenAsync(
65+
userId,
66+
"explicit-created-at",
67+
createdAtUtc: createdAtUtc);
68+
69+
await Assert.That(entity.CreatedAt).IsEqualTo(createdAtUtc);
70+
await Assert.That(entity.ExpiresAt).IsNotNull();
71+
await Assert.That(entity.ExpiresAt!.Value)
72+
.IsEqualTo(McpApiTokenService.GetDefaultExpirationUtc(createdAtUtc));
73+
}
5474
}

EssentialCSharp.Web/Areas/Identity/Pages/Account/Manage/McpAccess.cshtml.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ public async Task<IActionResult> OnPostCreateAsync()
7272
// Convert date-only boundary to end-of-day UTC instant before persisting
7373
DateTime? expiresAt = ExpiresOn?.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc);
7474

75-
var (rawToken, entity) = await tokenService.CreateTokenAsync(userId, TokenName.Trim(), expiresAt);
75+
var (rawToken, entity) = await tokenService.CreateTokenAsync(
76+
userId,
77+
TokenName.Trim(),
78+
expiresAt,
79+
createdAtUtc: nowUtc);
7680
GeneratedToken = rawToken;
7781
GeneratedTokenEntity = entity;
7882
UserTokens = await tokenService.GetUserTokensAsync(userId);

EssentialCSharp.Web/Controllers/McpTokenController.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ public async Task<IActionResult> CreateToken(
4141
}
4242

4343
var (rawToken, entity) = await tokenService.CreateTokenAsync(
44-
userId, name, expiresAt, cancellationToken);
44+
userId,
45+
name,
46+
expiresAt,
47+
createdAtUtc: nowUtc,
48+
cancellationToken: cancellationToken);
4549

4650
return Ok(new
4751
{

EssentialCSharp.Web/Services/McpApiTokenService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ public static string GenerateRawToken()
3636
string userId,
3737
string name,
3838
DateTime? expiresAt = null,
39+
DateTime? createdAtUtc = null,
3940
CancellationToken cancellationToken = default)
4041
{
4142
string raw = GenerateRawToken();
42-
DateTime createdAt = DateTime.UtcNow;
43+
DateTime createdAt = createdAtUtc ?? DateTime.UtcNow;
4344
DateTime effectiveExpiration = ResolveExpiration(expiresAt, createdAt);
4445

4546
var entity = new McpApiToken

0 commit comments

Comments
 (0)