using System.Collections.Concurrent; using Microsoft.EntityFrameworkCore; using RadicadeServer.DB; namespace RadicadeServer.Utils { public static class TokenRevocation { private static readonly ConcurrentDictionary Versions = new(); public static async Task IsValidAsync(IServiceProvider services, long accountId, int tokenVersion) { if (Versions.TryGetValue(accountId, out var cached)) return cached == tokenVersion; var factory = services.GetRequiredService>(); await using var db = await factory.CreateDbContextAsync(); var current = await db.Players .AsNoTracking() .Where(p => p.AccountId == accountId) .Select(p => (int?)p.TokenVersion) .FirstOrDefaultAsync(); var stored = current ?? 0; Versions[accountId] = stored; return stored == tokenVersion; } public static void Bump(long accountId, int newVersion) { Versions.TryRemove(accountId, out _); } } }