This commit is contained in:
Халимов Рустам
2026-03-30 23:57:34 +03:00
parent d3f1e3f361
commit f1f8f6e012
27 changed files with 88 additions and 142 deletions
-1
View File
@@ -8,7 +8,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="1.4.0" /> <PackageReference Include="AngleSharp" Version="1.4.0" />
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" /> <PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="Mapster" Version="7.4.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
+14 -7
View File
@@ -1,5 +1,4 @@
using Knot.Modules.Messaging; using Knot.Modules.Messaging;
using Carter;
using Knot.Shared.Infrastructure; using Knot.Shared.Infrastructure;
using Knot.Modules.Auth; using Knot.Modules.Auth;
using Knot.Modules.Profiles; using Knot.Modules.Profiles;
@@ -19,7 +18,6 @@ using System.Text;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.FileProviders;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using System.Security.Claims; using System.Security.Claims;
@@ -77,9 +75,6 @@ builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(
typeof(Knot.Modules.Klipy.DependencyInjection).Assembly typeof(Knot.Modules.Klipy.DependencyInjection).Assembly
)); ));
// Carter для вызова Minimal APIs (Endpoints)
builder.Services.AddCarter();
// Настройка CORS // Настройка CORS
builder.Services.AddCors(options => builder.Services.AddCors(options =>
{ {
@@ -216,8 +211,20 @@ if (app.Environment.IsDevelopment())
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
// Добавляем контроллеры и Carter (Minimal APIs) // Регистрация эндпоинтов
app.MapCarter(); app.MapAuthEndpoints();
app.MapStoriesEndpoints();
app.MapContactsEndpoints();
app.MapSettingsEndpoints();
app.MapProfilesEndpoints();
app.MapFederationEndpoints();
app.MapKlipyEndpoints();
app.MapChatsEndpoints();
app.MapMessagesEndpoints();
app.MapAdminEndpoints();
app.MapFilesEndpoints();
app.MapWebRtcEndpoints();
app.MapTelegramImportEndpoints();
// Добавляем SignalR хабы // Добавляем SignalR хабы
app.MapHub<ChatHub>("/hubs/chat"); app.MapHub<ChatHub>("/hubs/chat");
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -18,7 +18,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" /> <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
</ItemGroup> </ItemGroup>
@@ -1,4 +1,3 @@
using Carter;
using Knot.Contracts.Settings.Application.Abstractions; using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs; using Knot.Contracts.Settings.Application.DTOs;
using Knot.Modules.Admin.Application.Admin.Commands; using Knot.Modules.Admin.Application.Admin.Commands;
@@ -15,9 +14,9 @@ namespace Knot.Host.Presentation.Endpoints;
public record KlipyTestDto(string ApiKey, string AppName); public record KlipyTestDto(string ApiKey, string AppName);
public record ResetPasswordRequest(string NewPassword); public record ResetPasswordRequest(string NewPassword);
public sealed class AdminEndpoints : ICarterModule public static class AdminEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapAdminEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/admin"); // Middleware handles auth var group = app.MapGroup("api/admin"); // Middleware handles auth
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
@@ -15,7 +15,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="BCrypt.Net-Next" Version="4.1.0" /> <PackageReference Include="BCrypt.Net-Next" Version="4.1.0" />
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="MediatR" Version="12.0.1" /> <PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" />
@@ -1,4 +1,3 @@
using Carter;
using Knot.Shared.Kernel; using Knot.Shared.Kernel;
using Knot.Modules.Auth.Application.Users.Login; using Knot.Modules.Auth.Application.Users.Login;
using Knot.Modules.Auth.Application.Users.Register; using Knot.Modules.Auth.Application.Users.Register;
@@ -11,9 +10,9 @@ using Microsoft.AspNetCore.Mvc;
namespace Knot.Modules.Auth.Presentation.Endpoints; namespace Knot.Modules.Auth.Presentation.Endpoints;
public sealed class AuthEndpoints : ICarterModule public static class AuthEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapAuthEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/auth"); var group = app.MapGroup("api/auth");
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -16,7 +16,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="1.4.0" /> <PackageReference Include="AngleSharp" Version="1.4.0" />
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" /> <PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="MediatR" Version="12.0.1" /> <PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
@@ -1,28 +1,27 @@
using Carter;
using Knot.Shared.Kernel;
using Knot.Modules.Conversations.Application.DTOs;
using Knot.Modules.Conversations.Application.Chats.GetChats;
using Knot.Modules.Conversations.Application.Chats.GetChatById;
using Knot.Modules.Conversations.Application.Chats.Create;
using Knot.Modules.Conversations.Application.Chats.GetOrCreateFavorites;
using Knot.Modules.Conversations.Application.Chats.Update;
using Knot.Modules.Conversations.Application.Chats.LeaveOrDelete;
using Knot.Modules.Conversations.Application.Chats.Clear;
using Knot.Modules.Conversations.Application.Chats.TogglePin;
using Knot.Modules.Conversations.Application.Chats.Members;
using Knot.Modules.Conversations.Application.Chats.Avatar; using Knot.Modules.Conversations.Application.Chats.Avatar;
using Knot.Modules.Conversations.Application.Chats.Clear;
using Knot.Modules.Conversations.Application.Chats.Create;
using Knot.Modules.Conversations.Application.Chats.GetChatById;
using Knot.Modules.Conversations.Application.Chats.GetChats;
using Knot.Modules.Conversations.Application.Chats.GetOrCreateFavorites;
using Knot.Modules.Conversations.Application.Chats.LeaveOrDelete;
using Knot.Modules.Conversations.Application.Chats.Members;
using Knot.Modules.Conversations.Application.Chats.TogglePin;
using Knot.Modules.Conversations.Application.Chats.Update;
using Knot.Modules.Conversations.Application.DTOs;
using Knot.Modules.Conversations.Domain; using Knot.Modules.Conversations.Domain;
using Knot.Shared.Kernel;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
namespace Knot.Modules.Conversations.Presentation.Endpoints; namespace Knot.Modules.Conversations.Presentation.Endpoints;
public sealed class ChatsEndpoints : ICarterModule public static class ChatsEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapChatsEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/chats").RequireAuthorization(); var group = app.MapGroup("api/chats").RequireAuthorization();
@@ -1,22 +1,21 @@
using Carter;
using Knot.Shared.Kernel;
using Knot.Modules.Conversations.Application.DTOs; using Knot.Modules.Conversations.Application.DTOs;
using Knot.Modules.Conversations.Application.Messages.GetMessages; using Knot.Modules.Conversations.Application.Messages.GetMessages;
using Knot.Modules.Conversations.Application.Messages.SearchMessages;
using Knot.Modules.Conversations.Application.Messages.UploadFile;
using Knot.Modules.Conversations.Application.Messages.GetSharedMedia; using Knot.Modules.Conversations.Application.Messages.GetSharedMedia;
using Knot.Modules.Conversations.Application.Messages.SearchMessages;
using Knot.Modules.Conversations.Application.Messages.Send; using Knot.Modules.Conversations.Application.Messages.Send;
using Knot.Modules.Conversations.Application.Messages.UploadFile;
using Knot.Shared.Kernel;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
namespace Knot.Modules.Conversations.Presentation.Endpoints; namespace Knot.Modules.Conversations.Presentation.Endpoints;
public sealed class MessagesEndpoints : ICarterModule public static class MessagesEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapMessagesEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/messages").RequireAuthorization(); var group = app.MapGroup("api/messages").RequireAuthorization();
@@ -41,7 +40,7 @@ public sealed class MessagesEndpoints : ICarterModule
using var stream = file.OpenReadStream(); using var stream = file.OpenReadStream();
var result = await sender.Send(new UploadFileCommand(file.FileName, file.ContentType, file.Length, stream), ct); var result = await sender.Send(new UploadFileCommand(file.FileName, file.ContentType, file.Length, stream), ct);
if (result.IsFailure) if (result.IsFailure)
{ {
if (result.Error.Code == "File.TooLarge") return Results.StatusCode(413); if (result.Error.Code == "File.TooLarge") return Results.StatusCode(413);
@@ -58,13 +57,13 @@ public sealed class MessagesEndpoints : ICarterModule
group.MapPost("chat/{chatId:guid}", async (Guid chatId, [FromBody] SendMessageRequest request, ISender sender, IUserContext userContext, CancellationToken ct) => group.MapPost("chat/{chatId:guid}", async (Guid chatId, [FromBody] SendMessageRequest request, ISender sender, IUserContext userContext, CancellationToken ct) =>
{ {
var attachments = request.Attachments?.Select(a => var attachments = request.Attachments?.Select(a =>
new AttachmentRequest(a.Type, a.Url, a.FileName, a.FileSize)).ToList(); new AttachmentRequest(a.Type, a.Url, a.FileName, a.FileSize)).ToList();
var command = new SendMessageCommand( var command = new SendMessageCommand(
chatId, chatId,
userContext.UserId, userContext.UserId,
request.Content, request.Content,
request.Type, request.Type,
attachments, attachments,
request.ReplyToId, request.ReplyToId,
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -13,7 +13,4 @@
<ProjectReference Include="..\..\Contracts\Conversations\Knot.Contracts.Conversations.csproj" /> <ProjectReference Include="..\..\Contracts\Conversations\Knot.Contracts.Conversations.csproj" />
<ProjectReference Include="..\..\Contracts\Profiles\Knot.Contracts.Profiles.csproj" /> <ProjectReference Include="..\..\Contracts\Profiles\Knot.Contracts.Profiles.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
</ItemGroup>
</Project> </Project>
@@ -1,4 +1,3 @@
using Carter;
using MediatR; using MediatR;
using Knot.Shared.Kernel.Constants; using Knot.Shared.Kernel.Constants;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@@ -17,9 +16,9 @@ namespace Host.Endpoints;
/// <summary> /// <summary>
/// Эндпоинты федерации для межсерверного взаимодействия. /// Эндпоинты федерации для межсерверного взаимодействия.
/// </summary> /// </summary>
public sealed class FederationEndpoints : ICarterModule public static class FederationEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapFederationEndpoints(this WebApplication app)
{ {
var group = app.MapGroup(Routes.ApiFederation); var group = app.MapGroup(Routes.ApiFederation);
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -9,7 +9,4 @@
<ProjectReference Include="..\..\Shared\Knot.Shared.Infrastructure\Knot.Shared.Infrastructure.csproj" /> <ProjectReference Include="..\..\Shared\Knot.Shared.Infrastructure\Knot.Shared.Infrastructure.csproj" />
<ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" /> <ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
</ItemGroup>
</Project> </Project>
@@ -1,4 +1,3 @@
using Carter;
using MediatR; using MediatR;
using Knot.Shared.Kernel.Constants; using Knot.Shared.Kernel.Constants;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@@ -13,9 +12,9 @@ namespace Host.Endpoints;
/// <summary> /// <summary>
/// Регистрация эндпоинтов для сервиса Klipy. /// Регистрация эндпоинтов для сервиса Klipy.
/// </summary> /// </summary>
public sealed class KlipyEndpoints : ICarterModule public static class KlipyEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapKlipyEndpoints(this WebApplication app)
{ {
var group = app.MapGroup(Routes.ApiKlipy).RequireAuthorization(); var group = app.MapGroup(Routes.ApiKlipy).RequireAuthorization();
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
@@ -13,7 +13,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="MediatR" Version="12.0.1" /> <PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" />
@@ -1,4 +1,3 @@
using Carter;
using Knot.Shared.Kernel; using Knot.Shared.Kernel;
using Knot.Modules.Profiles.Application.Profiles.Avatar; using Knot.Modules.Profiles.Application.Profiles.Avatar;
using Knot.Modules.Profiles.Application.Profiles.GetProfile; using Knot.Modules.Profiles.Application.Profiles.GetProfile;
@@ -13,9 +12,9 @@ using Microsoft.AspNetCore.Mvc;
namespace Knot.Modules.Profiles.Presentation.Endpoints; namespace Knot.Modules.Profiles.Presentation.Endpoints;
public sealed class ProfilesEndpoints : ICarterModule public static class ProfilesEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapProfilesEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/profiles").RequireAuthorization(); var group = app.MapGroup("api/profiles").RequireAuthorization();
@@ -13,7 +13,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="MediatR" Version="12.0.1" /> <PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" />
@@ -1,4 +1,3 @@
using Carter;
using Knot.Contracts.Relations.Domain; using Knot.Contracts.Relations.Domain;
using Knot.Modules.Relations.Application.Contacts; using Knot.Modules.Relations.Application.Contacts;
using Knot.Shared.Infrastructure; using Knot.Shared.Infrastructure;
@@ -12,9 +11,9 @@ using Microsoft.EntityFrameworkCore;
namespace Knot.Modules.Relations.Presentation.Endpoints; namespace Knot.Modules.Relations.Presentation.Endpoints;
public sealed class ContactsEndpoints : ICarterModule public static class ContactsEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapContactsEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/contacts").RequireAuthorization(); var group = app.MapGroup("api/contacts").RequireAuthorization();
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -9,7 +9,4 @@
<ProjectReference Include="..\..\Shared\Knot.Shared.Infrastructure\Knot.Shared.Infrastructure.csproj" /> <ProjectReference Include="..\..\Shared\Knot.Shared.Infrastructure\Knot.Shared.Infrastructure.csproj" />
<ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" /> <ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
</ItemGroup>
</Project> </Project>
@@ -1,4 +1,3 @@
using Carter;
using Knot.Modules.Settings.Application.Settings.Queries; using Knot.Modules.Settings.Application.Settings.Queries;
using Knot.Shared.Kernel; using Knot.Shared.Kernel;
using MediatR; using MediatR;
@@ -8,9 +7,9 @@ using Microsoft.AspNetCore.Routing;
namespace Knot.Modules.Settings.Presentation.Endpoints; namespace Knot.Modules.Settings.Presentation.Endpoints;
public sealed class SettingsEndpoints : ICarterModule public static class SettingsEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapSettingsEndpoints(this WebApplication app)
{ {
app.MapGet("api/config", async (ISender sender, CancellationToken ct) => app.MapGet("api/config", async (ISender sender, CancellationToken ct) =>
{ {
@@ -15,7 +15,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="Minio" Version="7.0.0" /> <PackageReference Include="Minio" Version="7.0.0" />
<ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" /> <ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" />
</ItemGroup> </ItemGroup>
@@ -1,21 +1,19 @@
using Carter; using System.Security.Cryptography;
using Microsoft.Extensions.Caching.Memory; using System.Text;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;
using Knot.Shared.Kernel.Storage; using Knot.Shared.Kernel.Storage;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Knot.Contracts.Settings.Application.Abstractions; using Microsoft.Extensions.Caching.Memory;
using Knot.Contracts.Settings.Application.DTOs;
using System.Text;
using System.Security.Cryptography;
namespace Knot.Host.Presentation.Endpoints; namespace Knot.Host.Presentation.Endpoints;
public sealed class FilesEndpoints : ICarterModule public static class FilesEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapFilesEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/files"); var group = app.MapGroup("api/files");
@@ -31,12 +29,12 @@ public sealed class FilesEndpoints : ICarterModule
using var ms = new MemoryStream(); using var ms = new MemoryStream();
if (result.Stream.CanSeek) result.Stream.Position = 0; if (result.Stream.CanSeek) result.Stream.Position = 0;
await result.Stream.CopyToAsync(ms, ct); await result.Stream.CopyToAsync(ms, ct);
cachedData = (ms.ToArray(), result.ContentType, result.FileName); cachedData = (ms.ToArray(), result.ContentType, result.FileName);
var cacheEntryOptions = new MemoryCacheEntryOptions() var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(30)); .SetSlidingExpiration(TimeSpan.FromMinutes(30));
cache.Set(cacheKey, cachedData, cacheEntryOptions); cache.Set(cacheKey, cachedData, cacheEntryOptions);
result.Stream.Dispose(); result.Stream.Dispose();
} }
@@ -47,7 +45,7 @@ public sealed class FilesEndpoints : ICarterModule
{ {
return Results.File(outStream, cachedData.ContentType, fileDownloadName: cachedData.FileName, enableRangeProcessing: true); return Results.File(outStream, cachedData.ContentType, fileDownloadName: cachedData.FileName, enableRangeProcessing: true);
} }
return Results.File(outStream, cachedData.ContentType, enableRangeProcessing: true); return Results.File(outStream, cachedData.ContentType, enableRangeProcessing: true);
} }
catch (Exception ex) catch (Exception ex)
@@ -64,12 +62,13 @@ public sealed class FilesEndpoints : ICarterModule
// Формируем подписанный запрос к удаленному серверу // Формируем подписанный запрос к удаленному серверу
var targetUrl = $"{domain.TrimEnd('/')}/api/federation/v1/proxy/{id}"; var targetUrl = $"{domain.TrimEnd('/')}/api/federation/v1/proxy/{id}";
var request = new HttpRequestMessage(HttpMethod.Get, targetUrl); var request = new HttpRequestMessage(HttpMethod.Get, targetUrl);
request.Headers.Add("X-Knot-Domain", settings.System.DomainUrl); request.Headers.Add("X-Knot-Domain", settings.System.DomainUrl);
// Генерируем подпись запроса своим приватным ключом // Генерируем подпись запроса своим приватным ключом
using(var rsa = RSA.Create()) { using (var rsa = RSA.Create())
{
rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(settings.Federation.PrivateKey!), out _); rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(settings.Federation.PrivateKey!), out _);
var dataToSign = Encoding.UTF8.GetBytes(id + settings.System.DomainUrl); var dataToSign = Encoding.UTF8.GetBytes(id + settings.System.DomainUrl);
var signature = Convert.ToBase64String(rsa.SignData(dataToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); var signature = Convert.ToBase64String(rsa.SignData(dataToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
@@ -81,7 +80,7 @@ public sealed class FilesEndpoints : ICarterModule
var remoteStream = await response.Content.ReadAsStreamAsync(ct); var remoteStream = await response.Content.ReadAsStreamAsync(ct);
var contentType = response.Content.Headers.ContentType?.ToString() ?? "application/octet-stream"; var contentType = response.Content.Headers.ContentType?.ToString() ?? "application/octet-stream";
return Results.Stream(remoteStream, contentType, enableRangeProcessing: true); return Results.Stream(remoteStream, contentType, enableRangeProcessing: true);
}); });
} }
@@ -15,7 +15,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="MediatR" Version="12.0.1" /> <PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.4" />
@@ -1,16 +1,10 @@
using Carter;
using Knot.Modules.Stories.Application.DTOs; using Knot.Modules.Stories.Application.DTOs;
using Knot.Modules.Stories.Application.Stories.Commands.AddStoryReaction;
using Knot.Modules.Stories.Application.Stories.Commands.AddStoryReply;
using Knot.Modules.Stories.Application.Stories.Commands.CreateStory; using Knot.Modules.Stories.Application.Stories.Commands.CreateStory;
using Knot.Modules.Stories.Application.Stories.Commands.DeleteStory; using Knot.Modules.Stories.Application.Stories.Commands.DeleteStory;
using Knot.Modules.Stories.Application.Stories.Commands.RemoveStoryReaction;
using Knot.Modules.Stories.Application.Stories.Commands.ViewStory; using Knot.Modules.Stories.Application.Stories.Commands.ViewStory;
using Knot.Modules.Stories.Application.Stories.Queries.GetStories; using Knot.Modules.Stories.Application.Stories.Queries.GetStories;
using Knot.Modules.Stories.Application.Stories.Queries.GetStoryReplies;
using Knot.Modules.Stories.Application.Stories.Queries.GetStoryViewers; using Knot.Modules.Stories.Application.Stories.Queries.GetStoryViewers;
using Knot.Modules.Stories.Application.Stories.Queries.GetUserStories; using Knot.Modules.Stories.Application.Stories.Queries.GetUserStories;
using Knot.Modules.Stories.Domain;
using Knot.Shared.Kernel; using Knot.Shared.Kernel;
using Knot.Shared.Kernel.Storage; using Knot.Shared.Kernel.Storage;
using MediatR; using MediatR;
@@ -21,9 +15,9 @@ using Microsoft.AspNetCore.Routing;
namespace Knot.Modules.Stories.Presentation.Endpoints; namespace Knot.Modules.Stories.Presentation.Endpoints;
public sealed class StoriesEndpoints : ICarterModule public static class StoriesEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapStoriesEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/stories").RequireAuthorization(); var group = app.MapGroup("api/stories").RequireAuthorization();
@@ -76,30 +70,6 @@ public sealed class StoriesEndpoints : ICarterModule
if (result.IsFailure) return result.Error.Code == "Unauthorized" ? Results.Forbid() : Results.NotFound(); if (result.IsFailure) return result.Error.Code == "Unauthorized" ? Results.Forbid() : Results.NotFound();
return Results.Ok(result.Value); return Results.Ok(result.Value);
}); });
group.MapPost("{id:guid}/reaction", async (Guid id, [FromBody] AddStoryReactionRequest request, ISender sender, IUserContext userContext, CancellationToken ct) =>
{
var result = await sender.Send(new AddStoryReactionCommand(userContext.UserId, id, request.Emoji), ct);
return result.IsSuccess ? Results.Ok(new { message = "Reaction added" }) : Results.NotFound();
});
group.MapDelete("{id:guid}/reaction", async (Guid id, [FromBody] RemoveStoryReactionRequest request, ISender sender, IUserContext userContext, CancellationToken ct) =>
{
var result = await sender.Send(new RemoveStoryReactionCommand(userContext.UserId, id, request.Emoji), ct);
return result.IsSuccess ? Results.Ok(new { message = "Reaction removed" }) : Results.NotFound();
});
group.MapPost("{id:guid}/reply", async (Guid id, [FromBody] AddStoryReplyRequest request, ISender sender, IUserContext userContext, CancellationToken ct) =>
{
var result = await sender.Send(new AddStoryReplyCommand(userContext.UserId, id, request.Content), ct);
return result.IsSuccess ? Results.Ok(new { message = "Reply added" }) : Results.NotFound();
});
group.MapGet("{id:guid}/replies", async (Guid id, ISender sender, IUserContext userContext, CancellationToken ct) =>
{
var result = await sender.Send(new GetStoryRepliesQuery(userContext.UserId, id), ct);
return result.IsSuccess ? Results.Ok(result.Value) : Results.NotFound();
});
} }
} }
@@ -9,7 +9,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AngleSharp" Version="1.1.2" /> <PackageReference Include="AngleSharp" Version="1.1.2" />
<PackageReference Include="Carter" Version="10.0.0" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@@ -1,18 +1,17 @@
using Carter;
using Knot.Shared.Kernel;
using Knot.Modules.TelegramImport.Application.TelegramImport.DTOs;
using Knot.Modules.TelegramImport.Application.TelegramImport; using Knot.Modules.TelegramImport.Application.TelegramImport;
using Knot.Modules.TelegramImport.Application.TelegramImport.DTOs;
using Knot.Shared.Kernel;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
namespace Knot.Modules.TelegramImport.Presentation.Endpoints; namespace Knot.Modules.TelegramImport.Presentation.Endpoints;
public sealed class TelegramImportEndpoints : ICarterModule public static class TelegramImportEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapTelegramImportEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/import/telegram").RequireAuthorization(); var group = app.MapGroup("api/import/telegram").RequireAuthorization();
@@ -10,7 +10,6 @@
<ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" /> <ProjectReference Include="..\..\Contracts\Settings\Knot.Contracts.Settings.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Carter" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.1.25120.3" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.1.25120.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,7 +1,6 @@
using Carter;
using MediatR;
using Knot.Shared.Kernel;
using Knot.Modules.WebRtc.Application.WebRtc.Queries; using Knot.Modules.WebRtc.Application.WebRtc.Queries;
using Knot.Shared.Kernel;
using MediatR;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
@@ -11,9 +10,9 @@ namespace Knot.Modules.WebRtc.Presentation.Endpoints;
/// <summary> /// <summary>
/// Endpoints for WebRTC signaling and ICE configuration /// Endpoints for WebRTC signaling and ICE configuration
/// </summary> /// </summary>
public sealed class WebRtcEndpoints : ICarterModule public static class WebRtcEndpoints
{ {
public void AddRoutes(IEndpointRouteBuilder app) public static void MapWebRtcEndpoints(this WebApplication app)
{ {
var group = app.MapGroup("api/webrtc") var group = app.MapGroup("api/webrtc")
.RequireAuthorization(); .RequireAuthorization();