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

51 lines
2.5 KiB
C#

using Fitness_core_BE.DTOs.Auth;
using Fitness_core_BE.Exceptions;
using Fitness_core_BE.Models.IOs;
using System.Text.Json;
namespace Fitness_core_BE.Helpers
{
// Parses AuthHex's real /api/alt|/api/user response shapes. The AuthHex gateway wraps
// whatever the underlying handler returns in its own {success,message,data} envelope, so
// authResponse.Data (already unwrapped once by AuthService) can itself be a SECOND envelope:
// { "success": true, "message": "...", "data": { "referenceNumber": "REC...", "expiresAt": "2026-07-03T18:49:38Z", "recoveryType": "..." } }
// referenceNumber is an opaque string, not a Guid, and there is no "expiresInSeconds" field -
// it's an absolute "expiresAt" timestamp that we convert to a countdown.
public static class AuthOtpResponseParser
{
public static SendOtpResult ToSendOtpResult(AuthResponse authResponse, int resendAllowedInSeconds = 60)
{
if (authResponse.Data == null)
throw new BadRequestException("Auth service did not return OTP data.");
var data = UnwrapToField(DeserializePayload.Deserialize(authResponse.Data), "referenceNumber", "ReferenceNumber");
var referenceNumber = DataExtractor.GetRequiredStringByKeys(data, "referenceNumber");
var expiresAt = DataExtractor.GetOptionalDateTime(data, "expiresAt");
var expiresInSeconds = expiresAt.HasValue
? Math.Max(0, (int)(expiresAt.Value.ToUniversalTime() - DateTime.UtcNow).TotalSeconds)
: DataExtractor.GetNullableInt(data, "expiresInSeconds") ?? 600;
return new SendOtpResult(referenceNumber, expiresInSeconds, resendAllowedInSeconds);
}
// If the payload doesn't have any of the fields we're after but looks like another
// {success,message,data} envelope, drop down into its "data" and try again.
public static Dictionary<string, JsonElement> UnwrapToField(Dictionary<string, JsonElement> data, params string[] anyOfKeys)
{
for (var depth = 0; depth < 3; depth++)
{
if (anyOfKeys.Any(k => data.ContainsKey(k)))
return data;
if (!data.TryGetValue("data", out var nested) || nested.ValueKind != JsonValueKind.Object)
return data;
data = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(nested.GetRawText())!;
}
return data;
}
}
}