using DigitalData.Auth.Abstractions; using DigitalData.Core.Abstractions.Security; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Caching.Memory; namespace DigitalData.Auth.API.Hubs; public class AuthHub : Hub, IAuthSenderHandler { private readonly ICryptoFactory _cFactory; private readonly ILogger _logger; private readonly IMemoryCache _cache; private readonly static string CacheId = Guid.NewGuid().ToString(); public AuthHub(ICryptoFactory cryptoFactory, ILogger logger, IMemoryCache cache) { _cFactory = cryptoFactory; _logger = logger; _cache = cache; } public async Task GetPublicKeyAsync(string issuer, string audience) { if(_cFactory.TokenDescriptors.TryGet(issuer, audience, out var tDesc)) { await Clients.Caller.ReceivePublicKeyAsync(issuer, audience, tDesc.PublicKey.Content); } else { await Clients.Caller.ReceivePublicKeyAsync(issuer, audience, string.Empty); // Log this warning only once per minute to avoid unnecessary repetition. _cache.GetOrCreate(CacheId + "LastLoggingDate", e => { _logger.LogWarning("Token description is not found. Issuer: {issuer} Audience: {audience}", issuer, audience); e.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1); return true; }); } } public async Task SendPublicKeyAsync(string issuer, string audience, string value) => await Clients.All.ReceivePublicKeyAsync(issuer, audience, value); }