using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using LittleShop.Data; using LittleShop.Services; using FluentValidation; using Serilog; var builder = WebApplication.CreateBuilder(args); // Configure Serilog Log.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/littleshop.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); builder.Host.UseSerilog(); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddControllersWithViews(); // Add MVC for Admin Panel // Database builder.Services.AddDbContext(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"))); // Authentication - Cookie for Admin Panel, JWT for API var jwtKey = builder.Configuration["Jwt:Key"] ?? "YourSuperSecretKeyThatIsAtLeast32CharactersLong!"; var jwtIssuer = builder.Configuration["Jwt:Issuer"] ?? "LittleShop"; var jwtAudience = builder.Configuration["Jwt:Audience"] ?? "LittleShop"; builder.Services.AddAuthentication("Cookies") .AddCookie("Cookies", options => { options.LoginPath = "/Admin/Account/Login"; options.LogoutPath = "/Admin/Account/Logout"; options.AccessDeniedPath = "/Admin/Account/AccessDenied"; }) .AddJwtBearer("Bearer", options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtIssuer, ValidAudience = jwtAudience, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)) }; }); builder.Services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => policy.RequireAuthenticatedUser()); options.AddPolicy("ApiAccess", policy => policy.RequireAuthenticatedUser()); }); // Services builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); // AutoMapper builder.Services.AddAutoMapper(typeof(Program)); // FluentValidation builder.Services.AddValidatorsFromAssemblyContaining(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "LittleShop API", Version = "v1", Description = "A basic online sales system backend with multi-cryptocurrency payment support", Contact = new Microsoft.OpenApi.Models.OpenApiContact { Name = "LittleShop Support" } }); // Add JWT authentication to Swagger c.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below.", Name = "Authorization", In = Microsoft.OpenApi.Models.ParameterLocation.Header, Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey, Scheme = "Bearer" }); c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement { { new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Reference = new Microsoft.OpenApi.Models.OpenApiReference { Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty() } }); }); // CORS builder.Services.AddCors(options => { options.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors("AllowAll"); app.UseStaticFiles(); // Enable serving static files app.UseAuthentication(); app.UseAuthorization(); // Configure routing app.MapControllerRoute( name: "admin", pattern: "Admin/{controller=Dashboard}/{action=Index}/{id?}", defaults: new { area = "Admin" } ); app.MapControllerRoute( name: "areas", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapControllers(); // API routes // Ensure database is created using (var scope = app.Services.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); context.Database.EnsureCreated(); // Seed default admin user var authService = scope.ServiceProvider.GetRequiredService(); await authService.SeedDefaultUserAsync(); // Seed sample data var dataSeeder = scope.ServiceProvider.GetRequiredService(); await dataSeeder.SeedSampleDataAsync(); } Log.Information("LittleShop API starting up..."); app.Run(); // Make Program accessible to test project public partial class Program { }