using System; using System.Security.Cryptography; using System.Text; namespace GB5Shared.Auth.Jwt { /// /// Refresh-token generation/hashing — extracted verbatim (byte-identical logic) from what /// DXPJwtService and ClientJwtService each independently hand-rolled. Not used by stateless /// M2M/client-credentials flows (a service just re-presents its secret when the access token /// expires — there is nothing to rotate). /// public static class RefreshTokenHelper { public static (string RawToken, string TokenHash) GenerateRefreshToken() { var bytes = RandomNumberGenerator.GetBytes(64); var raw = Convert.ToBase64String(bytes) .Replace("+", "-").Replace("/", "_").TrimEnd('='); // URL-safe return (raw, HashRefreshToken(raw)); } public static string HashRefreshToken(string rawToken) { var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(rawToken)); return Convert.ToHexString(bytes); } } }