using JSMR.Application.DI; using JSMR.Infrastructure.Data; using JSMR.Infrastructure.DI; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Http.Json; using Microsoft.EntityFrameworkCore; using Serilog; using Serilog.Events; using System.Text.Json; using System.Text.Json.Serialization; namespace JSMR.Api.Startup; public static class ServiceCollectionExtensions { public static IServiceCollection AddAppServices(this IServiceCollection services, IHostApplicationBuilder builder) { services .AddMemoryCache() .AddApplication() .AddInfrastructure(); string connectionString = builder.Configuration.GetConnectionString("AppDb") ?? throw new InvalidOperationException("Missing ConnectionStrings:AppDb"); services.AddDbContextFactory(opt => opt.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)) .EnableSensitiveDataLogging(false)); services.AddControllers(); return services; } public static IServiceCollection AddAppJson(this IServiceCollection services) { services.Configure(options => { options.SerializerOptions.PropertyNameCaseInsensitive = true; options.SerializerOptions.Converters.Add( new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); }); return services; } public static IServiceCollection AddAppOpenApi(this IServiceCollection services) { services.AddOpenApi(); return services; } public static IServiceCollection AddAppAuthentication(this IServiceCollection services) { services.AddAuthorization(); services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.Name = "vw_auth"; options.Cookie.HttpOnly = true; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Events = new CookieAuthenticationEvents { OnRedirectToLogin = ctx => { ctx.Response.StatusCode = StatusCodes.Status401Unauthorized; return Task.CompletedTask; }, OnRedirectToAccessDenied = ctx => { ctx.Response.StatusCode = StatusCodes.Status403Forbidden; return Task.CompletedTask; } }; }); return services; } public static IServiceCollection AddAppCors(this IServiceCollection services, IHostApplicationBuilder builder) { // Prefer config-based origins so you stop editing code for ports. // appsettings.Development.json: // "Cors": { "AllowedOrigins": [ "https://localhost:7112", ... ] } string[] origins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get() ?? []; services.AddCors(options => { options.AddPolicy("ui", policyBuilder => policyBuilder.WithOrigins(origins) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials()); }); return services; } public static IServiceCollection AddAppLogging(this IServiceCollection services, IHostApplicationBuilder builder) { var config = builder.Configuration; var env = builder.Environment; Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(config) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .Enrich.WithProperty("Service", "JSMR.Api") .Enrich.WithProperty("Environment", env.EnvironmentName) .CreateLogger(); return services; } }