using System.Globalization; using System.Net.Http.Headers; using Bit.Billing.Services; using Bit.Billing.Services.Implementations; using Bit.Core.Billing.Extensions; using Bit.Core.Context; using Bit.Core.SecretsManager.Repositories; using Bit.Core.SecretsManager.Repositories.Noop; using Bit.Core.Settings; using Bit.Core.Utilities; using Bit.SharedWeb.Utilities; using Microsoft.Extensions.DependencyInjection.Extensions; using Quartz; using Stripe; namespace Bit.Billing; public class Startup { public Startup(IWebHostEnvironment env, IConfiguration configuration) { CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); Configuration = configuration; Environment = env; } public IConfiguration Configuration { get; } public IWebHostEnvironment Environment { get; set; } public void ConfigureServices(IServiceCollection services) { // Options services.AddOptions(); // Settings var globalSettings = services.AddGlobalSettingsServices(Configuration, Environment); services.Configure(Configuration.GetSection("BillingSettings")); var billingSettings = Configuration.GetSection("BillingSettings").Get(); // Stripe Billing StripeConfiguration.ApiKey = globalSettings.Stripe.ApiKey; StripeConfiguration.MaxNetworkRetries = globalSettings.Stripe.MaxNetworkRetries; // Data Protection services.AddCustomDataProtectionServices(Environment, globalSettings); // Repositories services.AddDatabaseRepositories(globalSettings); // BitPay Client services.AddSingleton(); // PayPal IPN Client services.AddHttpClient(); // Context services.AddScoped(); //Handlers services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); // Identity services.AddCustomIdentityServices(globalSettings); //services.AddPasswordlessIdentityServices(globalSettings); // Services services.AddBaseServices(globalSettings); services.AddDefaultServices(globalSettings); services.AddDistributedCache(globalSettings); services.AddBillingOperations(); services.TryAddSingleton(); // TODO: Remove when OrganizationUser methods are moved out of OrganizationService, this noop dependency should // TODO: no longer be required - see PM-1880 services.AddScoped(); services.AddControllers(config => { config.Filters.Add(new LoggingExceptionHandlerFilterAttribute()); }); services.Configure(options => options.LowercaseUrls = true); // Authentication services.AddAuthentication(); // Set up HttpClients services.AddHttpClient("FreshdeskApi"); services.AddHttpClient("OnyxApi", client => { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", billingSettings.Onyx.ApiKey); }); services.AddScoped(); services.AddScoped(); services.AddScoped(); // Add Quartz services first services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionJobFactory(); }); services.AddQuartzHostedService(); // Jobs service Jobs.JobsHostedService.AddJobsServices(services); services.AddHostedService(); // Swagger services.AddEndpointsApiExplorer(); services.AddSwaggerGen(); } public void Configure( IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime, GlobalSettings globalSettings) { app.UseSerilog(env, appLifetime, globalSettings); // Add general security headers app.UseMiddleware(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Billing API V1"); }); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute()); } }