first commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user