using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Prometheus; using StackExchange.Redis; using VoidCat.Model; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; using VoidCat.Services.InMemory; using VoidCat.Services.Migrations; using VoidCat.Services.Paywall; using VoidCat.Services.Redis; using VoidCat.Services.Stats; using VoidCat.Services.Users; var builder = WebApplication.CreateBuilder(args); var services = builder.Services; var configuration = builder.Configuration; var voidSettings = configuration.GetSection("Settings").Get(); services.AddSingleton(voidSettings); services.AddSingleton(voidSettings.Strike ?? new()); var seqSettings = configuration.GetSection("Seq"); builder.Logging.AddSeq(seqSettings); var useRedis = !string.IsNullOrEmpty(voidSettings.Redis); if (useRedis) { var cx = await ConnectionMultiplexer.ConnectAsync(voidSettings.Redis); services.AddSingleton(cx); services.AddSingleton(cx.GetDatabase()); } services.AddCors(opt => { opt.AddDefaultPolicy(p => { p.AllowAnyMethod() .AllowAnyHeader() .WithOrigins(voidSettings.CorsOrigins.Select(a => a.OriginalString).ToArray()); }); }); services.AddRouting(); services.AddControllers().AddNewtonsoftJson((opt) => { opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; opt.SerializerSettings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; opt.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore; }); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new() { ValidateIssuer = true, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = voidSettings.JwtSettings.Issuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(voidSettings.JwtSettings.Key)) }; }); services.AddAuthorization((opt) => { opt.AddPolicy(Policies.RequireAdmin, (auth) => { auth.RequireRole(Roles.Admin); }); }); // void.cat services // services.AddVoidMigrations(); // file storage services.AddTransient(); services.AddTransient(); // stats services.AddTransient(); services.AddTransient(); // paywall services.AddVoidPaywall(); // users services.AddTransient(); services.AddTransient(); if (useRedis) { services.AddTransient(); services.AddTransient(); services.AddTransient(svc => svc.GetRequiredService()); services.AddTransient(svc => svc.GetRequiredService()); } else { services.AddMemoryCache(); services.AddTransient(); services.AddTransient(); services.AddTransient(svc => svc.GetRequiredService()); services.AddTransient(svc => svc.GetRequiredService()); } var app = builder.Build(); // run migrations var migrations = app.Services.GetServices(); foreach (var migration in migrations) { await migration.Migrate(); } #if HostSPA app.UseStaticFiles(); #endif app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(ep => { ep.MapControllers(); ep.MapMetrics(); #if HostSPA ep.MapFallbackToFile("index.html"); #endif }); app.Run();