Files
Backend-Api/ServiceHost/Program.cs
mahan 8fc798746f Refactor error handling and IHttpContextAccessor usage
Simplified error message construction in RoleApplication.cs by
removing redundant properties. Refactored IHttpContextAccessor
registration in Program.cs to use the service provider after
app initialization. Removed redundant no-op code in
NullFaceEmbeddingNotificationService.cs.
2025-11-27 12:45:18 +03:30

462 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using _0_Framework.Application.Sms;
using _0_Framework.Application;
using AccountManagement.Configuration;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;
using PersonalContractingParty.Config;
using ServiceHost;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Query.Bootstrapper;
using ServiceHost.Hubs;
using ServiceHost.MiddleWare;
using WorkFlow.Infrastructure.Config;
using _0_Framework.Application.UID;
using _0_Framework.Exceptions.Handler;
using _0_Framework.Application.FaceEmbedding;
using Microsoft.OpenApi.Models;
using ServiceHost.Test;
using System.Text.Json.Serialization;
using System.Text.Json;
using _0_Framework.InfraStructure.Mongo;
using Bogus;
using CompanyManagment.App.Contracts.Hubs;
using CompanyManagment.EFCore.Services;
using Microsoft.AspNetCore.CookiePolicy;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Diagnostics;
using MongoDB.Driver;
using Parbad.Builder;
using Parbad.Gateway.Sepehr;
using Swashbuckle.AspNetCore.SwaggerUI;
using AccountManagement.Domain.InternalApiCaller;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions => { serverOptions.Limits.MaxRequestBodySize = long.MaxValue; });
builder.Services.AddRazorPages()
.AddRazorRuntimeCompilation();
//Register Services
//test
#region Register Services
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient("holidayApi", c => c.BaseAddress = new System.Uri("https://api.github.com"));
var connectionString = builder.Configuration.GetConnectionString("MesbahDb");
var connectionStringTestDb = builder.Configuration.GetConnectionString("TestDb");
#region MongoDb
var mongoConnectionSection = builder.Configuration.GetSection("MongoDb");
var mongoDbSettings = mongoConnectionSection.Get<MongoDbConfig>();
var mongoClient = new MongoClient(mongoDbSettings.ConnectionString);
var mongoDatabase = mongoClient.GetDatabase(mongoDbSettings.DatabaseName);
builder.Services.AddSingleton<IMongoDatabase>(mongoDatabase);
#endregion
builder.Services.AddSingleton<IActionResultExecutor<JsonResult>, CustomJsonResultExecutor>();
PersonalBootstrapper.Configure(builder.Services, connectionString);
TestDbBootStrapper.Configure(builder.Services, connectionStringTestDb);
AccountManagementBootstrapper.Configure(builder.Services, connectionString);
WorkFlowBootstrapper.Configure(builder.Services, connectionString);
QueryBootstrapper.Configure(builder.Services);
builder.Services.AddSingleton<IPasswordHasher, PasswordHasher>();
builder.Services.AddTransient<IFileUploader, FileUploader>();
builder.Services.AddTransient<IAuthHelper, AuthHelper>();
builder.Services.AddTransient<IGoogleRecaptcha, GoogleRecaptcha>();
builder.Services.AddTransient<ISmsService, SmsService>();
builder.Services.AddTransient<IUidService, UidService>();
builder.Services.AddTransient<IFaceEmbeddingNotificationService, FaceEmbeddingNotificationService>();
//services.AddSingleton<IWorkingTest, WorkingTest>();
//services.AddHostedService<JobWorker>();
#region Mahan
builder.Services.AddTransient<Tester>();
builder.Services.Configure<AppSettingConfiguration>(builder.Configuration);
#endregion
builder.Services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
options.KeyLengthLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = long.MaxValue;
options.MemoryBufferThreshold = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
});
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
//options.MinimumSameSitePolicy = SameSiteMode.Strict;
});
var domain = builder.Configuration["Domain"];
builder.Services.ConfigureApplicationCookie(options =>
{
//options.Cookie.Name = "GozarAuth";
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.None; // مهم ✅
options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // فقط روی HTTPS کار می‌کنه ✅
options.Cookie.Domain = domain; // دامنه مشترک بین پدر و ساب‌دامین‌ها ✅
});
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, o =>
{
o.LoginPath = new PathString("/");
o.LogoutPath = new PathString("/index");
o.AccessDeniedPath = new PathString("/AccessDenied");
o.ExpireTimeSpan = TimeSpan.FromHours(10);
o.SlidingExpiration = true;
});
//services.AddAuthorization(options =>
// options.AddPolicy("AdminArea", builder =>builder.RequireRole(Roles.role)));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminArea",
builder => builder.RequireClaim("AccountId"));
options.AddPolicy("AdminArea",
builder => builder.RequireClaim("AdminAreaPermission", new List<string> { "true" }));
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ClientArea",
builder => builder.RequireClaim("AccountId"));
options.AddPolicy("ClientArea",
builder => builder.RequireClaim("ClientAriaPermission", new List<string> { "true" }));
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CameraArea",
builder => builder.RequireClaim("AccountId"));
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminNewArea",
builder => builder.RequireClaim("AccountId"));
options.AddPolicy("AdminNewArea",
builder => builder.RequireClaim("AdminAreaPermission", new List<string> { "true" }));
});
//services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
// .AddCookie(option =>
// {
// option.LoginPath = "/Index";
// option.LogoutPath = "/Index";
// option.ExpireTimeSpan = TimeSpan.FromDays(1);
// });
builder.Services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
//builder.Services.AddControllers(
//options=> {
// options.Filters.Add(new ApiJsonEnumFilter());
//});
builder.Services.AddRazorPages(options =>
options.Conventions.AuthorizeAreaFolder("Admin", "/", "AdminArea"));
builder.Services.AddRazorPages(options =>
options.Conventions.AuthorizeAreaFolder("Client", "/", "ClientArea"))
.AddMvcOptions(options => options.Filters.Add<SecurityPageFilter>());
builder.Services.AddRazorPages(options =>
options.Conventions.AuthorizeAreaFolder("Camera", "/", "CameraArea"));
builder.Services.AddRazorPages(options =>
options.Conventions.AuthorizeAreaFolder("AdminNew", "/", "AdminNewArea"));
builder.Services.AddMvc();
builder.Services.AddSignalR();
#endregion
#region PWA
//old
//builder.Services.AddProgressiveWebApp();
//new
//builder.Services.AddProgressiveWebApp(new PwaOptions
//{
// RegisterServiceWorker = true,
// RegisterWebmanifest = true,
// Strategy = ServiceWorkerStrategy.NetworkFirst,
//});
#endregion
#region Swagger
builder.Services.AddSwaggerGen(options =>
{
options.UseInlineDefinitionsForEnums();
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
// Get XML comments from the class library
var classLibraryXmlFile = "CompanyManagment.App.Contracts.xml";
var classLibraryXmlPath = Path.Combine(AppContext.BaseDirectory, classLibraryXmlFile);
options.IncludeXmlComments(classLibraryXmlPath);
options.SwaggerDoc("General", new OpenApiInfo { Title = "API - General", Version = "v1" });
options.SwaggerDoc("Admin", new OpenApiInfo { Title = "API - Admin", Version = "v1" });
options.SwaggerDoc("Client", new OpenApiInfo { Title = "API - Client", Version = "v1" });
options.SwaggerDoc("Camera", new OpenApiInfo { Title = "API - Camera", Version = "v1" });
options.DocInclusionPredicate((docName, apiDesc) =>
string.Equals(docName, apiDesc.GroupName, StringComparison.OrdinalIgnoreCase));
// اضافه کردن پشتیبانی از JWT در Swagger
options.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
{
Name = "Authorization",
Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = Microsoft.OpenApi.Models.ParameterLocation.Header,
Description = "لطفاً 'Bearer [space] token' را وارد کنید."
});
options.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
{
{
new Microsoft.OpenApi.Models.OpenApiSecurityScheme
{
Reference = new Microsoft.OpenApi.Models.OpenApiReference
{
Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
options.EnableAnnotations();
});
#endregion
#region CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigins", policy =>
{
policy.WithOrigins(
"http://localhost:3000",
"http://localhost:4000",
"http://localhost:4001",
"http://localhost:3001",
"https://gozareshgir.ir",
"https://dad-mehr.ir",
"https://admin.dad-mehr.ir",
"https://client.dad-mehr.ir",
"https://admin.gozareshgir.ir",
"https://client.gozareshgir.ir",
"https://admin.dadmehrg.ir",
"https://client.dadmehrg.ir"
)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//builder.Services.AddCors(options =>
//{
// options.AddPolicy("AllowAny", policy =>
// {
// policy.AllowAnyOrigin()
// .AllowAnyHeader()
// .AllowAnyMethod();
// });
// options.AddPolicy("AllowSpecificOrigins", policy =>
// {
// policy.WithOrigins("http://localhost:3000", "http://localhost:3001", "https://gozareshgir.ir", "https://dad-mehr.ir")
// .AllowAnyHeader()
// .AllowAnyMethod()
// .AllowCredentials();
// });
//});
#endregion
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var sepehrTerminalId = builder.Configuration.GetValue<long>("SepehrGateWayTerminalId");
builder.Services.AddParbad().ConfigureGateways(gateways =>
{
gateways.AddSepehr().WithAccounts(accounts =>
{
accounts.AddInMemory(account =>
{
account.TerminalId = sepehrTerminalId;
account.Name="Sepehr Account";
});
});
}).ConfigureHttpContext(httpContext=>httpContext.UseDefaultAspNetCore())
.ConfigureStorage(storage =>
{
storage.UseMemoryCache();
});
var app = builder.Build();
#region GetHttpContext
var httpContextAccessor = app.Services.GetRequiredService<IHttpContextAccessor>();
#endregion
app.UseCors("AllowSpecificOrigins");
#region InternalProgarmManagerApi
// بعد از Build:
var host = httpContextAccessor.HttpContext?.Request.Host.Host ?? "";
// مقداردهی BaseUrl
string baseUrl;
if (host.Contains("localhost"))
{
baseUrl = builder.Configuration["InternalApi:Local"];
}
else if (host.Contains("dadmehrg"))
{
baseUrl = builder.Configuration["InternalApi:Dadmehrg"];
}
else if (host.Contains("gozareshgir"))
{
baseUrl = builder.Configuration["InternalApi:Gozareshgir"];
}
else
{
baseUrl = builder.Configuration["InternalApi:Local"]; // fallback
}
// مقداردهی به کلاس Static
InternalApiCaller.SetBaseUrl(baseUrl);
#endregion
#region Mahan
//app.UseStatusCodePagesWithRedirects("/error/{0}");
//the backend Tester
if (builder.Environment.IsDevelopment())
{
using var scope = app.Services.CreateScope();
var tester = scope.ServiceProvider.GetRequiredService<Tester>();
await tester.Test();
}
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.DocExpansion(DocExpansion.None);
options.SwaggerEndpoint("/swagger/General/swagger.json", "API - General");
options.SwaggerEndpoint("/swagger/Admin/swagger.json", "API - Admin");
options.SwaggerEndpoint("/swagger/Client/swagger.json", "API - Client");
options.SwaggerEndpoint("/swagger/Camera/swagger.json", "API - Camera");
});
}
#endregion
//Create Http Pipeline
#region Create Http Pipeline
if (builder.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for pro
app.UseHsts();
}
app.UseExceptionHandler(options => { }); // این خط CustomExceptionHandler رو فعال می‌کنه
app.UseRouting();
app.UseWebSockets();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
#region Mahan
//app.UseLoginHandlerMiddleware();
//app.UseCheckTaskMiddleware();
app.UseMiddleware<RazorJsonEnumOverrideMiddleware>();
#endregion
app.MapHub<CreateContractTarckingHub>("/trackingHub");
app.MapHub<SendAccountMessage>("/trackingSmsHub");
app.MapHub<HolidayApiHub>("/trackingHolidayHub");
app.MapHub<CheckoutHub>("/trackingCheckoutHub");
// app.MapHub<FaceEmbeddingHub>("/trackingFaceEmbeddingHub");
app.MapHub<SendSmsHub>("/trackingSendSmsHub");
app.MapRazorPages();
app.MapControllers();
#endregion
app.Run();