- Added role-based permission checks in NavMenu for dashboard and management links. - Created ManualPaymentDialog for creating and managing manual payments. - Implemented TransactionDetailsDialog for displaying transaction details. - Developed Transactions page for viewing and filtering transactions. - Introduced RolePermissionsDialog for managing role permissions. - Established AuthorizationService to handle permission checks and user roles. - Enhanced UI components with MudBlazor for better user experience.
156 lines
8.1 KiB
C#
156 lines
8.1 KiB
C#
using BackOffice.BFF.Otp.Protobuf.Protos.Otp;
|
|
using BackOffice.BFF.Package.Protobuf.Protos.Package;
|
|
using BackOffice.BFF.Role.Protobuf.Protos.Role;
|
|
using BackOffice.BFF.Products.Protobuf.Protos.Products;
|
|
using BackOffice.BFF.User.Protobuf.Protos.User;
|
|
using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress;
|
|
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder;
|
|
using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole;
|
|
using BackOffice.BFF.Category.Protobuf.Protos.Category;
|
|
using BackOffice.BFF.Commission.Protobuf;
|
|
using BackOffice.BFF.NetworkMembership.Protobuf;
|
|
using BackOffice.BFF.ClubMembership.Protobuf;
|
|
using BackOffice.BFF.Configuration.Protobuf;
|
|
using BackOffice.BFF.Health.Protobuf;
|
|
using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct;
|
|
using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory;
|
|
using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder;
|
|
using BackOffice.BFF.Tag.Protobuf.Protos.Tag;
|
|
using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag;
|
|
using BackOffice.BFF.PublicMessage.Protobuf.Protos.PublicMessage;
|
|
using BackOffice.Common.Utilities;
|
|
using BackOffice.Services.DiscountProduct;
|
|
using BackOffice.Services.DiscountCategory;
|
|
using BackOffice.Services.DiscountOrder;
|
|
using BackOffice.Services.PublicMessage;
|
|
using BackOffice.Services.Tag;
|
|
using Blazored.LocalStorage;
|
|
using Grpc.Core;
|
|
using Grpc.Core.Interceptors;
|
|
using Grpc.Net.Client;
|
|
using Grpc.Net.Client.Web;
|
|
using Microsoft.AspNetCore.Components.Authorization;
|
|
using MudBlazor.Services;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
|
|
namespace Microsoft.Extensions.DependencyInjection;
|
|
|
|
public static class ConfigureServices
|
|
{
|
|
public static IServiceCollection AddCommonServices(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
services.AddBlazoredLocalStorageAsSingleton(config =>
|
|
{
|
|
config.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
|
|
config.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
|
config.JsonSerializerOptions.IgnoreReadOnlyProperties = true;
|
|
config.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
|
|
config.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
|
config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
|
|
config.JsonSerializerOptions.WriteIndented = false;
|
|
});
|
|
services.AddAuthorizationCore();
|
|
services.AddScoped<AuthenticationStateProvider, ApiAuthenticationStateProvider>();
|
|
services.AddSingleton<ITokenProvider, AppTokenProvider>();
|
|
services.AddSingleton<ITokenHandler, TokenHandler>();
|
|
services.AddMudServices();
|
|
services.AddGrpcServices(configuration);
|
|
|
|
// Application Services
|
|
services.AddScoped<BackOffice.Services.Authorization.IAuthorizationService, BackOffice.Services.Authorization.AuthorizationService>();
|
|
services.AddScoped<IDiscountProductService, DiscountProductService>();
|
|
services.AddScoped<IDiscountCategoryService, DiscountCategoryService>();
|
|
services.AddScoped<IDiscountOrderService, DiscountOrderService>();
|
|
services.AddScoped<IPublicMessageService, PublicMessageService>();
|
|
services.AddScoped<ITagService, TagService>();
|
|
|
|
return services;
|
|
}
|
|
|
|
|
|
|
|
public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
services.AddSingleton<CallInvoker>(sp =>
|
|
{
|
|
var config = sp.GetRequiredService<IConfiguration>();
|
|
var baseUri = config["GwUrl"];
|
|
|
|
if (string.IsNullOrWhiteSpace(baseUri))
|
|
{
|
|
throw new InvalidOperationException("Configuration value 'GwUrl' is missing or empty.");
|
|
}
|
|
|
|
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()))
|
|
{
|
|
Timeout = TimeSpan.FromMinutes(10)
|
|
};
|
|
|
|
return CreateAuthenticatedChannel(baseUri, httpClient, sp);
|
|
});
|
|
|
|
services.AddTransient(sp => new OtpContract.OtpContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new PackageContract.PackageContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new ProductsContract.ProductsContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new RoleContract.RoleContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new UserContract.UserContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new UserAddressContract.UserAddressContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new UserOrderContract.UserOrderContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new UserRoleContract.UserRoleContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new CategoryContract.CategoryContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
|
|
// CMS Services (Commission, Network, Club, Configuration, Health)
|
|
services.AddTransient(sp => new CommissionContract.CommissionContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new NetworkMembershipContract.NetworkMembershipContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new ClubMembershipContract.ClubMembershipContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new ConfigurationContract.ConfigurationContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new HealthContract.HealthContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
|
|
// Discount Shop Services
|
|
services.AddTransient(sp => new DiscountProductsContract.DiscountProductsContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new DiscountCategoriesContract.DiscountCategoriesContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new DiscountOrdersContract.DiscountOrdersContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
|
|
// Public Message Service
|
|
services.AddTransient(sp => new PublicMessagesContract.PublicMessagesContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
|
|
// Tag Management Services
|
|
services.AddTransient(sp => new TagContract.TagContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
services.AddTransient(sp => new ProductTagContract.ProductTagContractClient(sp.GetRequiredService<CallInvoker>()));
|
|
|
|
return services;
|
|
}
|
|
|
|
private static CallInvoker CreateAuthenticatedChannel(string address, HttpClient httpClient, IServiceProvider serviceProvider)
|
|
{
|
|
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
|
|
{
|
|
var provider = serviceProvider.GetRequiredService<ITokenProvider>();
|
|
// var accessToken = await provider.RequestAccessToken();
|
|
// accessToken.TryGetToken(out var token);
|
|
var token = await provider.GetTokenAsync();
|
|
if (!string.IsNullOrEmpty(token))
|
|
{
|
|
// Console.WriteLine($"Authorization Bearer {token.Value}");
|
|
metadata.Add("Authorization", $"Bearer {token}");
|
|
}
|
|
|
|
await Task.CompletedTask;
|
|
});
|
|
|
|
// SslCredentials is used here because this channel is using TLS.
|
|
// CallCredentials can't be used with ChannelCredentials.Insecure on non-TLS channels.
|
|
var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
|
|
{
|
|
UnsafeUseInsecureChannelCallCredentials = true,
|
|
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
|
|
HttpClient = httpClient,
|
|
MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB
|
|
MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB
|
|
});
|
|
return channel.Intercept(new ErrorHandlerInterceptor());
|
|
}
|
|
}
|