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 System.Text.Json; using System.Text.Json.Serialization; namespace JSMR.Api.Startup; public static class ServiceCollectionExtensions { public static IServiceCollection AddAppServices(this IServiceCollection services, IConfigurationManager configuration) { services .AddMemoryCache() .AddApplication() .AddInfrastructure(); string connectionString = 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, IHostEnvironment environment) { 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.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = environment.IsDevelopment() ? CookieSecurePolicy.SameAsRequest : 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, IConfigurationManager configuration) { string[] origins = configuration.GetSection("Cors:AllowedOrigins").Get() ?? []; services.AddCors(options => { options.AddPolicy("ui", policyBuilder => { if (origins.Length == 0) { // In container/prod you often don't need CORS at all (same-origin), // but if it *is* needed and not configured, fail closed rather than crash. // Do not call WithOrigins(). return; } 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; //} }