using Azure.Identity; using Hutopy.Web; using Hutopy.Web.Features.Contents; using Hutopy.Web.Features.Contents.Data; using Hutopy.Web.Features.Memberships; using Hutopy.Web.Features.Memberships.Data; using Hutopy.Web.Features.Messages; using Hutopy.Web.Features.Messages.Data; using Hutopy.Web.Features.Users; using Hutopy.Web.Features.Users.Data; using Microsoft.AspNetCore.HttpOverrides; using NSwag; using NSwag.Generation.AspNetCore.Processors; using NSwag.Generation.Processors.Security; var builder = WebApplication.CreateBuilder(args); if (!builder.Environment.IsDevelopment()) { var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri") ?? ""); builder.Configuration.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential()); } builder.Services.AddCors(options => { options.AddPolicy("AllowAll", policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); options.AddPolicy("AllowHutopyUi", policy => { policy.WithOrigins("https://jolly-stone-078869d0f.5.azurestaticapps.net") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); options.AddPolicy("AllowHutopyUiPreview", policy => { policy.WithOrigins("https://zealous-bay-08204590f-preview.eastus2.5.azurestaticapps.net") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); // Add services to the container. builder.Services.AddKeyVaultIfConfigured(builder.Configuration); builder.Services.AddWebServices(); builder.Services.AddAuthorizationAndAuthentication(builder.Configuration); // TODO: This old tech should be remove - need to move Facebook / Google controllers to FastEndpoints builder.Services.AddControllers(); builder.Services.AddOpenApiDocument(( configure, sp) => { configure.Title = "Hutopy API"; // Add JWT configure.AddSecurity( "JWT", [], new OpenApiSecurityScheme { Type = OpenApiSecuritySchemeType.ApiKey, Name = "Authorization", In = OpenApiSecurityApiKeyLocation.Header, Description = "Type into the textbox: Bearer {your JWT token}.", }); configure.OperationProcessors.Add(new AspNetCoreOperationTagsProcessor()); configure.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT")); }); var postgresConnectionString = builder.Configuration.GetConnectionString("PostgresConnection") ?? throw new InvalidOperationException("Missing ConnectionStrings:PostgresConnection"); builder.Services.AddFastEndpoints(); builder.Services.AddUsersModule(options => options.UseNpgsql( postgresConnectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", ApplicationDbContext.SchemaName))); builder.Services.AddContentModule(options => options.UseNpgsql( postgresConnectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", ContentDbContext.SchemaName))); builder.Services.AddMessagingModule(options => options.UseNpgsql( postgresConnectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", MessagingDbContext.SchemaName))); builder.AddMembershipModule( options => options.UseNpgsql( postgresConnectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", MembershipDbContext.SchemaName))); builder.Services.Configure(builder.Configuration.GetRequiredSection(JwtOptions.SectionName)); var app = builder.Build(); app.UseForwardedHeaders( new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto } ); app.UseCors("AllowAll"); app.UseCors("AllowHutopyUi"); app.UseCors("AllowHutopyUiPreview"); app.UseAuthentication(); app.UseAuthorization(); // Initialize and seed the db. await app.InitialiseApplicationDatabaseAsync(); await app.InitialiseContentDbContextAsync(); await app.InitialiseMessagingDbContextAsync(); await app.InitialiseMembershipDbContextAsync(); await app.SeedDatabaseWithTestDataOnlyIfNoDataIsPresentAsync(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { // 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.UseHealthChecks("/health"); app.UseHttpsRedirection(); app.UseStaticFiles(); if (app.Environment.IsDevelopment()) { app.UseOpenApi(); app.UseSwaggerUi(options => options.Path = "/api"); } app.MapControllerRoute( name: "default", pattern: "{controller}/{action=Index}/{id?}"); app.UseFastEndpoints(); app.Run(); namespace Hutopy.Web { public abstract partial class Program { } }