Files
Core_Be/Helpers/RequestAccessTokenHelper.cs
Dhananjaya99 bffc9b1686 first commit
2026-09-28 11:44:26 +05:30

72 lines
2.7 KiB
C#

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Fitness_core_BE.Helpers
{
// Mints/validates the short-lived "requestAccessToken" used between mobile-OTP verification
// and onboarding-request creation. Separate from the RSA-signed AuthHex tokens validated by
// CustomMiddleware, since this repo only holds the AuthHex *public* key (no local RSA signing key).
public class RequestAccessTokenHelper
{
private readonly string _signingKey;
private readonly int _expiresInMinutes;
public RequestAccessTokenHelper(IConfiguration configuration)
{
_signingKey = configuration["RequestAccessToken:SigningKey"]
?? throw new InvalidOperationException("RequestAccessToken:SigningKey is not configured.");
_expiresInMinutes = int.TryParse(configuration["RequestAccessToken:ExpiresInMinutes"], out var m) ? m : 15;
}
public (string token, int expiresIn) Generate(string mobileNumber)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_signingKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim("MobileNumber", mobileNumber),
new Claim("Purpose", "RequestAccess")
};
var expires = DateTime.UtcNow.AddMinutes(_expiresInMinutes);
var token = new JwtSecurityToken(
claims: claims,
expires: expires,
signingCredentials: creds);
return (new JwtSecurityTokenHandler().WriteToken(token), _expiresInMinutes * 60);
}
public string? ValidateAndGetMobileNumber(string token)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_signingKey));
var handler = new JwtSecurityTokenHandler();
try
{
var principal = handler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ClockSkew = TimeSpan.FromMinutes(2)
}, out _);
if (principal.FindFirst("Purpose")?.Value != "RequestAccess")
return null;
return principal.FindFirst("MobileNumber")?.Value;
}
catch
{
return null;
}
}
}
}