using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using QuotifyBE.Controllers; using QuotifyBE.Data; using System.Reflection; using System.Text; var builder = WebApplication.CreateBuilder(args); // Configure Database Connection var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); builder.Services.AddDbContext(options => options.UseNpgsql(connectionString)); var JwtSecret = builder.Configuration["JwtSecret"] ?? throw new InvalidOperationException("JWT token secret is not configured!!! Please configure JwtSecret in appsettings.json!"); var DomainName = builder.Configuration["DomainName"] ?? throw new InvalidOperationException("Domain name is not configured!!! Please configure DomainName in appsettings.json!"); var CorsOrigins = builder.Configuration.GetSection("CorsOrigins").Get>() ?? throw new InvalidOperationException("CORS is not configured!!! Please configure CorsOrigins in appsettings.json!"); // Add default CORS policy builder.Services.AddCors(options => { options.AddDefaultPolicy( policy => { policy .WithOrigins(CorsOrigins.ToArray()) .AllowAnyHeader(); // this might not be the greatest idea }); }); // Configure JWT authentication // https://medium.com/@solomongetachew112/jwt-authentication-in-net-8-a-complete-guide-for-secure-and-scalable-applications-6281e5e8667c builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = DomainName, ValidAudience = DomainName, IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(JwtSecret) ) }; }); // Add services to the container. builder.Services.AddAuthorization(); builder.Services.AddSingleton(builder.Configuration); builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped(); builder.Services.AddControllers(); builder.Services.AddHttpLogging(o => { }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "Quotify API", Description = "An ASP.NET Core Web API for managing quotes", Contact = new OpenApiContact { Name = "Quotify project's production branch", Url = new Uri("https://quotify.7o7.cx") }, License = new OpenApiLicense { Name = "AGPLv3", Url = new Uri("https://www.gnu.org/licenses/agpl-3.0.en.html") } }); // https://stackoverflow.com/a/58972781 options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = @"JWT Authorization header using the Bearer scheme.
Enter your JWT from /api/v1/auth/login to authorize.", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "Bearer" }); options.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, }, new List() } }); // using System.Reflection; var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); }); var app = builder.Build(); using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); var guhf = scope.ServiceProvider.GetRequiredService(); var seeder = new Seed(db, guhf); await seeder.SeedAsync(); } // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseHttpLogging(); app.UseMigrationsEndPoint(); app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();