From cb804d72698467e56bbf0bcf0d2ba27cee9afc8b Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 2 Nov 2026 21:09:26 +0900 Subject: [PATCH] Use the factory clock in token expiry checks The remember token factory stamps ExpirationDate from an injected TimeProvider, but ExpiringTokenable.IsExpired read DateTime.UtcNow. A token created with a fixed test clock was judged against the real one, so the factory test started failing on 2026-11-01 when its 30 day token passed its expiry. Let a factory pass its clock to the token it creates. Tokens that are deserialized keep using the system clock. --- .../Tokenables/TwoFactorRememberTokenableFactory.cs | 1 + src/Core/Tokens/ExpiringTokenable.cs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Core/Auth/Models/Business/Tokenables/TwoFactorRememberTokenableFactory.cs b/src/Core/Auth/Models/Business/Tokenables/TwoFactorRememberTokenableFactory.cs index dedab6bb5a85..1fc9e45bdc44 100644 --- a/src/Core/Auth/Models/Business/Tokenables/TwoFactorRememberTokenableFactory.cs +++ b/src/Core/Auth/Models/Business/Tokenables/TwoFactorRememberTokenableFactory.cs @@ -14,5 +14,6 @@ public TwoFactorRememberTokenable CreateToken(User user, Device device, string s { ExpirationDate = timeProvider.GetUtcNow().UtcDateTime .AddDays(globalSettings.TwoFactorRememberTokenLifetimeInDays), + TimeProvider = timeProvider, }; } diff --git a/src/Core/Tokens/ExpiringTokenable.cs b/src/Core/Tokens/ExpiringTokenable.cs index 5aac7080fc41..c0343cfddd5b 100644 --- a/src/Core/Tokens/ExpiringTokenable.cs +++ b/src/Core/Tokens/ExpiringTokenable.cs @@ -14,7 +14,13 @@ public abstract class ExpiringTokenable : Tokenable /// public override bool Valid => !IsExpired && TokenIsValid(); - public bool IsExpired => ExpirationDate < DateTime.UtcNow; + /// + /// Clock used for the expiration check. Can be overwritten for tests. + /// + [JsonIgnore] + internal TimeProvider TimeProvider { get; set; } = TimeProvider.System; + + public bool IsExpired => ExpirationDate < TimeProvider.GetUtcNow().UtcDateTime; /// /// Validates that the token data properties are correct.