using DigitalData.UserManager.Infrastructure.Repositories; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.MappingProfiles; using EnvelopeGenerator.Application.Services; using EnvelopeGenerator.Infrastructure.Contracts; using EnvelopeGenerator.Infrastructure.Repositories; using EnvelopeGenerator.Web.Services; using Microsoft.EntityFrameworkCore; using NLog; using Quartz; using NLog.Web; using DigitalData.Core.API; using Microsoft.AspNetCore.Authentication.Cookies; using DigitalData.UserManager.Application.MappingProfiles; using EnvelopeGenerator.Web.Models; using DigitalData.Core.DTO; using Microsoft.Extensions.Localization; var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); logger.Info("Logging initialized!"); try { var builder = WebApplication.CreateBuilder(args); var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get() ?? throw new InvalidOperationException("AllowedOrigins section is missing in the configuration."); builder.Services.AddCors(options => { options.AddPolicy("SameOriginPolicy", builder => { builder.WithOrigins(allowedOrigins) .SetIsOriginAllowedToAllowWildcardSubdomains() .AllowCredentials() .AllowAnyMethod() .AllowAnyHeader(); }); }); builder.Logging.ClearProviders(); builder.Host.UseNLog(); // Add base services builder.Services.AddScoped(); // Add higher order services builder.Services.AddScoped(); // Add controllers and razor views builder.Services.AddControllersWithViews(options => { //remove option for Test*Controller options.Conventions.Add(new RemoveIfControllerConvention() .AndIf(c => c.ControllerName.StartsWith("Test")) .AndIf(c => !builder.Configuration.GetValue("AddTestControllers"))); }).AddJsonOptions(q => { // Prevents serialization error when serializing SvgBitmap in EnvelopeReceiver q.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //AddEF Core dbcontext var connStr = builder.Configuration["Config:ConnectionString"]; builder.Services.AddDbContext(options => options.UseSqlServer(connStr)); //Inject CRUD Service and repositoriesad builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); //Auto mapping profiles builder.Services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly); builder.Services.AddAutoMapper(typeof(UserMappingProfile).Assembly); builder.Services.Configure(options => { options.CheckConsentNeeded = context => { var consentCookie = context.Request.Cookies["cookie-consent-settings"]; return consentCookie != "necessary=false"; }; options.MinimumSameSitePolicy = SameSiteMode.Strict; options.ConsentCookie.Name = "cookie-consent-settings"; }); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites options.Events = new CookieAuthenticationEvents { OnRedirectToLogin = context => { // Dynamically calculate the redirection path, for example: var envelopeReceiverId = context.HttpContext.Request.RouteValues["envelopeReceiverId"]; context.RedirectUri = $"/EnvelopeKey/{envelopeReceiverId}/Locked"; context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; }, OnRedirectToLogout = context => { // Apply a similar redirection logic for logout var envelopeReceiverId = context.HttpContext.Request.RouteValues["envelopeReceiverId"]; context.RedirectUri = $"/EnvelopeKey/{envelopeReceiverId}/Success"; context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; } }; }); builder.Services.AddSingleton(_ => builder.Configuration.GetSection("ContactLink").Get() ?? new ContactLink()); builder.Services.AddCookieConsentSettings(); builder.Services.AddCookieBasedLocalizer(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseCookieBasedLocalizer("de_DE", "en_US"); app.UseCors("SameOriginPolicy"); app.MapControllers(); app.MapFallbackToController("Error404", "Home"); app.Run(); } catch(Exception ex) { logger.Error(ex, "Stopped program because of exception"); throw; }