u
This commit is contained in:
@@ -33,22 +33,38 @@ public static class ConfigureServices
|
|||||||
public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var baseUrl = configuration["GwUrl"];
|
var baseUrl = configuration["GwUrl"];
|
||||||
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
|
|
||||||
httpClient.Timeout = TimeSpan.FromMinutes(10); // TODO Check Timeout
|
|
||||||
var serviceProvider = services.BuildServiceProvider();
|
|
||||||
var channel = CreateAuthenticatedChannel(baseUrl, httpClient, serviceProvider);
|
|
||||||
|
|
||||||
services.AddScoped(sp => new PackageContract.PackageContractClient(channel));
|
// Register optimized HttpClient for gRPC
|
||||||
services.AddScoped(sp => new UserContract.UserContractClient(channel));
|
services.AddScoped(sp =>
|
||||||
services.AddScoped(sp => new UserAddressContract.UserAddressContractClient(channel));
|
{
|
||||||
services.AddScoped(sp => new UserOrderContract.UserOrderContractClient(channel));
|
var handler = new HttpClientHandler
|
||||||
|
{
|
||||||
|
MaxConnectionsPerServer = 10,
|
||||||
|
AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, handler))
|
||||||
|
{
|
||||||
|
Timeout = TimeSpan.FromMinutes(10),
|
||||||
|
BaseAddress = new Uri(baseUrl)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register gRPC clients with authentication
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<PackageContract.PackageContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<UserContract.UserContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<UserAddressContract.UserAddressContractClient>);
|
||||||
|
services.AddScoped(CreateAuthenticatedClient<UserOrderContract.UserOrderContractClient>);
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GrpcChannel CreateAuthenticatedChannel(string address, HttpClient httpClient, IServiceProvider serviceProvider)
|
private static TClient CreateAuthenticatedClient<TClient>(IServiceProvider sp)
|
||||||
|
where TClient : class
|
||||||
{
|
{
|
||||||
var localStorage = serviceProvider.GetRequiredService<ILocalStorageService>();
|
var httpClient = sp.GetRequiredService<HttpClient>();
|
||||||
|
var localStorage = sp.GetRequiredService<ILocalStorageService>();
|
||||||
|
var baseUrl = httpClient.BaseAddress?.ToString() ?? throw new InvalidOperationException("Base URL not configured");
|
||||||
|
|
||||||
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
|
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
|
||||||
{
|
{
|
||||||
@@ -60,15 +76,15 @@ public static class ConfigureServices
|
|||||||
metadata.Add("Authorization", $"Bearer {token}");
|
metadata.Add("Authorization", $"Bearer {token}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Ignore errors during token retrieval
|
#if DEBUG
|
||||||
|
Console.WriteLine($"Token retrieval error: {ex.Message}");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// SslCredentials is used here because this channel is using TLS.
|
var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions
|
||||||
// CallCredentials can't be used with ChannelCredentials.Insecure on non-TLS channels.
|
|
||||||
var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
|
|
||||||
{
|
{
|
||||||
UnsafeUseInsecureChannelCallCredentials = true,
|
UnsafeUseInsecureChannelCallCredentials = true,
|
||||||
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
|
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
|
||||||
@@ -76,6 +92,7 @@ public static class ConfigureServices
|
|||||||
MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB
|
MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB
|
||||||
MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB
|
MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB
|
||||||
});
|
});
|
||||||
return channel;
|
|
||||||
|
return (TClient)Activator.CreateInstance(typeof(TClient), channel)!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,56 +81,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</MudTabPanel>
|
</MudTabPanel>
|
||||||
|
|
||||||
<!-- Password Change Tab -->
|
|
||||||
<MudTabPanel Text="تغییر رمز عبور" Icon="@Icons.Material.Filled.Lock">
|
|
||||||
<div class="pa-4">
|
|
||||||
<MudText Typo="Typo.h6" Class="mb-4 mud-typography-subtitle1">تغییر رمز عبور</MudText>
|
|
||||||
|
|
||||||
<MudForm @ref="_passwordForm" Model="_passwordModel" Validation="@((Func<object, IEnumerable<FluentValidation.Results.ValidationFailure>>)((model) => _passwordValidator.Validate((PasswordChangeModel)model).Errors))">
|
|
||||||
<MudGrid Spacing="3">
|
|
||||||
<MudItem xs="12">
|
|
||||||
<MudTextField @bind-Value="_passwordModel.CurrentPassword"
|
|
||||||
For="@(() => _passwordModel.CurrentPassword)"
|
|
||||||
Label="رمز عبور فعلی"
|
|
||||||
Variant="Variant.Outlined"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
Required="true"
|
|
||||||
RequiredError="وارد کردن رمز عبور فعلی الزامی است." />
|
|
||||||
</MudItem>
|
|
||||||
|
|
||||||
<MudItem xs="12" md="6">
|
|
||||||
<MudTextField @bind-Value="_passwordModel.NewPassword"
|
|
||||||
For="@(() => _passwordModel.NewPassword)"
|
|
||||||
Label="رمز عبور جدید"
|
|
||||||
Variant="Variant.Outlined"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
Required="true"
|
|
||||||
RequiredError="وارد کردن رمز عبور جدید الزامی است." />
|
|
||||||
</MudItem>
|
|
||||||
|
|
||||||
<MudItem xs="12" md="6">
|
|
||||||
<MudTextField @bind-Value="_passwordModel.ConfirmPassword"
|
|
||||||
For="@(() => _passwordModel.ConfirmPassword)"
|
|
||||||
Label="تکرار رمز عبور جدید"
|
|
||||||
Variant="Variant.Outlined"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
Required="true"
|
|
||||||
RequiredError="تکرار رمز عبور جدید الزامی است." />
|
|
||||||
</MudItem>
|
|
||||||
</MudGrid>
|
|
||||||
|
|
||||||
<MudStack Row="true" Spacing="2" Justify="Justify.FlexEnd" Class="mt-4">
|
|
||||||
<MudButton Variant="Variant.Outlined" Color="Color.Secondary" OnClick="CancelPasswordChange">
|
|
||||||
لغو
|
|
||||||
</MudButton>
|
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ChangePassword" Disabled="_isPasswordChanging">
|
|
||||||
تغییر رمز عبور
|
|
||||||
</MudButton>
|
|
||||||
</MudStack>
|
|
||||||
</MudForm>
|
|
||||||
</div>
|
|
||||||
</MudTabPanel>
|
|
||||||
|
|
||||||
<!-- Account Settings Tab -->
|
<!-- Account Settings Tab -->
|
||||||
<MudTabPanel Text="تنظیمات حساب" Icon="@Icons.Material.Filled.Settings">
|
<MudTabPanel Text="تنظیمات حساب" Icon="@Icons.Material.Filled.Settings">
|
||||||
<div class="pa-4">
|
<div class="pa-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user