using System.Globalization; using System.Security.Claims; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Options; using WorkTracker.Components; using WorkTracker.Configuration; using WorkTracker.Services.Auth; using WorkTracker.Services.Festivities; using WorkTracker.Services.Settings; using WorkTracker.Services.Storage; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddCascadingAuthenticationState(); builder.Services.AddAuthorization(); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/login"; options.LogoutPath = "/logout"; options.AccessDeniedPath = "/login"; options.SlidingExpiration = true; options.ExpireTimeSpan = TimeSpan.FromDays(14); }); builder.Services.AddLocalization(); builder.Services.Configure(builder.Configuration.GetSection(CouchbaseLiteOptions.SectionName)); builder.Services.Configure(builder.Configuration.GetSection(SingleUserOptions.SectionName)); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); var app = builder.Build(); var italianCulture = new CultureInfo("it-IT"); CultureInfo.DefaultThreadCurrentCulture = italianCulture; CultureInfo.DefaultThreadCurrentUICulture = italianCulture; var localizationOptions = new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture(italianCulture), SupportedCultures = [italianCulture], SupportedUICultures = [italianCulture] }; // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error", createScopeForErrors: true); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } var useHttpsRedirection = app.Configuration.GetValue("UseHttpsRedirection", !app.Environment.IsDevelopment()); if (useHttpsRedirection) { app.UseHttpsRedirection(); } app.UseRequestLocalization(localizationOptions); app.UseAuthentication(); app.UseAuthorization(); app.UseAntiforgery(); app.MapPost("/login", async (HttpContext context, IAuthService authService) => { var form = await context.Request.ReadFormAsync(); var email = form["email"].ToString(); var password = form["password"].ToString(); var returnUrl = form["returnUrl"].ToString(); if (string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(password)) { return TypedResults.LocalRedirect($"/login?error=Missing%20credentials&returnUrl={Uri.EscapeDataString(returnUrl)}"); } var user = await authService.ValidateCredentialsAsync(email, password, context.RequestAborted); if (user is null) { return TypedResults.LocalRedirect($"/login?error=Invalid%20credentials&returnUrl={Uri.EscapeDataString(returnUrl)}"); } var claims = new List { new(ClaimTypes.NameIdentifier, user.Id), new(ClaimTypes.Name, user.Email) }; var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme)); await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); var safeReturnUrl = string.IsNullOrWhiteSpace(returnUrl) || !Uri.IsWellFormedUriString(returnUrl, UriKind.Relative) ? "/" : returnUrl; return TypedResults.LocalRedirect(safeReturnUrl); }).DisableAntiforgery(); app.MapPost("/logout", async (HttpContext context) => { await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return TypedResults.LocalRedirect("/login"); }).DisableAntiforgery(); app.MapStaticAssets(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); app.Run();