using CPRNIMS.Infrastructure.Helper; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using System.IdentityModel.Tokens.Jwt; namespace CPRNIMS.WebApps.Common.Middleware { public class TokenRefreshMiddleware { private readonly RequestDelegate _next; public TokenRefreshMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync( HttpContext context, IHttpClientFactory httpClientFactory) { var accessToken = context.Session.GetString("AccessToken"); if (!string.IsNullOrEmpty(accessToken) && IsTokenExpiringSoon(accessToken)) { var client = httpClientFactory.CreateClient($"AuthApi{"Account/RefreshToken"}"); var response = await client.PostAsync("RefreshToken", null); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); var tokenResult = JsonConvert.DeserializeObject(json); context.Session.SetString("AccessToken", tokenResult.AccessToken); } else { // refresh token invalid → force logout context.Session.Clear(); context.Response.Redirect("/Home/Logout"); return; } } await _next(context); } private static bool IsTokenExpiringSoon(string token, int thresholdMinutes = 2) { var jwt = new JwtSecurityTokenHandler().ReadJwtToken(token); return DateTime.UtcNow >= jwt.ValidTo.AddMinutes(-thresholdMinutes); } public class TokenResult { public string? AccessToken { get; set; } public DateTime Expiration { get; set; } } } }