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") } }); // 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();