using System.Net.Http.Json;
using System.Text.Json;
namespace Azaion.Missions.E2E.Helpers;
///
/// Invokes the missions service's test-only POST /test/refresh-jwks
/// endpoint, which forces the JWKS
/// to re-fetch immediately. The endpoint is mapped only when
/// ASPNETCORE_ENVIRONMENT=Test; production deployments never expose it.
///
///
/// Why this exists: Microsoft.IdentityModel.Tokens hard-pins the
/// MinimumAutomaticRefreshInterval floor to 5 minutes via a static
/// field. JWKS-rotation e2e scenarios (NFT-SEC-11, NFT-RES-07) cannot rely on
/// the proactive refresh path inside the 15-minute CI window. The signature-
/// failure refresh path the JwtBearer middleware exposes
/// (RefreshOnIssuerKeyNotFound) is bypassed because the service uses a
/// custom IssuerSigningKeyResolver. Hence: explicit refresh via this
/// hook, no test poisons later tests.
///
public static class JwksRefreshHelper
{
public static async Task ForceRefreshAsync(HttpClient missions, CancellationToken cancel = default)
{
ArgumentNullException.ThrowIfNull(missions);
using var resp = await missions.PostAsync("/test/refresh-jwks", content: null, cancel)
.ConfigureAwait(false);
resp.EnsureSuccessStatusCode();
var body = await resp.Content.ReadFromJsonAsync(cancel).ConfigureAwait(false);
var kids = body.GetProperty("kids");
var result = new string[kids.GetArrayLength()];
for (var i = 0; i < result.Length; i++)
result[i] = kids[i].GetString() ?? "";
return result;
}
}