using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Security.Configuration; using PostFundManagement.Domain.Security.Models; using PostFundManagement.Domain.Security.Sdk; namespace PostFundManagement.Application.Services.Shared; public sealed class TokenService(ISecurityConnectApi connectApi, IOptions clientOptions) { private readonly SecurityClientSettings clientSettings = clientOptions.Value; public async Task> GenerateAsync(CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { using var response = await connectApi.GetToken(new Domain.Security.Models.TokenRequest { ClientId = clientSettings.ClientId, ClientSecret = clientSettings.ClientSecret, GrantType = clientSettings.GrantType, Scope = clientSettings.Scope, }, cancellationToken); var contentRaw = await response.Content.ReadAsStringAsync(cancellationToken); if (string.IsNullOrWhiteSpace(contentRaw)) return Result.Fail(ValidationError.Create($"The authentication endpoint returned an empty payload. Status code: {response.StatusCode}")); if (response.IsSuccessStatusCode) { var tokenResponse = JsonSerializer.Deserialize(contentRaw); return Result.FailIf(string.IsNullOrWhiteSpace(tokenResponse?.AccessToken), NotFoundError.Create("Authentication succeeded, but no access token was found in the response payload.")) .ToResult(tokenResponse!); } return await Result.Try((Func>>)(async () => { var errorResult = JsonSerializer.Deserialize(contentRaw); return Result.OkIf(errorResult is not null, CreateError.Create($"{errorResult!.Error}: {errorResult.ErrorDescription}")); })); })); }