using Asp.Versioning; using Azure.Identity; using Core.Blueprint.Logging.Configuration; using Core.Thalos.Adapters.Contracts; using Core.Thalos.Adapters.Extensions; using Core.Thalos.Adapters.Services; using Core.Thalos.BFF.Api.Services; using Core.Thalos.External.ClientConfiguration; using Google.Protobuf.WellKnownTypes; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Extensions.Configuration.AzureAppConfiguration; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using OpenTelemetry.Logs; using OpenTelemetry.Resources; using Swashbuckle.AspNetCore.SwaggerUI; using System.IO.Compression; using System.Reflection; using System.Security.Claims; var builder = WebApplication.CreateBuilder(args); builder.Configuration .AddUserSecrets(Assembly.GetExecutingAssembly()) .AddEnvironmentVariables(); // 🔑 Google Auth config var googleClientId = builder.Configuration["Authentication:Google:ClientId"]; var googleClientSecret = builder.Configuration["Authentication:Google:ClientSecret"]; var redirectUri = builder.Configuration["Authentication:Google:RedirectUri"]; // 🧩 Authentication builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = Constant.Scheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddScheme(Constant.Scheme, null) .AddGoogle(options => { options.ClientId = googleClientId!; options.ClientSecret = googleClientSecret!; //options.SaveTokens = true; options.CallbackPath = $"/{redirectUri}"; }); builder.Services.AddAuthorization(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddEndpointsApiExplorer(); // 🧩 Swagger + OAuth2 builder.Services.AddSwaggerGen(opts => { const string schemeName = "oauth2"; opts.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Thalos.BFF", Version = "v1" }); opts.AddSecurityDefinition(schemeName, new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, Scheme = "bearer", // tells Swagger-UI to build an Authorization header BearerFormat = "JWT", Name = "Authorization", In = ParameterLocation.Header, /* ⚠️ The key line – tell Swagger-UI to pick id_token instead of access_token */ Extensions = new Dictionary { ["x-tokenName"] = new OpenApiString("id_token") }, Flows = new OpenApiOAuthFlows { AuthorizationCode = new OpenApiOAuthFlow { AuthorizationUrl = new Uri("https://accounts.google.com/o/oauth2/v2/auth"), TokenUrl = new Uri("https://oauth2.googleapis.com/token"), Scopes = new Dictionary { { "openid", "OpenID Connect" }, { "email", "Access email" }, { "profile", "Access profile" } } } } }); // every operation requires the scheme opts.AddSecurityRequirement(new OpenApiSecurityRequirement { [new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = schemeName } } ] = new[] { "openid", "email", "profile" } }); }); // 🎯 Existing configs (unchanged) builder.Services.AddResponseCompression(); builder.Services.AddProblemDetails(); builder.Services.AddLogs(builder); builder.Services.AddMemoryCache(); builder.Services.AddResponseCaching(options => { options.UseCaseSensitivePaths = true; }); builder.Logging.AddOpenTelemetry(logging => { logging.IncludeScopes = true; logging.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("core.thalos.bff.api")) .AddConsoleExporter(); }); builder.Host.ConfigureServices((context, services) => { services.AddHsts(options => { options.Preload = true; options.IncludeSubDomains = true; options.MaxAge = TimeSpan.FromDays(60); }); services.AddHttpsRedirection(options => { options.RedirectStatusCode = 308; }); services.AddAntiforgery(); services.AddHttpLogging(http => http.CombineLogs = true); services.AddCors(options => options.AddPolicy("AllowAll", policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod())); services.AddMvc().AddJsonOptions(opt => { opt.JsonSerializerOptions.WriteIndented = true; opt.JsonSerializerOptions.MaxDepth = 20; opt.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals; }); services.Configure(opt => opt.Level = CompressionLevel.SmallestSize); services.Configure(opt => opt.Level = CompressionLevel.SmallestSize); services.AddResponseCompression(opt => { opt.EnableForHttps = true; opt.Providers.Add(); opt.Providers.Add(); }); services.AddControllers(); services.AddHttpContextAccessor(); services.AddTransient(); services.RegisterExternalLayer(builder.Configuration); services.AddApiVersioning(options => options.ReportApiVersions = true) .AddApiExplorer(opt => { opt.GroupNameFormat = "'v'VVV"; opt.SubstituteApiVersionInUrl = true; }); }); builder.Services.AddScoped(); var app = builder.Build(); app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().WithOrigins("https://localhost:7239")); app.UseSwaggerUI(options => { foreach (var version in app.DescribeApiVersions().Select(v => v.GroupName)) options.SwaggerEndpoint($"/swagger/{version}/swagger.json", version); options.DisplayRequestDuration(); options.EnableTryItOutByDefault(); options.DocExpansion(DocExpansion.None); options.OAuthClientId(googleClientId); options.OAuthClientSecret(googleClientSecret); options.OAuthUsePkce(); options.OAuthScopes("openid", "email", "profile"); }); app.UseResponseCompression(); app.UseResponseCaching(); app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.UseHsts(); app.UseAntiforgery(); app.UseLogging(builder.Configuration); app.Run();