using AspNetCore.ReCaptcha; using Markdig; using OliverBooth.Common.Services; using OliverBooth.Data.Blog; using OliverBooth.Data.Web; using OliverBooth.Extensions; using OliverBooth.Extensions.Markdig; using OliverBooth.Extensions.Markdig.Markdown.Timestamp; using OliverBooth.Extensions.Markdig.Services; using OliverBooth.Services; using Serilog; Log.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/latest.log", rollingInterval: RollingInterval.Day) #if DEBUG .MinimumLevel.Debug() #endif .CreateLogger(); WebApplicationBuilder builder = WebApplication.CreateBuilder(args); builder.Configuration.AddTomlFile("data/config.toml", true, true); builder.Logging.ClearProviders(); builder.Logging.AddSerilog(); builder.Services.AddSingleton(provider => new MarkdownPipelineBuilder() .Use() .UseTemplates(provider.GetRequiredService()) // we have our own "alert blocks" .UseCallouts() // advanced extensions. add explicitly to avoid UseAlertBlocks .UseAbbreviations() .UseAutoIdentifiers() .UseCitations() .UseCustomContainers() .UseDefinitionLists() .UseEmphasisExtras() .UseFigures() .UseFooters() .UseFootnotes() .UseGridTables() .UseMathematics() .UseMediaLinks() .UsePipeTables() .UseListExtras() .UseTaskLists() .UseDiagrams() .UseAutoLinks() .UseGenericAttributes() // must be last as it is one parser that is modifying other parsers // no more advanced extensions .UseBootstrap() .UseEmojiAndSmiley() .UseSmartyPants() .Build()); builder.Services.AddDbContextFactory(); builder.Services.AddDbContextFactory(); builder.Services.AddHttpClient(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddRazorPages(); builder.Services.AddControllersWithViews(); builder.Services.AddRouting(options => options.LowercaseUrls = true); builder.Services.AddReCaptcha(builder.Configuration.GetSection("ReCaptcha")); if (builder.Environment.IsProduction()) { builder.WebHost.AddCertificateFromEnvironment(2845, 5049); } WebApplication app = builder.Build(); app.Use(async (ctx, next) => { await next(); if (ctx.Response.HasStarted) { return; } string? originalPath = ctx.Request.Path.Value; ctx.Items["originalPath"] = originalPath; bool matchedErrorPage = false; switch (ctx.Response.StatusCode) { case 400: ctx.Request.Path = "/error/401"; matchedErrorPage = true; break; case 403: ctx.Request.Path = "/error/403"; matchedErrorPage = true; break; case 404: ctx.Request.Path = "/error/404"; matchedErrorPage = true; break; case 410: ctx.Request.Path = "/error/410"; matchedErrorPage = true; break; case 418: ctx.Request.Path = "/error/418"; matchedErrorPage = true; break; case 429: ctx.Request.Path = "/error/429"; matchedErrorPage = true; break; case 500: ctx.Request.Path = "/error/500"; matchedErrorPage = true; break; case 503: ctx.Request.Path = "/error/503"; matchedErrorPage = true; break; case 504: ctx.Request.Path = "/error/504"; matchedErrorPage = true; break; } if (matchedErrorPage) { await next(); } }); app.UseStatusCodePagesWithReExecute("/error/{0}"); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error/500"); // 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.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.MapRazorPages(); app.Run();