using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.EntityFrameworkCore; using Shogi.Api; using Shogi.Api.Application; using Shogi.Api.Controllers; using Shogi.Api.Identity; using Shogi.Api.Repositories; var builder = WebApplication.CreateBuilder(args); var allowedOrigins = builder .Configuration .GetSection("Cors:AllowedOrigins") .Get() ?? throw new InvalidOperationException("Configuration for allowed origins is missing."); builder.Services .AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.WriteIndented = true; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddHttpClient(); builder.Services.Configure(builder.Configuration.GetSection("ApiKeys")); AddIdentity(builder, builder.Configuration); builder.Services.AddSignalR(); builder.Services.AddResponseCompression(opts => { opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(["application/octet-stream"]); }); var app = builder.Build(); app.MyMapIdentityApi(builder.Environment); if (app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); // Apache handles HTTPS in production. } else { app.UseResponseCompression(); } app.UseSwagger(); app.UseSwaggerUI(options => options.DocumentTitle = "Shogi.Api"); app.UseAuthorization(); app.Map("/", () => "OK"); app.MapControllers(); app.UseCors(policy => { policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod().AllowCredentials(); }); app.MapHub("/gamehub"); app.Run(); static void AddIdentity(WebApplicationBuilder builder, ConfigurationManager configuration) { builder.Services .AddAuthorizationBuilder() .AddPolicy("Admin", policy => { policy.RequireAuthenticatedUser(); policy.RequireAssertion(context => context.User?.Identity?.Name switch { "Hauth@live.com" => true, "aat-account" => true, _ => false }); }); builder.Services .AddDbContext(options => { var cs = configuration.GetConnectionString("ShogiDatabase") ?? throw new InvalidOperationException("Database not configured."); options.UseSqlServer(cs); // This is helpful to debug account issues without affecting the database. //options.UseInMemoryDatabase("AppDb"); }) .AddIdentityApiEndpoints(options => { options.SignIn.RequireConfirmedEmail = true; options.User.RequireUniqueEmail = true; }) .AddEntityFrameworkStores(); builder.Services.ConfigureApplicationCookie(options => { options.SlidingExpiration = true; options.ExpireTimeSpan = TimeSpan.FromDays(3); }); }