diff --git a/LiteCharms.Features.MidrandBooks.Tests/AuthorServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/AuthorServiceFeatureTests.cs
index d74aac1..8116065 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/AuthorServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/AuthorServiceFeatureTests.cs
@@ -1,7 +1,7 @@
using LiteCharms.Features.MidrandBooks.Authors;
using LiteCharms.Features.MidrandBooks.Authors.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
using LiteCharms.Features.Models;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/BooksServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/BooksServiceFeatureTests.cs
index d65e0d6..57e4474 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/BooksServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/BooksServiceFeatureTests.cs
@@ -1,5 +1,5 @@
using LiteCharms.Features.MidrandBooks.AuthorBooks;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/CategoryServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/CategoryServiceFeatureTests.cs
index c1f103c..f84b3f2 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/CategoryServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/CategoryServiceFeatureTests.cs
@@ -1,5 +1,5 @@
using LiteCharms.Features.MidrandBooks.Categories;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/CustomerServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/CustomerServiceFeatureTests.cs
index 5edea77..f102a78 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/CustomerServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/CustomerServiceFeatureTests.cs
@@ -1,6 +1,6 @@
using LiteCharms.Features.MidrandBooks.Customers;
using LiteCharms.Features.MidrandBooks.Customers.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/LiteCharms.Features.MidrandBooks.Tests.csproj b/LiteCharms.Features.MidrandBooks.Tests/LiteCharms.Features.MidrandBooks.Tests.csproj
index a4b86f0..b8084c2 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/LiteCharms.Features.MidrandBooks.Tests.csproj
+++ b/LiteCharms.Features.MidrandBooks.Tests/LiteCharms.Features.MidrandBooks.Tests.csproj
@@ -35,6 +35,7 @@
+
@@ -45,10 +46,4 @@
-
-
- Always
-
-
-
\ No newline at end of file
diff --git a/LiteCharms.Features.MidrandBooks.Tests/OrderServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/OrderServiceFeatureTests.cs
index ef09044..1e01faa 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/OrderServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/OrderServiceFeatureTests.cs
@@ -1,7 +1,7 @@
using LiteCharms.Features.MidrandBooks.Orders;
using LiteCharms.Features.MidrandBooks.Orders.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
using LiteCharms.Features.Models;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/PageServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/PageServiceFeatureTests.cs
index a98c368..afecd71 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/PageServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/PageServiceFeatureTests.cs
@@ -1,5 +1,5 @@
using LiteCharms.Features.MidrandBooks.Pages;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/PayfastServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/PayfastServiceFeatureTests.cs
index 65f4eed..7923a6b 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/PayfastServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/PayfastServiceFeatureTests.cs
@@ -1,6 +1,6 @@
using LiteCharms.Features.MidrandBooks.Payments;
using LiteCharms.Features.MidrandBooks.Payments.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/PaymentServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/PaymentServiceFeatureTests.cs
index 3681116..c1514b1 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/PaymentServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/PaymentServiceFeatureTests.cs
@@ -1,6 +1,6 @@
using LiteCharms.Features.MidrandBooks.Payments;
using LiteCharms.Features.MidrandBooks.Payments.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/ProductServiceFeatureTests.cs b/LiteCharms.Features.MidrandBooks.Tests/ProductServiceFeatureTests.cs
index 827025f..860f059 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/ProductServiceFeatureTests.cs
+++ b/LiteCharms.Features.MidrandBooks.Tests/ProductServiceFeatureTests.cs
@@ -1,7 +1,7 @@
using LiteCharms.Features.MidrandBooks.Products;
using LiteCharms.Features.MidrandBooks.Products.Models;
-using LiteCharms.Features.MidrandBooks.Tests.Common;
using LiteCharms.Features.Models;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.MidrandBooks.Tests;
diff --git a/LiteCharms.Features.MidrandBooks.Tests/Common/Fixture.cs b/LiteCharms.Features.Tests.Common/Fixture.cs
similarity index 85%
rename from LiteCharms.Features.MidrandBooks.Tests/Common/Fixture.cs
rename to LiteCharms.Features.Tests.Common/Fixture.cs
index a5a759f..507d4e1 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/Common/Fixture.cs
+++ b/LiteCharms.Features.Tests.Common/Fixture.cs
@@ -1,9 +1,7 @@
using LiteCharms.Features.Extensions;
-using LiteCharms.Features.MidrandBooks.Abstractions;
using LiteCharms.Features.MidrandBooks.Extensions;
-using Microsoft.VisualStudio.TestPlatform.TestHost;
-namespace LiteCharms.Features.MidrandBooks.Tests.Common;
+namespace LiteCharms.Features.Tests.Common;
public class Fixture : IDisposable
{
@@ -27,9 +25,8 @@ public class Fixture : IDisposable
.Build();
Services = new ServiceCollection()
- .AddHttpClient()
- .AddMediator()
.AddLogging()
+ .AddMediator()
.AddEmailServiceBus()
.AddGarageS3(Configuration)
.AddMidrandShopDatabase(Configuration)
@@ -37,7 +34,9 @@ public class Fixture : IDisposable
.AddSingleton(Configuration)
.AddShopServices()
.AddHashServices(Configuration)
- .BuildServiceProvider();
+ .AddLiteCharmsApiSecurity(Configuration)
+ .AddSecurityApiSdk(Configuration)
+ .BuildServiceProvider(); ;
Mediator = Services.GetRequiredService();
}
diff --git a/LiteCharms.Features.MidrandBooks.Tests/Common/IntegrationFactAttribute.cs b/LiteCharms.Features.Tests.Common/IntegrationFactAttribute.cs
similarity index 77%
rename from LiteCharms.Features.MidrandBooks.Tests/Common/IntegrationFactAttribute.cs
rename to LiteCharms.Features.Tests.Common/IntegrationFactAttribute.cs
index 304f78e..f62577c 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/Common/IntegrationFactAttribute.cs
+++ b/LiteCharms.Features.Tests.Common/IntegrationFactAttribute.cs
@@ -1,4 +1,4 @@
-namespace LiteCharms.Features.MidrandBooks.Tests.Common;
+namespace LiteCharms.Features.Tests.Common;
public class IntegrationFactAttribute : FactAttribute
{
diff --git a/LiteCharms.Features.Tests.Common/LiteCharms.Features.Tests.Common.csproj b/LiteCharms.Features.Tests.Common/LiteCharms.Features.Tests.Common.csproj
new file mode 100644
index 0000000..d90376e
--- /dev/null
+++ b/LiteCharms.Features.Tests.Common/LiteCharms.Features.Tests.Common.csproj
@@ -0,0 +1,80 @@
+
+
+
+ net10.0
+ enable
+ enable
+ 0521f45a-eba0-457f-bb5e-c3680f65d8b1
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/LiteCharms.Features.MidrandBooks.Tests/appsettings.json b/LiteCharms.Features.Tests.Common/appsettings.json
similarity index 75%
rename from LiteCharms.Features.MidrandBooks.Tests/appsettings.json
rename to LiteCharms.Features.Tests.Common/appsettings.json
index b6f6ba7..634da64 100644
--- a/LiteCharms.Features.MidrandBooks.Tests/appsettings.json
+++ b/LiteCharms.Features.Tests.Common/appsettings.json
@@ -1,4 +1,13 @@
{
+ "LiteCharmsSettings": {
+ "Authority": "https://sts.security.khongisa.co.za",
+ "Audience": "midrandbooks-api"
+ },
+ "LiteCharmsClientSettings": {
+ "Authority": "https://sts.security.khongisa.co.za",
+ "GrantType": "client_credentials",
+ "Scope": "midrandbooks-api"
+ },
"ValidPayfastHosts": [
"www.payfast.co.za",
"sandbox.payfast.co.za",
@@ -26,7 +35,6 @@
"UseSsl": true
},
"Monitoring": {
- "ApiKey": "",
"Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889",
"ServiceName": "LiteCharms.LeadGenerator"
},
diff --git a/LiteCharms.Features.Tests/Fixture.cs b/LiteCharms.Features.Tests/Fixture.cs
deleted file mode 100644
index 1ad8e4a..0000000
--- a/LiteCharms.Features.Tests/Fixture.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using LiteCharms.Features.Extensions;
-
-namespace LiteCharms.Features.Tests;
-
-public class Fixture : IDisposable
-{
- public IConfiguration Configuration { get; set; }
-
- public IServiceProvider Services { get; set; }
-
- public IMediator Mediator { get; set; }
-
- public Fixture()
- {
- Configuration = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddUserSecrets()
- .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"), optional: true, reloadOnChange: true)
- .AddEnvironmentVariables()
- .Build();
-
- Services = new ServiceCollection()
- .AddMediator()
- .AddLogging()
- .AddEmailServiceBus()
- .AddGarageS3(Configuration)
- .AddEmailServices(Configuration)
- .AddSingleton(Configuration)
- .AddHashServices(Configuration)
- .BuildServiceProvider();
-
- Mediator = Services.GetRequiredService();
- }
-
- public void Dispose() { }
-}
diff --git a/LiteCharms.Features.Tests/HashServiceFeatureTests.cs b/LiteCharms.Features.Tests/HashServiceFeatureTests.cs
index 844c7fb..8f2a331 100644
--- a/LiteCharms.Features.Tests/HashServiceFeatureTests.cs
+++ b/LiteCharms.Features.Tests/HashServiceFeatureTests.cs
@@ -1,4 +1,5 @@
using LiteCharms.Features.Hasher;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.Tests;
diff --git a/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj b/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj
index 2540fae..ef7e0dc 100644
--- a/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj
+++ b/LiteCharms.Features.Tests/LiteCharms.Features.Tests.csproj
@@ -36,6 +36,7 @@
+
@@ -43,10 +44,4 @@
-
-
- Always
-
-
-
\ No newline at end of file
diff --git a/LiteCharms.Features.Tests/LiteCharmsApiFeatureTests.cs b/LiteCharms.Features.Tests/LiteCharmsApiFeatureTests.cs
new file mode 100644
index 0000000..d33f897
--- /dev/null
+++ b/LiteCharms.Features.Tests/LiteCharmsApiFeatureTests.cs
@@ -0,0 +1,19 @@
+using LiteCharms.Features.Api;
+using LiteCharms.Features.Tests.Common;
+
+namespace LiteCharms.Features.Tests;
+
+public sealed class LiteCharmsApiFeatureTests(Fixture fixture) : IClassFixture
+{
+ private readonly TokenService tokenService = fixture.Services.GetRequiredService();
+
+ [IntegrationFact]
+ public async Task TokenService_GenerateTokenAsync_ShouldReturn_TokenInResult()
+ {
+ var result = await tokenService.GenerateAsync(fixture.CancellationToken);
+
+ Assert.True(result.IsSuccess);
+ Assert.NotNull(result.Value);
+ Assert.NotEmpty(result.Value.AccessToken!);
+ }
+}
diff --git a/LiteCharms.Features.Tests/S3ServiceFeatureTests.cs b/LiteCharms.Features.Tests/S3ServiceFeatureTests.cs
index 8af9a34..b355eac 100644
--- a/LiteCharms.Features.Tests/S3ServiceFeatureTests.cs
+++ b/LiteCharms.Features.Tests/S3ServiceFeatureTests.cs
@@ -1,4 +1,5 @@
using LiteCharms.Features.S3.Abstractions;
+using LiteCharms.Features.Tests.Common;
namespace LiteCharms.Features.Tests;
diff --git a/LiteCharms.Features.Tests/appsettings.json b/LiteCharms.Features.Tests/appsettings.json
deleted file mode 100644
index 1066af9..0000000
--- a/LiteCharms.Features.Tests/appsettings.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "BookshopS3Settings": {
- "ServiceUrl": "http://192.168.1.177:30900",
- "Region": "garage",
- "BucketName": "bookshop",
- "CdnBaseUrl": "https://bookshop.cdn.khongisa.co.za"
- },
- "BookshopQuotesS3Settings": {
- "ServiceUrl": "http://192.168.1.177:30900",
- "Region": "garage",
- "BucketName": "bookshop.quotes",
- "CdnBaseUrl": "https://bookshop.quotes.cdn.khongisa.co.za"
- },
- "Email": {
- "Credentials": {
- "Username": "shop@litecharms.co.za"
- },
- "Port": 465,
- "Host": "mail.litecharms.co.za",
- "UseSsl": true
- },
- "Monitoring": {
- "ApiKey": "",
- "Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889",
- "ServiceName": "LiteCharms.LeadGenerator"
- },
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
- },
- "AllowedHosts": "*"
-}
diff --git a/LiteCharms.Features/Api/Configuration/LiteCharmsClientSettings.cs b/LiteCharms.Features/Api/Configuration/LiteCharmsClientSettings.cs
new file mode 100644
index 0000000..aff2931
--- /dev/null
+++ b/LiteCharms.Features/Api/Configuration/LiteCharmsClientSettings.cs
@@ -0,0 +1,14 @@
+namespace LiteCharms.Features.Api.Configuration;
+
+public sealed class LiteCharmsClientSettings
+{
+ public string? Authority { get; set; }
+
+ public string? GrantType { get; set; }
+
+ public string? ClientId { get; set; }
+
+ public string? ClientSecret { get; set; }
+
+ public string? Scope { get; set; }
+}
diff --git a/LiteCharms.Features/Api/Models/TokenErrorResponse.cs b/LiteCharms.Features/Api/Models/TokenErrorResponse.cs
new file mode 100644
index 0000000..0d31195
--- /dev/null
+++ b/LiteCharms.Features/Api/Models/TokenErrorResponse.cs
@@ -0,0 +1,13 @@
+namespace LiteCharms.Features.Api.Models;
+
+public sealed class TokenErrorResponse
+{
+ [JsonPropertyName("error")]
+ public string? Error { get; set; }
+
+ [JsonPropertyName("error_description")]
+ public string? ErrorDescription { get; set; }
+
+ [JsonPropertyName("error_uri")]
+ public string? ErrorUri { get; set; }
+}
diff --git a/LiteCharms.Features/Api/Models/TokenRequest.cs b/LiteCharms.Features/Api/Models/TokenRequest.cs
new file mode 100644
index 0000000..68b1abc
--- /dev/null
+++ b/LiteCharms.Features/Api/Models/TokenRequest.cs
@@ -0,0 +1,20 @@
+namespace LiteCharms.Features.Api.Models;
+
+public sealed class TokenRequest
+{
+ [JsonPropertyName("grant_type")]
+ [AliasAs("grant_type")]
+ public string? GrantType { get; set; }
+
+ [JsonPropertyName("client_id")]
+ [AliasAs("client_id")]
+ public string? ClientId { get; set; }
+
+ [JsonPropertyName("client_secret")]
+ [AliasAs("client_secret")]
+ public string? ClientSecret { get; set; }
+
+ [JsonPropertyName("scope")]
+ [AliasAs("scope")]
+ public string? Scope { get; set; }
+}
diff --git a/LiteCharms.Features/Api/Models/TokenResponse.cs b/LiteCharms.Features/Api/Models/TokenResponse.cs
new file mode 100644
index 0000000..3fb090a
--- /dev/null
+++ b/LiteCharms.Features/Api/Models/TokenResponse.cs
@@ -0,0 +1,17 @@
+namespace LiteCharms.Features.Api.Models;
+
+public sealed class TokenResponse
+{
+ [JsonPropertyName("access_token")]
+ public string? AccessToken { get; set; }
+
+ [JsonPropertyName("expires_in")]
+ public int ExpiresIn { get; set; }
+
+ [JsonPropertyName("token_type")]
+ public string? TokenType { get; set; }
+
+ [JsonPropertyName("scope")]
+ public string? Scope { get; set; }
+}
+
diff --git a/LiteCharms.Features/Api/Sdk/IConnectApi.cs b/LiteCharms.Features/Api/Sdk/IConnectApi.cs
new file mode 100644
index 0000000..b7d3430
--- /dev/null
+++ b/LiteCharms.Features/Api/Sdk/IConnectApi.cs
@@ -0,0 +1,10 @@
+using LiteCharms.Features.Api.Models;
+
+namespace LiteCharms.Features.Api.Sdk;
+
+public interface IConnectApi
+{
+ [Post("/connect/token")]
+ ValueTask GetToken([Body(BodySerializationMethod.UrlEncoded)] TokenRequest request,
+ CancellationToken cancellationToken = default);
+}
diff --git a/LiteCharms.Features/Api/TokenService.cs b/LiteCharms.Features/Api/TokenService.cs
new file mode 100644
index 0000000..c2dcdfc
--- /dev/null
+++ b/LiteCharms.Features/Api/TokenService.cs
@@ -0,0 +1,67 @@
+using LiteCharms.Features.Abstractions;
+using LiteCharms.Features.Api.Configuration;
+using LiteCharms.Features.Api.Models;
+using LiteCharms.Features.Api.Sdk;
+
+namespace LiteCharms.Features.Api;
+
+public sealed class TokenService(IConnectApi connectApi, IOptions clientOptions) : IService
+{
+ private readonly LiteCharmsClientSettings clientSettings = clientOptions.Value;
+
+ public async Task> GenerateAsync(CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ var request = new TokenRequest
+ {
+ ClientId = clientSettings.ClientId,
+ ClientSecret = clientSettings.ClientSecret,
+ GrantType = clientSettings.GrantType,
+ Scope = clientSettings.Scope,
+ };
+
+ using var response = await connectApi.GetToken(request, cancellationToken);
+
+ var contentRaw = await response.Content.ReadAsStringAsync(cancellationToken);
+
+ if (string.IsNullOrWhiteSpace(contentRaw))
+ return Result.Fail(new Error($"The authentication endpoint returned an empty payload. Status code: {response.StatusCode}"));
+
+ if (response.IsSuccessStatusCode)
+ {
+ var tokenResponse = JsonSerializer.Deserialize(contentRaw);
+
+ return !string.IsNullOrWhiteSpace(tokenResponse?.AccessToken)
+ ? Result.Ok(tokenResponse)
+ : Result.Fail(new Error("Authentication succeeded, but no access token was found in the response payload."));
+ }
+
+ try
+ {
+ var errorResult = JsonSerializer.Deserialize(contentRaw);
+
+ if (errorResult != null)
+ {
+ string summary = $"{errorResult.Error}: {errorResult.ErrorDescription}";
+
+ return Result.Fail(new Error(summary));
+ }
+ }
+ catch
+ {
+ return Result.Fail(new Error($"Authentication failed: {contentRaw}"));
+ }
+
+ return Result.Fail(new Error($"Authentication failed with status code: {response.StatusCode}"));
+ }
+ catch (OperationCanceledException ex)
+ {
+ return Result.Fail(new Error("The token generation request was canceled.").CausedBy(ex));
+ }
+ catch (Exception ex)
+ {
+ return Result.Fail(new Error(ex.Message).CausedBy(ex));
+ }
+ }
+}
\ No newline at end of file
diff --git a/LiteCharms.Features/Extensions/Api.cs b/LiteCharms.Features/Extensions/Api.cs
index 1e60834..9fe6af4 100644
--- a/LiteCharms.Features/Extensions/Api.cs
+++ b/LiteCharms.Features/Extensions/Api.cs
@@ -1,7 +1,7 @@
using LiteCharms.Features.Abstractions;
using LiteCharms.Features.Api;
using LiteCharms.Features.Api.Configuration;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using LiteCharms.Features.Api.Sdk;
namespace LiteCharms.Features.Extensions;
@@ -9,6 +9,36 @@ public static class Api
{
public const string Books = nameof(Books);
public const string Payments = nameof(Payments);
+
+ public static IServiceCollection AddSecurityApiSdk(this IServiceCollection services, IConfiguration configuration)
+ {
+ var configSection = configuration.GetSection(nameof(LiteCharmsClientSettings));
+
+ var authOptions = new LiteCharmsClientSettings();
+ configSection.Bind(authOptions);
+
+ services.Configure(configSection);
+
+ if (string.IsNullOrWhiteSpace(authOptions.Authority))
+ return services;
+
+ if (!authOptions.Authority.EndsWith("/", StringComparison.Ordinal)) authOptions.Authority += "/";
+
+ services.AddRefitClient()
+ .ConfigureHttpClient(config =>
+ {
+ config.BaseAddress = new Uri(authOptions.Authority);
+ config.Timeout = TimeSpan.FromSeconds(15);
+ })
+ .AddStandardResilienceHandler(options =>
+ {
+ options.Retry.MaxRetryAttempts = 3;
+ options.Retry.Delay = TimeSpan.FromSeconds(1);
+ options.Retry.BackoffType = Polly.DelayBackoffType.Exponential;
+ });
+
+ return services;
+ }
public static IServiceCollection AddLiteCharmsWebSecurity(this IServiceCollection services, IConfiguration configuration)
{
diff --git a/LiteCharms.Features/LiteCharms.Features.csproj b/LiteCharms.Features/LiteCharms.Features.csproj
index b2374c2..f0ee577 100644
--- a/LiteCharms.Features/LiteCharms.Features.csproj
+++ b/LiteCharms.Features/LiteCharms.Features.csproj
@@ -37,11 +37,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -183,6 +195,7 @@
+
diff --git a/LiteCharmsShared.slnx b/LiteCharmsShared.slnx
index be7cb5c..de05e99 100644
--- a/LiteCharmsShared.slnx
+++ b/LiteCharmsShared.slnx
@@ -12,6 +12,7 @@
+