NonInventPurchasingSystem/CPRNIMS.WebApps/Common/ServiceExtensions.cs
2026-06-18 16:51:31 +08:00

184 lines
8.1 KiB
C#

using CPRNIMS.Domain.Contracts.Reports;
using CPRNIMS.Domain.UIContracts.Account;
using CPRNIMS.Domain.UIContracts.Canvass;
using CPRNIMS.Domain.UIContracts.CaptCha;
using CPRNIMS.Domain.UIContracts.Common;
using CPRNIMS.Domain.UIContracts.Finance;
using CPRNIMS.Domain.UIContracts.Inventory;
using CPRNIMS.Domain.UIContracts.Items;
using CPRNIMS.Domain.UIContracts.PO;
using CPRNIMS.Domain.UIContracts.PR;
using CPRNIMS.Domain.UIContracts.Receiving;
using CPRNIMS.Domain.UIContracts.SMTP;
using CPRNIMS.Domain.UIServices.Account;
using CPRNIMS.Domain.UIServices.Canvass;
using CPRNIMS.Domain.UIServices.CaptCha;
using CPRNIMS.Domain.UIServices.Common;
using CPRNIMS.Domain.UIServices.Finance;
using CPRNIMS.Domain.UIServices.Inventory;
using CPRNIMS.Domain.UIServices.Items;
using CPRNIMS.Domain.UIServices.PO;
using CPRNIMS.Domain.UIServices.PR;
using CPRNIMS.Domain.UIServices.Receiving;
using CPRNIMS.Domain.UIServices.SMTP;
using CPRNIMS.Infrastructure.Database;
using CPRNIMS.Infrastructure.Helper;
using CPRNIMS.Infrastructure.Reports;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.EntityFrameworkCore;
namespace CPRNIMS.WebApps.Common
{
public static class ServiceExtensions
{
public static void AddApplicationServices(this IServiceCollection services,
WebApplicationBuilder builder)
{
ConfigureHttpClient(builder);
AddScopedServices(builder);
AddSessionAndAuthentication(builder);
AddDbContext(builder);
FileSizeHelper(builder);
CacheUpdater(services);
}
private static void CacheUpdater(IServiceCollection services)
{
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddSignalR();
}
private static void FileSizeHelper(WebApplicationBuilder builder)
{
builder.Services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
options.MultipartBodyLengthLimit = long.MaxValue;
options.MemoryBufferThreshold = int.MaxValue;
});
}
private static void ConfigureHttpClient(WebApplicationBuilder builder)
{
builder.Services.AddHttpClient("AuthApi", client =>
{
client.BaseAddress = new Uri(builder.Configuration["CommonEndpoints:ApiDefaultHeaders:BaseUrl"]);
//This code block should be removed once deployed in production
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
});
}
private static void AddScopedServices(WebApplicationBuilder builder)
{
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IApiConfigurationService, ApiConfigurationService>();
builder.Services.AddScoped<TokenHelper>();
builder.Services.AddTransient<IItem, Item>();
builder.Services.AddTransient<IPRequest, PRequest>();
builder.Services.AddTransient<ICanvass, Canvass>();
builder.Services.AddTransient<IRR, RR>();
builder.Services.AddTransient<IReceiving, Receiving>();
builder.Services.AddTransient<ISMTP, SMTP>();
builder.Services.AddTransient<IInventory, Inventory>();
builder.Services.AddTransient<IPurchaseOrder, PurchaseOrder>();
builder.Services.AddTransient<ICustomPOService, CustomPOService>();
builder.Services.AddTransient<Domain.UIContracts.Attachment.IAttachment, Domain.UIServices.Attachment.Attachment>();
builder.Services.AddTransient<IAccount, Account>();
builder.Services.AddTransient<ICaptchaService, CaptchaService>();
builder.Services.AddScoped<ErrorLogHelper>();
builder.Services.AddScoped<IRIS, RIS>();
builder.Services.AddScoped<IMRS, MRS>();
builder.Services.AddScoped<IReportBuilder, ReportBuilder>();
builder.Services.AddScoped<IInventoryReports, InventoryReports>();
}
private static void AddSessionAndAuthentication(WebApplicationBuilder builder)
{
builder.Services.AddDistributedMemoryCache();
// Configure Session with proper settings
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromHours(2);
options.Cookie.Name = ".CPRNIMS.Session";
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
// Configure Authentication
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.LoginPath = "/Home/Index";
options.LogoutPath = "/Home/Logout";
options.AccessDeniedPath = "/Home/AccessDenied";
options.Cookie.Name = ".CPRNIMS.Auth";
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromHours(2);
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.IsEssential = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = async context =>
{
var tokenExpiryClaim = context.Principal?.FindFirst("TokenExpiry");
if (tokenExpiryClaim != null)
{
if (DateTime.TryParse(tokenExpiryClaim.Value, out DateTime expiry))
{
if (DateTime.UtcNow.AddMinutes(5) >= expiry)
{
// Token is expiring soon - trigger refresh
var tokenHelper = context.HttpContext.RequestServices
.GetRequiredService<Infrastructure.Helper.TokenHelper>();
var newToken = await tokenHelper.GetValidTokenAsync();
if (string.IsNullOrEmpty(newToken))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
}
},
OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api"))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
}
else
{
context.Response.Redirect(context.RedirectUri);
}
return Task.CompletedTask;
}
};
});
}
private static void AddDbContext(WebApplicationBuilder builder)
{
builder.Services.AddDbContext<NonInventoryDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
}
}
}