using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Scalar.AspNetCore; using SequenceAuth.Example.Infrastructure; using SequenceAuth.Example.Options; using SequenceAuth.Lib; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(options => { options.Conventions.Add(new RouteTokenTransformerConvention(new KebabCaseParameterTransformer())); }); builder.Services.AddDbContext(options => { options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection") ?? "Host=localhost;Database=sequencedb;Username=sequence_user;Password=sequence_password"); }); builder.Services.AddHttpContextAccessor(); builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly)); var sequenceOptions = new SequenceAuthOptions(); builder.Services.AddSequenceAuth(opts => { opts.IgnoredPaths = sequenceOptions.IgnoredPaths.Concat(["/auth/login"]).ToHashSet(); }); builder.Services.AddOpenApi(); builder.Services.AddCors(options => { options.AddDefaultPolicy(policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .WithExposedHeaders(sequenceOptions.NextHeaderName, sequenceOptions.RequestsRemainingHeaderName); }); }); builder.Services.Configure(builder.Configuration.GetSection("RedisOptions")); builder.Services.AddSingleton(sp => ConnectionMultiplexer.Connect(sp.GetRequiredService>().Value.Configuration)); builder.Services.AddSingleton(); var app = builder.Build(); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); await db.Database.MigrateAsync(); } app.MapOpenApi(); app.MapScalarApiReference(options => { options.Title = "SequenceAuth API"; options.WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient); }); app.MapGet("/", () => Results.Redirect("/scalar/v1")); app.UseCors(); app.UseMiddleware(); app.MapControllers(); app.Run(); public partial class Program { }