diff --git a/apps/server-net/src/Host/Program.cs b/apps/server-net/src/Host/Program.cs index f7e2b2f..e69de29 100644 --- a/apps/server-net/src/Host/Program.cs +++ b/apps/server-net/src/Host/Program.cs @@ -1,179 +0,0 @@ -using Knot.Shared.Infrastructure; -using Knot.Modules.Identity; -using Knot.Modules.Chats; -using Knot.Modules.Chats.Infrastructure.SignalR; -using Knot.Modules.Identity.Infrastructure.Persistence; -using Knot.Modules.Chats.Infrastructure.Persistence; -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.IdentityModel.Tokens; -using System.Text; -using System.IdentityModel.Tokens.Jwt; -using System.Text.Json; -using System.Text.Json.Serialization; -using Microsoft.Extensions.FileProviders; -using Microsoft.AspNetCore.SignalR; -using System.Security.Claims; - - - -JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - -var builder = WebApplication.CreateBuilder(args); - -// ╨а╨╡╨│╨╕╤Б╤В╤А╨░╤Ж╨╕╤П ╨╝╨╛╨┤╤Г╨╗╨╡╨╣ -// ╨Ь╨░╨┐╨┐╨╕╨╜╨│ ╤Б╤В╨░╨╜╨┤╨░╤А╤В╨╜╤Л╤Е ╨┐╨╡╤А╨╡╨╝╨╡╨╜╨╜╤Л╤Е ╨╛╨║╤А╤Г╨╢╨╡╨╜╨╕╤П ╨▓ ╨╕╨╡╤А╨░╤А╤Е╨╕╤О .NET -var envMappings = new Dictionary -{ - ["ConnectionStrings:Database"] = builder.Configuration["DATABASE_URL"], - ["Jwt:Secret"] = builder.Configuration["JWT_SECRET"], - ["Jwt:Issuer"] = builder.Configuration["JWT_ISSUER"], - ["Jwt:Audience"] = builder.Configuration["JWT_AUDIENCE"], - ["WebRtc:TurnUrl"] = builder.Configuration["TURN_URL"], - ["WebRtc:TurnUsername"] = builder.Configuration["TURN_USERNAME"], - ["WebRtc:TurnPassword"] = builder.Configuration["TURN_PASSWORD"] -}; - -// ╨Ф╨╛╨▒╨░╨▓╨╗╤П╨╡╨╝ ╤В╨╛╨╗╤М╨║╨╛ ╤В╨╡, ╤З╤В╨╛ ╤А╨╡╨░╨╗╤М╨╜╨╛ ╨╖╨░╨┤╨░╨╜╤Л ╨▓ ENV -builder.Configuration.AddInMemoryCollection( - envMappings.Where(kv => !string.IsNullOrEmpty(kv.Value)) - .ToDictionary(kv => kv.Key, kv => kv.Value)); - -builder.Services.AddIdentityModule(builder.Configuration); -builder.Services.AddChatsModule(builder.Configuration); -builder.Services.AddSharedInfrastructure(); - -// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ CORS -builder.Services.AddCors(options => -{ - options.AddDefaultPolicy(policy => - { - var originsFromConfig = builder.Configuration["Cors:Origins"]; - var domain = builder.Configuration["DOMAIN"]; - - var origins = !string.IsNullOrEmpty(originsFromConfig) - ? originsFromConfig.Split(',') - : (!string.IsNullOrEmpty(domain) ? new[] { $"https://{domain}" } : new[] { "*" }); - - policy.WithOrigins(origins) - .AllowAnyHeader() - .AllowAnyMethod() - .AllowCredentials(); - }); -}); - -// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ Swagger/OpenAPI -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); -// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╨╝╨░╤А╤И╤А╤Г╤В╨╕╨╖╨░╤Ж╨╕╨╕ -builder.Services.AddRouting(options => -{ - options.LowercaseUrls = true; - options.LowercaseQueryStrings = true; -}); - - -builder.Services.AddControllers() - .AddJsonOptions(options => - { - options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - }); - -builder.Services.AddSignalR() - .AddJsonProtocol(options => - { - options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - }); - -builder.Services.AddSingleton(); - -// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ JWT ╨Р╤Г╤В╨╡╨╜╤В╨╕╤Д╨╕╨║╨░╤Ж╨╕╨╕ -builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddJwtBearer(options => - { - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - ValidIssuer = builder.Configuration["Jwt:Issuer"], - ValidAudience = builder.Configuration["Jwt:Audience"], - IssuerSigningKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"]!)) - }; - - options.Events = new JwtBearerEvents - { - OnMessageReceived = context => - { - var accessToken = context.Request.Query["access_token"]; - var path = context.HttpContext.Request.Path; - if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs")) - { - context.Token = accessToken; - } - return Task.CompletedTask; - } - }; - }); - -builder.Services.AddAuthorization(); - -var app = builder.Build(); - -// ╨Я╤А╨╕╨╝╨╡╨╜╤П╨╡╨╝ ╨╝╨╕╨│╤А╨░╤Ж╨╕╨╕ ╨┐╤А╨╕ ╤Б╤В╨░╤А╤В╨╡ -using (var scope = app.Services.CreateScope()) -{ - var identityDb = scope.ServiceProvider.GetRequiredService(); - await identityDb.Database.MigrateAsync(); - - var chatsDb = scope.ServiceProvider.GetRequiredService(); - await chatsDb.Database.MigrateAsync(); -} - -// ╨Э╨░╤Б╤В╤А╨╛╨╣╨║╨░ ╨║╨╛╨╜╨▓╨╡╨╣╨╡╤А╨░ ╨╖╨░╨┐╤А╨╛╤Б╨╛╨▓ -app.UseMiddleware(); - -app.UseCors(); - -if (app.Environment.IsDevelopment()) -{ - app.UseSwagger(); - app.UseSwaggerUI(); -} - -// app.UseHttpsRedirection(); - -var uploadsPath = Path.Combine(Directory.GetCurrentDirectory(), "uploads"); -if (!Directory.Exists(uploadsPath)) -{ - Directory.CreateDirectory(uploadsPath); -} - -app.UseStaticFiles(new StaticFileOptions -{ - FileProvider = new PhysicalFileProvider(uploadsPath), - RequestPath = "/uploads" -}); - -app.UseAuthentication(); -app.UseAuthorization(); - -// ╨Ф╨╛╨▒╨░╨▓╨╗╤П╨╡╨╝ ╨║╨╛╨╜╤В╤А╨╛╨╗╨╗╨╡╤А╤Л -app.MapControllers(); - -// ╨Ф╨╛╨▒╨░╨▓╨╗╤П╨╡╨╝ SignalR ╤Е╨░╨▒╤Л -app.MapHub("/hubs/chat"); - -app.Run(); - -public class CustomUserIdProvider : IUserIdProvider -{ - public string? GetUserId(HubConnectionContext connection) - { - return connection.User?.FindFirstValue("sub") ?? connection.User?.FindFirstValue(ClaimTypes.NameIdentifier); - } -}