global using System.Text.Json; global using System.Text.Json.Serialization; global using Microsoft.EntityFrameworkCore; global using NetTopologySuite.IO.Converters; global using Microsoft.EntityFrameworkCore.Metadata.Builders; global using NetTopologySuite.Geometries; global using Microsoft.AspNetCore.Http.Extensions; global using Microsoft.AspNetCore.Mvc; global using NetTopologySuite; global using WhatApi.Database.Tables; global using WhatApi.Database; global using System.Text; global using WhatApi.Extras; global using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Npgsql; using WhatApi; using WhatApi.Middleware; var builder = WebApplication.CreateBuilder(args); var dev = builder.Environment.IsDevelopment(); builder.Services.AddHttpContextAccessor(); builder.Services.AddDbContextPool(b => { var connectionString = builder.Configuration.GetValue(Constants.Env.MasterDbConnectionString); var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString); dataSourceBuilder.EnableDynamicJson(); if (dev) { b.EnableSensitiveDataLogging(); dataSourceBuilder.EnableParameterLogging(); dataSourceBuilder.UseNetTopologySuite(); } b.UseNpgsql(dataSourceBuilder.Build(), o => { o.EnableRetryOnFailure(); o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); o.UseNetTopologySuite(); }); }); if (dev) builder.Configuration["DISABLE_AUDIT_TRAILS"] = "true"; builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())); var tokenEntropy = builder.Configuration.GetValue(Constants.Env.TokenEntropy); ArgumentException.ThrowIfNullOrEmpty(tokenEntropy); var tokenIssuer = builder.Configuration.GetValue(Constants.Env.TokenIssuer); var tokenAudience = builder.Configuration.GetValue(Constants.Env.TokenAudience); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = tokenIssuer, ValidAudience = tokenAudience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(tokenEntropy)), ClockSkew = TimeSpan.Zero }; }); builder.Services.AddAuthorization(); builder.Services.AddControllers() .AddJsonOptions(o => { o.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; o.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals; o.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; o.JsonSerializerOptions.Converters.Add(new GeoJsonConverterFactory()); }); var app = builder.Build(); if (dev) { using var scope = app.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); Seed.Full(db, opt => { opt.ClearTables = false; }); } app.UseRouting(); app.UseForwardedHeaders(); app.UseCors(); app.MapStaticAssets(); app.UseMiddleware(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapGet("/", () => Results.Redirect("/map")); app.Run(); return 0;