using FluentValidation; using Gameboard.ShogiUI.Sockets.Extensions; using Gameboard.ShogiUI.Sockets.Managers; using Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers; using Gameboard.ShogiUI.Sockets.Repositories; using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages; using Gameboard.ShogiUI.Sockets.Services; using Gameboard.ShogiUI.Sockets.Services.RequestValidators; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using System; using System.Linq; using System.Text; namespace Gameboard.ShogiUI.Sockets { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Socket ActionHandlers services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // Managers services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // Services services.AddSingleton, CreateGameRequestValidator>(); services.AddSingleton, JoinByCodeRequestValidator>(); services.AddSingleton, JoinGameRequestValidator>(); services.AddSingleton, ListGamesRequestValidator>(); services.AddSingleton, LoadGameRequestValidator>(); services.AddSingleton, MoveRequestValidator>(); services.AddSingleton(); // Repositories services.AddHttpClient("couchdb", c => { var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin:admin")); c.DefaultRequestHeaders.Add("Accept", "application/json"); c.DefaultRequestHeaders.Add("Authorization", $"Basic {base64}"); var baseUrl = $"{Configuration["AppSettings:CouchDB:Url"]}/{Configuration["AppSettings:CouchDB:Database"]}/"; c.BaseAddress = new Uri(baseUrl); }); services.AddTransient(); //services.AddSingleton(); //services.AddSingleton(provider => new CouchClient(databaseName, couchUrl)); services.AddControllers(); services .AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Authority = "https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0"; options.Audience = "935df672-efa6-45fa-b2e8-b76dfd65a122"; options.TokenValidationParameters.ValidateIssuer = true; options.TokenValidationParameters.ValidateAudience = true; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISocketService socketConnectionManager) { var origins = new[] { "http://localhost:3000", "https://localhost:3000", "http://127.0.0.1:3000", "https://127.0.0.1:3000", "https://dev.lucaserver.space", "https://lucaserver.space" }; var socketOptions = new WebSocketOptions(); foreach (var o in origins) socketOptions.AllowedOrigins.Add(o); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app .UseRequestResponseLogging() .UseCors( opt => opt .WithOrigins(origins) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() ) .UseRouting() .UseAuthentication() .UseAuthorization() .UseWebSockets(socketOptions) .UseEndpoints(endpoints => { endpoints.MapControllers(); }) .Use(async (context, next) => { var isUpgradeHeader = context .Request .Headers .Any(h => h.Key.Contains("upgrade", StringComparison.InvariantCultureIgnoreCase) && h.Value.ToString().Contains("websocket", StringComparison.InvariantCultureIgnoreCase)); if (isUpgradeHeader) { await socketConnectionManager.HandleSocketRequest(context); } else { await next(); } }); JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Formatting = Formatting.Indented, ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy { ProcessDictionaryKeys = true } }, Converters = new[] { new StringEnumConverter() }, NullValueHandling = NullValueHandling.Ignore, }; } } }