fix(auth): fix SQLite DateTimeOffset comparison crash in trusted-device checks
The sessions unit's live smoke test caught the same bug it fixed in SessionsController also present in TrustedDeviceService and TwoFactorController's device list: SQLite/Pomelo's EF Core provider cannot translate DateTimeOffset relational comparisons or ORDER BY to SQL, so IsDeviceTrustedAsync (the check that skips 2FA for a trusted browser) and ListTrustedDevices would 500 on real SQLite despite passing on EF's InMemory test provider. Same fix: equality-only in the DB query, expiry comparison and sort after materializing.
This commit is contained in:
@@ -26,10 +26,13 @@ public static class TrustedDeviceService
|
||||
|
||||
var hash = HashToken(token);
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
// SQLite/Pomelo cannot translate DateTimeOffset relational comparisons (>) to SQL, so the
|
||||
// expiry check has to happen after materializing the row -- fine here since the equality
|
||||
// filters (UserId, TokenHash) already narrow this to at most one row.
|
||||
var match = await db.TrustedDevices
|
||||
.IgnoreQueryFilters()
|
||||
.FirstOrDefaultAsync(x => x.UserId == userId && x.TokenHash == hash && x.ExpiresAtUtc > now, cancellationToken);
|
||||
if (match is null) return false;
|
||||
.FirstOrDefaultAsync(x => x.UserId == userId && x.TokenHash == hash, cancellationToken);
|
||||
if (match is null || match.ExpiresAtUtc <= now) return false;
|
||||
|
||||
match.LastSeenAtUtc = now;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user