using administration.Models; using administration.Models.Finances; using administration.Models.HelloFresh; using administration.Services; using IngredientsAI.Services; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using System.Text.Json; using User = administration.Models.User; namespace administration { public class Program { public static void Main(string[] args) { DotNetEnv.Env.Load(); var builder = WebApplication.CreateBuilder(args); // ============================================== // 1️⃣ Base de données // ============================================== var dbConnection = Environment.GetEnvironmentVariable("ADMIN_DB_CONNECTION"); if (string.IsNullOrEmpty(dbConnection)) throw new Exception("❌ ADMIN_DB_CONNECTION est introuvable."); bool inContainer = Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true"; string hostOverride = builder.Configuration["DB_HOST"] ?? Environment.GetEnvironmentVariable("DB_HOST"); string Fix(string? cs, string? dbNameFallback) { if (string.IsNullOrWhiteSpace(cs) && !string.IsNullOrWhiteSpace(dbNameFallback)) { var def = builder.Configuration.GetConnectionString("DefaultConnection") ?? ""; if (!string.IsNullOrWhiteSpace(def)) cs = System.Text.RegularExpressions.Regex.Replace(def, @"Database=([^;]+)", $"Database={dbNameFallback}"); } if (!string.IsNullOrWhiteSpace(cs) && !inContainer && !string.IsNullOrWhiteSpace(hostOverride)) { cs = cs.Replace("Server=sqlserver,1433", $"Server={hostOverride},1433", StringComparison.OrdinalIgnoreCase); } return cs ?? ""; } var csLayout = Fix(builder.Configuration.GetConnectionString("DefaultConnection"), "LayoutData"); var csHello = Fix(builder.Configuration.GetConnectionString("HelloFresh"), "HelloFresh"); var csFinance = Fix(builder.Configuration.GetConnectionString("Finances"), "Finances"); builder.Services.AddDbContext(o => o.UseSqlServer(csLayout)); builder.Services.AddDbContext(o => o.UseSqlServer(csHello)); builder.Services.AddDbContext(o => o.UseSqlServer(csFinance)); AppSettings.Initialize(builder.Configuration); builder.Services.AddSingleton(); // ============================================== // 2️⃣ Session // ============================================== builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromHours(8); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // ============================================== // 3️⃣ Authentification par cookie // ============================================== builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Connections/Login"; options.AccessDeniedPath = "/Connections/Login"; options.SlidingExpiration = true; options.ExpireTimeSpan = TimeSpan.FromDays(14); }); builder.Services.AddAuthorization(); builder.Services.AddControllers().AddJsonOptions(o => { o.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); // ============================================== // 4️⃣ MVC + services // ============================================== builder.Services.AddControllersWithViews(); builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped, PasswordHasher>(); // ============================================== // 5️⃣ CORS // ============================================== builder.Services.AddCors(options => { options.AddPolicy("AllowFrontend", policy => { policy.WithOrigins("http://localhost:5018", "https://administration.byakurepo.online") .AllowAnyHeader() .AllowAnyMethod(); }); }); builder.Services.AddHttpClient(); // déjà présent chez toi builder.Services.AddHttpClient("ollama", (sp, client) => { var cfg = sp.GetRequiredService(); var baseUrl = cfg["Ollama:Url"] ?? "http://ollama:11434"; client.BaseAddress = new Uri(baseUrl); client.Timeout = TimeSpan.FromSeconds(25); }); var ollamaBuilder = builder.Services.AddHttpClient("ollama", (sp, client) => { var cfg = sp.GetRequiredService(); var baseUrl = cfg["Ollama:Url"] ?? "http://ollama:11434"; client.BaseAddress = new Uri(baseUrl); client.Timeout = TimeSpan.FromSeconds(25); }); #if DEBUG ollamaBuilder.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator }); #endif // ... // ... builder.Logging.AddFilter("administration.Services.BasicAuthenticationHandler", LogLevel.Warning); var app = builder.Build(); // ============================================== // 6️⃣ Pipeline app.MapGet("/_dbping", async (HelloFreshContext hf, LayoutDataContext ld) => { try { await hf.Database.ExecuteSqlRawAsync("SELECT 1"); } catch (Exception ex) { return Results.Problem($"HelloFresh: {ex.GetBaseException().Message}"); } try { await ld.Database.ExecuteSqlRawAsync("SELECT 1"); } catch (Exception ex) { return Results.Problem($"LayoutData: {ex.GetBaseException().Message}"); } return Results.Ok("OK"); }); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseRouting(); app.UseCors("AllowFrontend"); app.UseSession(); // ✅ toujours avant auth app.UseAuthentication(); // ✅ s'applique à tout le site app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); } } }