using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using Serilog; using watcher_monitoring.Data; var builder = WebApplication.CreateBuilder(args); // Serilog konfigurieren – nur Logs, die nicht von Microsoft stammen Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.File( "logs/watcher-.log", outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}", rollingInterval: RollingInterval.Day ) .CreateLogger(); builder.Host.UseSerilog(); // ---------- Konfiguration ---------- DotNetEnv.Env.Load(); builder.Configuration.AddEnvironmentVariables(); // Konfiguration laden var configuration = builder.Configuration; // DbContext - Nur SQLite wird unterstützt var sqliteConnectionString = configuration.GetConnectionString("Sqlite") ?? configuration["Database:ConnectionStrings:Sqlite"] ?? "Data Source=./persistence/watcher.db"; builder.Services.AddDbContext((serviceProvider, options) => { options.UseSqlite(sqliteConnectionString); }); // Add services to the container. builder.Services.AddControllersWithViews(); // Cookie-basierte Authentifizierung builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Auth/Login"; options.LogoutPath = "/Auth/Logout"; options.AccessDeniedPath = "/Auth/AccessDenied"; options.ExpireTimeSpan = TimeSpan.FromHours(8); options.SlidingExpiration = true; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.Lax; }); builder.Services.AddAuthorization(); // Health Checks builder.Services.AddHealthChecks(); // Swagger API-Dokumentation builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "Watcher-Server API", Version = "v1" }); // Nur API-Controller dokumentieren (mit [ApiController]-Attribut) options.DocInclusionPredicate((docName, apiDesc) => { var controllerActionDescriptor = apiDesc.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor; if (controllerActionDescriptor == null) return false; // Nur Controller mit [ApiController]-Attribut einbeziehen return controllerActionDescriptor.ControllerTypeInfo .GetCustomAttributes(typeof(ApiControllerAttribute), true).Any(); }); }); var app = builder.Build(); // Stelle sicher, dass das persistence-Verzeichnis existiert var persistenceDir = Path.Combine(Directory.GetCurrentDirectory(), "persistence"); if (!Directory.Exists(persistenceDir)) { Log.Information("Erstelle persistence-Verzeichnis: {PersistenceDir}", persistenceDir); Directory.CreateDirectory(persistenceDir); } // Datenbank-Migration beim Start ausführen using (var scope = app.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService(); try { Log.Information("Führe Datenbank-Migrationen aus..."); dbContext.Database.Migrate(); Log.Information("Datenbank-Migrationen erfolgreich angewendet"); // Standard-Admin-User erstellen, falls noch kein User existiert if (!dbContext.Users.Any()) { Log.Information("Erstelle Standard-Admin-User..."); var adminUser = new watcher_monitoring.Models.User { Username = "admin", Email = "admin@watcher.local", Password = BCrypt.Net.BCrypt.HashPassword("admin"), IsActive = true, CreatedAt = DateTime.UtcNow, LastLogin = DateTime.UtcNow }; dbContext.Users.Add(adminUser); dbContext.SaveChanges(); Log.Information("Standard-Admin-User erstellt (Username: admin, Passwort: admin)"); } } catch (Exception ex) { Log.Error(ex, "Fehler beim Ausführen der Datenbank-Migrationen"); throw; } } // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // 🔹 Swagger aktivieren app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "Watcher-Server API v1"); options.RoutePrefix = "api/v1/swagger"; }); app.UseAuthentication(); app.UseAuthorization(); // Health Check Endpoint app.MapHealthChecks("/health"); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();