diff --git a/apps/server-net/.editorconfig b/apps/server-net/.editorconfig
new file mode 100644
index 0000000..a078cf2
--- /dev/null
+++ b/apps/server-net/.editorconfig
@@ -0,0 +1,6 @@
+root = true
+
+[*.cs]
+csharp_prefer_braces = true:warning
+csharp_style_namespace_declarations = file_scoped:warning
+dotnet_diagnostic.IDE0011.severity = warning
diff --git a/apps/server-net/FormatFixer/FormatFixer.csproj b/apps/server-net/FormatFixer/FormatFixer.csproj
new file mode 100644
index 0000000..ed9781c
--- /dev/null
+++ b/apps/server-net/FormatFixer/FormatFixer.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/apps/server-net/FormatFixer/Program.cs b/apps/server-net/FormatFixer/Program.cs
new file mode 100644
index 0000000..0fedeb3
--- /dev/null
+++ b/apps/server-net/FormatFixer/Program.cs
@@ -0,0 +1,80 @@
+using System;
+using System.IO;
+
+namespace FormatFixer
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var srcPath = @"e:\GIT\forkmessager\apps\server-net\src";
+ var files = Directory.GetFiles(srcPath, "*.cs", SearchOption.AllDirectories);
+ foreach (var file in files)
+ {
+ var lines = File.ReadAllLines(file);
+ bool changed = false;
+ for (int i = 0; i < lines.Length; i++)
+ {
+ var line = lines[i];
+ var stripped = line.TrimStart();
+ if ((stripped.StartsWith("if (") || stripped.StartsWith("if(") ||
+ stripped.StartsWith("foreach (") || stripped.StartsWith("foreach("))
+ && stripped.EndsWith(";"))
+ {
+ // Check if it's already a block
+ if (stripped.Contains("{")) continue;
+
+ int parenCount = 0;
+ bool inString = false;
+ int firstParenIdx = line.IndexOf('(');
+ int condEndIdx = -1;
+
+ for (int j = firstParenIdx; j < line.Length; j++)
+ {
+ char c = line[j];
+ if (c == '"' && line[j - 1] != '\\')
+ {
+ inString = !inString;
+ }
+ else if (!inString)
+ {
+ if (c == '(') parenCount++;
+ else if (c == ')')
+ {
+ parenCount--;
+ if (parenCount == 0)
+ {
+ condEndIdx = j;
+ break;
+ }
+ }
+ }
+ }
+
+ if (condEndIdx != -1)
+ {
+ var statement = line.Substring(condEndIdx + 1).Trim();
+ if (!string.IsNullOrEmpty(statement) && !statement.StartsWith("{") && statement.EndsWith(";"))
+ {
+ var indent = line.Substring(0, line.Length - line.TrimStart().Length);
+ var newLine1 = line.Substring(0, condEndIdx + 1);
+ var newLine2 = indent + "{";
+ var newLine3 = indent + " " + statement;
+ var newLine4 = indent + "}";
+
+ lines[i] = newLine1 + Environment.NewLine + newLine2 + Environment.NewLine + newLine3 + Environment.NewLine + newLine4;
+ changed = true;
+ }
+ }
+ }
+ }
+ if (changed)
+ {
+ File.WriteAllText(file, string.Join(Environment.NewLine, lines));
+ Console.WriteLine("Fixed: " + file);
+ }
+ }
+ Console.WriteLine("Formatting complete.");
+ }
+ }
+}
diff --git a/apps/server-net/src/Host/Application/Admin/Commands/CleanRun/CleanRunCommand.cs b/apps/server-net/src/Host/Application/Admin/Commands/CleanRun/CleanRunCommand.cs
index cdb026e..11be342 100644
--- a/apps/server-net/src/Host/Application/Admin/Commands/CleanRun/CleanRunCommand.cs
+++ b/apps/server-net/src/Host/Application/Admin/Commands/CleanRun/CleanRunCommand.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
@@ -57,9 +57,18 @@ internal sealed class CleanRunCommandHandler : ICommandHandler !string.IsNullOrEmpty(u.Avatar))
.Select(u => u.Avatar!);
- foreach (var u in activeMessageUrls) validUrls.Add(u!);
- foreach (var u in activeChatUrls) validUrls.Add(u);
- foreach (var u in activeUserUrls) validUrls.Add(u);
+ foreach (var u in activeMessageUrls)
+ {
+ validUrls.Add(u!);
+ }
+ foreach (var u in activeChatUrls)
+ {
+ validUrls.Add(u);
+ }
+ foreach (var u in activeUserUrls)
+ {
+ validUrls.Add(u);
+ }
var validFileIds = validUrls
.Where(u => u.Contains("/api/files/"))
@@ -82,4 +91,4 @@ internal sealed class CleanRunCommandHandler : ICommandHandler> Handle(ResetUserPasswordCommand request, CancellationToken cancellationToken)
{
var user = await _userRepository.GetByIdAsync(request.UserId, cancellationToken);
- if (user == null) return Result.Failure(new Error("User.NotFound", "User not found"));
+ if (user == null)
+ {
+ return Result.Failure(new Error("User.NotFound", "User not found"));
+ }
if (string.IsNullOrWhiteSpace(request.NewPassword))
return Result.Failure(new Error("InvalidPassword", "Password cannot be empty"));
@@ -37,4 +40,4 @@ internal sealed class ResetUserPasswordCommandHandler : ICommandHandler !string.IsNullOrEmpty(u.Avatar))
.Select(u => u.Avatar!);
- foreach (var u in activeMessageUrls) validUrls.Add(u!);
- foreach (var u in activeChatUrls) validUrls.Add(u);
- foreach (var u in activeUserUrls) validUrls.Add(u);
+ foreach (var u in activeMessageUrls)
+ {
+ validUrls.Add(u!);
+ }
+ foreach (var u in activeChatUrls)
+ {
+ validUrls.Add(u);
+ }
+ foreach (var u in activeUserUrls)
+ {
+ validUrls.Add(u);
+ }
var validFileIds = validUrls
.Where(u => u.Contains("/api/files/"))
@@ -84,4 +93,4 @@ internal sealed class CleanDryRunQueryHandler : IQueryHandler> Handle(GetUserDetailsQuery request, CancellationToken cancellationToken)
{
var targetUser = await _userRepository.GetByIdAsync(request.UserId, cancellationToken);
- if (targetUser == null) return Result.Failure(new Error("User.NotFound", "User not found"));
+ if (targetUser == null)
+ {
+ return Result.Failure(new Error("User.NotFound", "User not found"));
+ }
var messagesCount = await _chatsDbContext.Messages.CountAsync(m => m.SenderId == request.UserId, cancellationToken);
@@ -69,4 +72,4 @@ internal sealed class GetUserDetailsQueryHandler : IQueryHandler> Handle(AddStoryReactionCommand request, CancellationToken cancellationToken)
{
var story = await _context.Stories.FindAsync(new object[] { request.StoryId }, cancellationToken);
- if (story == null) return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ if (story == null)
+ {
+ return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ }
var existing = await _context.StoryReactions
.FirstOrDefaultAsync(r => r.StoryId == request.StoryId && r.UserId == request.UserId && r.Emoji == request.Emoji, cancellationToken);
- if (existing != null) return Result.Success(new MessageResponse("Reaction already exists"));
+ if (existing != null)
+ {
+ return Result.Success(new MessageResponse("Reaction already exists"));
+ }
var reaction = new StoryReaction(request.StoryId, request.UserId, request.Emoji);
_context.StoryReactions.Add(reaction);
@@ -103,7 +109,10 @@ internal sealed class AddStoryReactionCommandHandler : ICommandHandler "🖼 Фото",
@@ -119,10 +128,13 @@ internal sealed class AddStoryReactionCommandHandler : ICommandHandler m.UserId == userId2));
- if (personalChat != null) return personalChat.Id;
+ if (personalChat != null)
+ {
+ return personalChat.Id;
+ }
var command = new Knot.Modules.Chats.Application.Chats.Create.CreateChatCommand(string.Empty, ChatType.Personal, new List { userId1, userId2 });
var result = await _sender.Send(command, cancellationToken);
return result.Value;
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Application/Stories/Commands/AddStoryReply/AddStoryReplyCommand.cs b/apps/server-net/src/Host/Application/Stories/Commands/AddStoryReply/AddStoryReplyCommand.cs
index 88656a4..7e77d23 100644
--- a/apps/server-net/src/Host/Application/Stories/Commands/AddStoryReply/AddStoryReplyCommand.cs
+++ b/apps/server-net/src/Host/Application/Stories/Commands/AddStoryReply/AddStoryReplyCommand.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -47,7 +47,10 @@ internal sealed class AddStoryReplyCommandHandler : ICommandHandler> Handle(AddStoryReplyCommand request, CancellationToken cancellationToken)
{
var story = await _context.Stories.FindAsync(new object[] { request.StoryId }, cancellationToken);
- if (story == null) return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ if (story == null)
+ {
+ return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ }
var reply = new StoryReply(request.StoryId, request.UserId, request.Content);
_context.StoryReplies.Add(reply);
@@ -89,7 +92,10 @@ internal sealed class AddStoryReplyCommandHandler : ICommandHandler "�� Фото",
@@ -105,10 +111,13 @@ internal sealed class AddStoryReplyCommandHandler : ICommandHandler m.UserId == userId2));
- if (personalChat != null) return personalChat.Id;
+ if (personalChat != null)
+ {
+ return personalChat.Id;
+ }
var command = new Knot.Modules.Chats.Application.Chats.Create.CreateChatCommand(string.Empty, ChatType.Personal, new List { userId1, userId2 });
var result = await _sender.Send(command, cancellationToken);
return result.Value;
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Application/Stories/Commands/DeleteStory/DeleteStoryCommand.cs b/apps/server-net/src/Host/Application/Stories/Commands/DeleteStory/DeleteStoryCommand.cs
index 04de990..2724e5c 100644
--- a/apps/server-net/src/Host/Application/Stories/Commands/DeleteStory/DeleteStoryCommand.cs
+++ b/apps/server-net/src/Host/Application/Stories/Commands/DeleteStory/DeleteStoryCommand.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
@@ -22,12 +22,18 @@ internal sealed class DeleteStoryCommandHandler : ICommandHandler> Handle(DeleteStoryCommand request, CancellationToken cancellationToken)
{
var story = await _context.Stories.FindAsync(new object[] { request.StoryId }, cancellationToken);
- if (story == null) return Result.Failure(new Error("Story.NotFound", "Story not found"));
- if (story.UserId != request.UserId) return Result.Failure(new Error("Unauthorized", "Unauthorized"));
+ if (story == null)
+ {
+ return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ }
+ if (story.UserId != request.UserId)
+ {
+ return Result.Failure(new Error("Unauthorized", "Unauthorized"));
+ }
_context.Stories.Remove(story);
await _context.SaveChangesAsync(cancellationToken);
return Result.Success(new MessageResponse("Story deleted"));
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Application/Stories/Commands/RemoveStoryReaction/RemoveStoryReactionCommand.cs b/apps/server-net/src/Host/Application/Stories/Commands/RemoveStoryReaction/RemoveStoryReactionCommand.cs
index 5f8416b..98f6547 100644
--- a/apps/server-net/src/Host/Application/Stories/Commands/RemoveStoryReaction/RemoveStoryReactionCommand.cs
+++ b/apps/server-net/src/Host/Application/Stories/Commands/RemoveStoryReaction/RemoveStoryReactionCommand.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -26,11 +26,14 @@ internal sealed class RemoveStoryReactionCommandHandler : ICommandHandler r.StoryId == request.StoryId && r.UserId == request.UserId && r.Emoji == request.Emoji, cancellationToken);
- if (reaction == null) return Result.Success(new MessageResponse("Reaction not found"));
+ if (reaction == null)
+ {
+ return Result.Success(new MessageResponse("Reaction not found"));
+ }
_context.StoryReactions.Remove(reaction);
await _context.SaveChangesAsync(cancellationToken);
return Result.Success(new MessageResponse("Reaction removed"));
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Application/Stories/Commands/ViewStory/ViewStoryCommand.cs b/apps/server-net/src/Host/Application/Stories/Commands/ViewStory/ViewStoryCommand.cs
index 73a4945..05ce334 100644
--- a/apps/server-net/src/Host/Application/Stories/Commands/ViewStory/ViewStoryCommand.cs
+++ b/apps/server-net/src/Host/Application/Stories/Commands/ViewStory/ViewStoryCommand.cs
@@ -36,7 +36,10 @@ internal sealed class ViewStoryCommandHandler : ICommandHandler s.Viewers)
.FirstOrDefaultAsync(s => s.Id == request.StoryId, cancellationToken);
- if (story == null) return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ if (story == null)
+ {
+ return Result.Failure(new Error("Story.NotFound", "Story not found"));
+ }
if (story.UserId == request.UserId)
{
@@ -70,4 +73,4 @@ internal sealed class ViewStoryCommandHandler : ICommandHandler
{
- if (r.User.Id == request.UserId) return 0;
+ if (r.User.Id == request.UserId)
+ {
+ return 0;
+ }
return 1;
}).ToList());
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Application/Stories/Queries/GetStoryReplies/GetStoryRepliesQuery.cs b/apps/server-net/src/Host/Application/Stories/Queries/GetStoryReplies/GetStoryRepliesQuery.cs
index 4f9f6ef..50e9402 100644
--- a/apps/server-net/src/Host/Application/Stories/Queries/GetStoryReplies/GetStoryRepliesQuery.cs
+++ b/apps/server-net/src/Host/Application/Stories/Queries/GetStoryReplies/GetStoryRepliesQuery.cs
@@ -31,14 +31,23 @@ internal sealed class GetStoryRepliesQueryHandler : IQueryHandler s.Replies)
.FirstOrDefaultAsync(s => s.Id == request.StoryId, cancellationToken);
- if (story == null) return Result.Failure>(new Error("Story.NotFound", "Story not found"));
- if (story.UserId != request.UserId) return Result.Failure>(new Error("Unauthorized", "Unauthorized"));
+ if (story == null)
+ {
+ return Result.Failure>(new Error("Story.NotFound", "Story not found"));
+ }
+ if (story.UserId != request.UserId)
+ {
+ return Result.Failure>(new Error("Unauthorized", "Unauthorized"));
+ }
var replies = new List();
foreach (var reply in story.Replies.OrderBy(r => r.CreatedAt))
{
var user = await _userRepository.GetByIdAsync(reply.UserId, cancellationToken);
- if (user == null) continue;
+ if (user == null)
+ {
+ continue;
+ }
replies.Add(new StoryReplyDto(
reply.Id,
@@ -53,4 +62,4 @@ internal sealed class GetStoryRepliesQueryHandler : IQueryHandler s.Viewers)
.FirstOrDefaultAsync(s => s.Id == request.StoryId, cancellationToken);
- if (story == null) return Result.Failure>(new Error("Story.NotFound", "Story not found"));
- if (story.UserId != request.UserId) return Result.Failure>(new Error("Unauthorized", "Unauthorized"));
+ if (story == null)
+ {
+ return Result.Failure>(new Error("Story.NotFound", "Story not found"));
+ }
+ if (story.UserId != request.UserId)
+ {
+ return Result.Failure>(new Error("Unauthorized", "Unauthorized"));
+ }
var viewerIds = story.Viewers.Select(v => v.UserId).ToList();
var viewers = new List();
@@ -40,7 +46,10 @@ internal sealed class GetStoryViewersQueryHandler : IQueryHandler v.UserId == viewerId);
@@ -55,4 +64,4 @@ internal sealed class GetStoryViewersQueryHandler : IQueryHandler(new Error("User.NotFound", "User not found"));
+ if (user == null)
+ {
+ return Result.Failure(new Error("User.NotFound", "User not found"));
+ }
var result = new StoryGroupDto(
new StoryUserDto(user.Id, user.Username, user.DisplayName, user.Avatar),
@@ -59,4 +62,4 @@ internal sealed class GetUserStoriesQueryHandler : IQueryHandler GetUserDetails(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new GetUserDetailsQuery(id), ct);
- if (result.IsFailure) return NotFound("User not found");
+ if (result.IsFailure)
+ {
+ return NotFound("User not found");
+ }
return Ok(result.Value);
}
@@ -104,4 +107,4 @@ public class AdminController : ControllerBase
var result = await _sender.Send(new CleanRunCommand(fileStorage, identityDb), ct);
return Ok(result.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/AuthController.cs b/apps/server-net/src/Host/Controllers/AuthController.cs
index 7d48ae4..b1fbe48 100644
--- a/apps/server-net/src/Host/Controllers/AuthController.cs
+++ b/apps/server-net/src/Host/Controllers/AuthController.cs
@@ -33,7 +33,10 @@ public sealed class AuthController : ControllerBase
public async Task GetMe([FromServices] IUserContext userContext, CancellationToken ct)
{
var result = await _sender.Send(new GetMeQuery(userContext.UserId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(new { User = result.Value.User });
}
@@ -44,4 +47,4 @@ public sealed class AuthController : ControllerBase
if (result.IsFailure) return Unauthorized(new { error = result.Error.Code ?? result.Error.Description });
return Ok(result.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/ChatsController.cs b/apps/server-net/src/Host/Controllers/ChatsController.cs
index 6ec8d0d..a7aadc5 100644
--- a/apps/server-net/src/Host/Controllers/ChatsController.cs
+++ b/apps/server-net/src/Host/Controllers/ChatsController.cs
@@ -41,7 +41,10 @@ public sealed class ChatsController : ControllerBase
public async Task GetChats(CancellationToken ct)
{
var result = await _sender.Send(new GetChatsQuery(_userContext.UserId), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(result.Value);
}
@@ -50,7 +53,10 @@ public sealed class ChatsController : ControllerBase
{
var command = new CreateChatCommand(request.Name, request.Type, request.MemberIds);
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -61,7 +67,10 @@ public sealed class ChatsController : ControllerBase
{
var command = new CreateChatCommand(string.Empty, ChatType.Personal, new List { _userContext.UserId, request.UserId });
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -79,7 +88,10 @@ public sealed class ChatsController : ControllerBase
var command = new CreateChatCommand(request.Name, ChatType.Group, memberIds);
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -89,7 +101,10 @@ public sealed class ChatsController : ControllerBase
public async Task GetOrCreateFavorites(CancellationToken ct)
{
var result = await _sender.Send(new GetOrCreateFavoritesCommand(_userContext.UserId), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -99,7 +114,10 @@ public sealed class ChatsController : ControllerBase
public async Task UpdateChat(Guid id, [FromBody] UpdateChatRequest request, CancellationToken ct)
{
var result = await _sender.Send(new UpdateChatCommand(id, _userContext.UserId, request.Name, request.Description), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -111,7 +129,10 @@ public sealed class ChatsController : ControllerBase
var result = await _sender.Send(new LeaveOrDeleteChatCommand(id, _userContext.UserId), ct);
if (result.IsFailure)
{
- if (result.Error.Code == "Unauthorized") return Forbid();
+ if (result.Error.Code == "Unauthorized")
+ {
+ return Forbid();
+ }
return NotFound();
}
return Ok(result.Value);
@@ -121,7 +142,10 @@ public sealed class ChatsController : ControllerBase
public async Task ClearChat(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new ClearChatCommand(id, _userContext.UserId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -129,7 +153,10 @@ public sealed class ChatsController : ControllerBase
public async Task TogglePin(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new TogglePinCommand(id, _userContext.UserId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -137,7 +164,10 @@ public sealed class ChatsController : ControllerBase
public async Task AddMembers(Guid id, [FromBody] AddMembersRequest request, CancellationToken ct)
{
var result = await _sender.Send(new AddMembersCommand(id, _userContext.UserId, request.UserIds.ToList()), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -147,7 +177,10 @@ public sealed class ChatsController : ControllerBase
public async Task RemoveMember(Guid id, Guid userId, CancellationToken ct)
{
var result = await _sender.Send(new RemoveMemberCommand(id, _userContext.UserId, userId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -156,12 +189,18 @@ public sealed class ChatsController : ControllerBase
[HttpPost("{id:guid}/avatar")]
public async Task UploadGroupAvatar(Guid id, Microsoft.AspNetCore.Http.IFormFile avatar, CancellationToken ct)
{
- if (avatar == null || avatar.Length == 0) return BadRequest("No file");
+ if (avatar == null || avatar.Length == 0)
+ {
+ return BadRequest("No file");
+ }
using var stream = avatar.OpenReadStream();
var result = await _sender.Send(new UploadGroupAvatarCommand(id, _userContext.UserId, avatar.FileName, avatar.ContentType, stream), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -170,12 +209,18 @@ public sealed class ChatsController : ControllerBase
[HttpPost("{id:guid}/avatar/crop")]
public async Task CropGroupAvatar(Guid id, [FromForm] Microsoft.AspNetCore.Http.IFormFile avatar, [FromForm] int x, [FromForm] int y, [FromForm] int width, [FromForm] int height, CancellationToken ct)
{
- if (avatar == null || avatar.Length == 0) return BadRequest("No file");
+ if (avatar == null || avatar.Length == 0)
+ {
+ return BadRequest("No file");
+ }
using var stream = avatar.OpenReadStream();
var result = await _sender.Send(new CropGroupAvatarCommand(id, _userContext.UserId, avatar.FileName, avatar.ContentType, stream, x, y, width, height), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
@@ -185,9 +230,12 @@ public sealed class ChatsController : ControllerBase
public async Task RemoveGroupAvatar(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new RemoveGroupAvatarCommand(id, _userContext.UserId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
var chatResult = await _sender.Send(new GetChatByIdQuery(_userContext.UserId, result.Value), ct);
return Ok(chatResult.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/FriendsController.cs b/apps/server-net/src/Host/Controllers/FriendsController.cs
index ee45036..af0da69 100644
--- a/apps/server-net/src/Host/Controllers/FriendsController.cs
+++ b/apps/server-net/src/Host/Controllers/FriendsController.cs
@@ -27,7 +27,10 @@ public sealed class FriendsController : ControllerBase
public async Task GetFriends(CancellationToken ct)
{
var result = await _sender.Send(new GetFriendsQuery(_userContext.UserId), ct);
- if (result.IsFailure) return BadRequest(result.Error);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error);
+ }
return Ok(result.Value);
}
@@ -35,7 +38,10 @@ public sealed class FriendsController : ControllerBase
public async Task GetRequests(CancellationToken ct)
{
var result = await _sender.Send(new GetIncomingRequestsQuery(_userContext.UserId), ct);
- if (result.IsFailure) return BadRequest(result.Error);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error);
+ }
return Ok(result.Value);
}
@@ -43,7 +49,10 @@ public sealed class FriendsController : ControllerBase
public async Task GetOutgoingRequests(CancellationToken ct)
{
var result = await _sender.Send(new GetOutgoingRequestsQuery(_userContext.UserId), ct);
- if (result.IsFailure) return BadRequest(result.Error);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error);
+ }
return Ok(result.Value);
}
@@ -51,7 +60,10 @@ public sealed class FriendsController : ControllerBase
public async Task SendRequest([FromBody] Host.Models.SendFriendRequest request, CancellationToken ct)
{
var result = await _sender.Send(new SendFriendRequestCommand(_userContext.UserId, request.FriendId), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(new { status = "pending" });
}
@@ -59,7 +71,10 @@ public sealed class FriendsController : ControllerBase
public async Task AcceptRequest(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new AcceptFriendRequestCommand(_userContext.UserId, id), ct);
- if (result.IsFailure) return NotFound(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error.Description);
+ }
return Ok(new { id = result.Value });
}
@@ -67,7 +82,10 @@ public sealed class FriendsController : ControllerBase
public async Task DeclineRequest(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new DeclineFriendRequestCommand(_userContext.UserId, id), ct);
- if (result.IsFailure) return NotFound(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error.Description);
+ }
return Ok(new Knot.Shared.Kernel.SuccessResponse(true));
}
@@ -75,7 +93,10 @@ public sealed class FriendsController : ControllerBase
public async Task GetStatus(Guid userId, CancellationToken ct)
{
var result = await _sender.Send(new GetFriendshipStatusQuery(_userContext.UserId, userId), ct);
- if (result.IsFailure) return BadRequest(result.Error);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error);
+ }
return Ok(result.Value);
}
@@ -83,7 +104,10 @@ public sealed class FriendsController : ControllerBase
public async Task RemoveFriend(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new RemoveFriendCommand(_userContext.UserId, id), ct);
- if (result.IsFailure) return NotFound(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error.Description);
+ }
return Ok(new Knot.Shared.Kernel.SuccessResponse(true));
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/MessagesController.cs b/apps/server-net/src/Host/Controllers/MessagesController.cs
index 9ff06ec..bb9b34e 100644
--- a/apps/server-net/src/Host/Controllers/MessagesController.cs
+++ b/apps/server-net/src/Host/Controllers/MessagesController.cs
@@ -34,7 +34,10 @@ public sealed class MessagesController : ControllerBase
public async Task GetMessages(Guid chatId, [FromQuery] string? cursor, CancellationToken ct = default)
{
var result = await _sender.Send(new GetMessagesQuery(_userContext.UserId, chatId, cursor), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(result.Value);
}
@@ -42,21 +45,30 @@ public sealed class MessagesController : ControllerBase
public async Task GetSearch([FromQuery] string q, [FromQuery] Guid? chatId, CancellationToken ct)
{
var result = await _sender.Send(new SearchMessagesQuery(_userContext.UserId, q, chatId), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(result.Value);
}
[HttpPost("upload")]
public async Task UploadFile(IFormFile file, CancellationToken ct)
{
- if (file == null || file.Length == 0) return BadRequest("No file uploaded");
+ if (file == null || file.Length == 0)
+ {
+ return BadRequest("No file uploaded");
+ }
using var stream = file.OpenReadStream();
var result = await _sender.Send(new UploadFileCommand(file.FileName, file.ContentType, file.Length, stream), ct);
if (result.IsFailure)
{
- if (result.Error.Code == "File.TooLarge") return StatusCode(413, result.Error.Description);
+ if (result.Error.Code == "File.TooLarge")
+ {
+ return StatusCode(413, result.Error.Description);
+ }
return BadRequest(result.Error.Description);
}
@@ -67,7 +79,10 @@ public sealed class MessagesController : ControllerBase
public async Task GetSharedMedia(Guid chatId, [FromQuery] string? type, CancellationToken ct)
{
var result = await _sender.Send(new GetSharedMediaQuery(_userContext.UserId, chatId, type), ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(result.Value);
}
@@ -89,8 +104,11 @@ public sealed class MessagesController : ControllerBase
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return BadRequest(result.Error.Description);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error.Description);
+ }
return Ok(result.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/StoriesController.cs b/apps/server-net/src/Host/Controllers/StoriesController.cs
index f2e9644..3ea3174 100644
--- a/apps/server-net/src/Host/Controllers/StoriesController.cs
+++ b/apps/server-net/src/Host/Controllers/StoriesController.cs
@@ -51,7 +51,10 @@ public sealed class StoriesController : ControllerBase
public async Task GetUserStories(Guid userId, CancellationToken ct)
{
var result = await _sender.Send(new GetUserStoriesQuery(_userContext.UserId, userId), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -59,7 +62,10 @@ public sealed class StoriesController : ControllerBase
public async Task ViewStory(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new ViewStoryCommand(_userContext.UserId, id), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -69,7 +75,10 @@ public sealed class StoriesController : ControllerBase
var result = await _sender.Send(new GetStoryViewersQuery(_userContext.UserId, id), ct);
if (result.IsFailure)
{
- if (result.Error.Code == "Unauthorized") return Forbid();
+ if (result.Error.Code == "Unauthorized")
+ {
+ return Forbid();
+ }
return NotFound();
}
return Ok(result.Value);
@@ -79,7 +88,10 @@ public sealed class StoriesController : ControllerBase
public async Task AddReaction(Guid id, [FromBody] AddStoryReactionRequest request, CancellationToken ct)
{
var result = await _sender.Send(new AddStoryReactionCommand(_userContext.UserId, id, request.Emoji), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -87,7 +99,10 @@ public sealed class StoriesController : ControllerBase
public async Task RemoveReaction(Guid id, [FromBody] RemoveStoryReactionRequest request, CancellationToken ct)
{
var result = await _sender.Send(new RemoveStoryReactionCommand(_userContext.UserId, id, request.Emoji), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -95,7 +110,10 @@ public sealed class StoriesController : ControllerBase
public async Task AddReply(Guid id, [FromBody] AddStoryReplyRequest request, CancellationToken ct)
{
var result = await _sender.Send(new AddStoryReplyCommand(_userContext.UserId, id, request.Content), ct);
- if (result.IsFailure) return NotFound();
+ if (result.IsFailure)
+ {
+ return NotFound();
+ }
return Ok(result.Value);
}
@@ -105,7 +123,10 @@ public sealed class StoriesController : ControllerBase
var result = await _sender.Send(new GetStoryRepliesQuery(_userContext.UserId, id), ct);
if (result.IsFailure)
{
- if (result.Error.Code == "Unauthorized") return Forbid();
+ if (result.Error.Code == "Unauthorized")
+ {
+ return Forbid();
+ }
return NotFound();
}
return Ok(result.Value);
@@ -117,9 +138,12 @@ public sealed class StoriesController : ControllerBase
var result = await _sender.Send(new DeleteStoryCommand(_userContext.UserId, id), ct);
if (result.IsFailure)
{
- if (result.Error.Code == "Unauthorized") return Forbid();
+ if (result.Error.Code == "Unauthorized")
+ {
+ return Forbid();
+ }
return NotFound();
}
return Ok(result.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Controllers/UsersController.cs b/apps/server-net/src/Host/Controllers/UsersController.cs
index 29141fe..ac68fd8 100644
--- a/apps/server-net/src/Host/Controllers/UsersController.cs
+++ b/apps/server-net/src/Host/Controllers/UsersController.cs
@@ -31,7 +31,10 @@ public sealed class UsersController : ControllerBase
public async Task Search([FromQuery] string q, CancellationToken ct)
{
var result = await _sender.Send(new SearchUsersQuery(q), ct);
- if (result.IsFailure) return BadRequest(result.Error);
+ if (result.IsFailure)
+ {
+ return BadRequest(result.Error);
+ }
return Ok(result.Value);
}
@@ -39,7 +42,10 @@ public sealed class UsersController : ControllerBase
public async Task UpdateSettings([FromBody] UpdateSettingsRequest request, CancellationToken ct)
{
var result = await _sender.Send(new UpdateSettingsCommand(_userContext.UserId, request.HideStoryViews), ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
@@ -47,7 +53,10 @@ public sealed class UsersController : ControllerBase
public async Task UploadAvatar(IFormFile avatar, CancellationToken ct)
{
var fileToUpload = avatar ?? Request.Form.Files.FirstOrDefault();
- if (fileToUpload == null || fileToUpload.Length == 0) return BadRequest("No file uploaded");
+ if (fileToUpload == null || fileToUpload.Length == 0)
+ {
+ return BadRequest("No file uploaded");
+ }
using var stream = fileToUpload.OpenReadStream();
var command = new UploadAvatarCommand(
@@ -58,14 +67,20 @@ public sealed class UsersController : ControllerBase
);
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
[HttpPost("avatar/crop")]
public async Task CropAvatar([FromForm] IFormFile avatar, [FromForm] int x, [FromForm] int y, [FromForm] int width, [FromForm] int height, CancellationToken ct)
{
- if (avatar == null || avatar.Length == 0) return BadRequest("No file uploaded");
+ if (avatar == null || avatar.Length == 0)
+ {
+ return BadRequest("No file uploaded");
+ }
using var stream = avatar.OpenReadStream();
var command = new CropAvatarCommand(
@@ -77,7 +92,10 @@ public sealed class UsersController : ControllerBase
);
var result = await _sender.Send(command, ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
@@ -85,7 +103,10 @@ public sealed class UsersController : ControllerBase
public async Task DeleteAvatar(CancellationToken ct)
{
var result = await _sender.Send(new DeleteAvatarCommand(_userContext.UserId), ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
@@ -93,7 +114,10 @@ public sealed class UsersController : ControllerBase
public async Task UpdateProfile([FromBody] UpdateProfileRequest request, CancellationToken ct)
{
var result = await _sender.Send(new UpdateProfileCommand(_userContext.UserId, request.DisplayName, request.Bio, request.Birthday), ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
@@ -101,7 +125,10 @@ public sealed class UsersController : ControllerBase
public async Task GetUser(Guid id, CancellationToken ct)
{
var result = await _sender.Send(new GetUserQuery(id), ct);
- if (result.IsFailure) return NotFound(result.Error);
+ if (result.IsFailure)
+ {
+ return NotFound(result.Error);
+ }
return Ok(result.Value);
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Host/Endpoints/FederationEndpoints.cs b/apps/server-net/src/Host/Endpoints/FederationEndpoints.cs
index a331f74..b8e8276 100644
--- a/apps/server-net/src/Host/Endpoints/FederationEndpoints.cs
+++ b/apps/server-net/src/Host/Endpoints/FederationEndpoints.cs
@@ -21,12 +21,21 @@ public sealed class FederationEndpoints : ICarterModule
group.MapPost("/handshake", async ([FromBody] Host.Application.Federation.Commands.HandshakeRequest request, ISender sender, CancellationToken ct) =>
{
var result = await sender.Send(new Host.Application.Federation.Commands.HandshakeFederationCommand(request), ct);
- if (result.IsSuccess) return Results.Ok(result.Value);
+ if (result.IsSuccess)
+ {
+ return Results.Ok(result.Value);
+ }
- if (result.Error.Code == "Unauthorized") return Results.Forbid();
- if (result.Error.Code == Knot.Shared.Kernel.Constants.Errors.DisabledByAdmin) return Results.StatusCode(503);
+ if (result.Error.Code == "Unauthorized")
+ {
+ return Results.Forbid();
+ }
+ if (result.Error.Code == Knot.Shared.Kernel.Constants.Errors.DisabledByAdmin)
+ {
+ return Results.StatusCode(503);
+ }
return Results.BadRequest(new { error = result.Error.Description });
});
}
-}
+}
\ No newline at end of file
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/Avatar/Avatar.cs b/apps/server-net/src/Modules/Chats/Application/Chats/Avatar/Avatar.cs
index e9f501a..03447ac 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/Avatar/Avatar.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/Avatar/Avatar.cs
@@ -32,7 +32,9 @@ internal sealed class UploadGroupAvatarCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
var fileId = await _fileStorage.UploadFileAsync(request.FileStream, request.FileName, request.ContentType);
var url = $"/api/files/{fileId}";
@@ -64,7 +66,9 @@ internal sealed class CropGroupAvatarCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
string url;
@@ -112,7 +116,9 @@ internal sealed class RemoveGroupAvatarCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
chat.UpdateAvatar(null);
_chatRepository.Update(chat);
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/Clear/ClearChat.cs b/apps/server-net/src/Modules/Chats/Application/Chats/Clear/ClearChat.cs
index 5f9b6b0..6463e25 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/Clear/ClearChat.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/Clear/ClearChat.cs
@@ -24,7 +24,9 @@ internal sealed class ClearChatCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
// Currently a placeholder
return Result.Success(new MessageResponse("Cleared"));
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/GetChatById/GetChatById.cs b/apps/server-net/src/Modules/Chats/Application/Chats/GetChatById/GetChatById.cs
index 613c527..a8f73db 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/GetChatById/GetChatById.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/GetChatById/GetChatById.cs
@@ -29,7 +29,10 @@ internal sealed class GetChatByIdQueryHandler : IQueryHandler> Handle(GetChatByIdQuery request, CancellationToken cancellationToken)
{
var chat = await _chatRepository.GetByIdAsync(request.ChatId, cancellationToken);
- if (chat == null) return Result.Success(null);
+ if (chat == null)
+ {
+ return Result.Success(null);
+ }
if (!chat.Members.Any(m => m.UserId == request.UserId))
{
@@ -37,14 +40,20 @@ internal sealed class GetChatByIdQueryHandler : IQueryHandler();
- foreach (var m in chat.Members) userIdsToFetch.Add(m.UserId);
+ foreach (var m in chat.Members)
+ {
+ userIdsToFetch.Add(m.UserId);
+ }
var chatMessages = await _messageRepository.GetChatMessagesAsync(chat.Id, 1, 0, cancellationToken);
var mFirst = chatMessages.FirstOrDefault();
if (mFirst != null)
{
userIdsToFetch.Add(mFirst.SenderId);
- foreach (var r in mFirst.Reactions) userIdsToFetch.Add(r.UserId);
+ foreach (var r in mFirst.Reactions)
+ {
+ userIdsToFetch.Add(r.UserId);
+ }
}
var usersInfo = await _userProvider.GetUsersInfoAsync(userIdsToFetch, cancellationToken);
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/GetChats/GetChats.cs b/apps/server-net/src/Modules/Chats/Application/Chats/GetChats/GetChats.cs
index 392161e..9ac35b1 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/GetChats/GetChats.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/GetChats/GetChats.cs
@@ -36,14 +36,20 @@ internal sealed class GetChatsQueryHandler : IQueryHandler();
- foreach (var m in c.Members) userIdsToFetch.Add(m.UserId);
+ foreach (var m in c.Members)
+ {
+ userIdsToFetch.Add(m.UserId);
+ }
var chatMessages = await _messageRepository.GetChatMessagesAsync(c.Id, 1, 0, cancellationToken);
var mFirst = chatMessages.FirstOrDefault();
if (mFirst != null)
{
userIdsToFetch.Add(mFirst.SenderId);
- foreach (var r in mFirst.Reactions) userIdsToFetch.Add(r.UserId);
+ foreach (var r in mFirst.Reactions)
+ {
+ userIdsToFetch.Add(r.UserId);
+ }
}
var usersInfo = await _userProvider.GetUsersInfoAsync(userIdsToFetch, cancellationToken);
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/LeaveOrDelete/LeaveOrDeleteChat.cs b/apps/server-net/src/Modules/Chats/Application/Chats/LeaveOrDelete/LeaveOrDeleteChat.cs
index 1a8edaa..1f0c0c0 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/LeaveOrDelete/LeaveOrDeleteChat.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/LeaveOrDelete/LeaveOrDeleteChat.cs
@@ -25,10 +25,15 @@ internal sealed class LeaveOrDeleteChatCommandHandler : ICommandHandler> Handle(LeaveOrDeleteChatCommand request, CancellationToken cancellationToken)
{
var chat = await _chatRepository.GetByIdAsync(request.ChatId, cancellationToken);
- if (chat == null) return Result.Success(new SuccessResponse(true));
+ if (chat == null)
+ {
+ return Result.Success(new SuccessResponse(true));
+ }
if (!chat.Members.Any(m => m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Unauthorized", "Access denied"));
+ }
if (chat.Type == ChatType.Group)
{
@@ -39,7 +44,7 @@ internal sealed class LeaveOrDeleteChatCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
foreach (var userId in request.UserIdsToAdd)
{
@@ -57,7 +59,9 @@ internal sealed class RemoveMemberCommandHandler : ICommandHandler m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
chat.RemoveMember(request.UserIdToRemove);
_chatRepository.Update(chat);
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/TogglePin/TogglePin.cs b/apps/server-net/src/Modules/Chats/Application/Chats/TogglePin/TogglePin.cs
index 0739448..22337bd 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/TogglePin/TogglePin.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/TogglePin/TogglePin.cs
@@ -27,11 +27,15 @@ internal sealed class TogglePinCommandHandler : ICommandHandler(new Error("Chat.NotFound", "Chat not found"));
+ }
var member = chat.Members.FirstOrDefault(m => m.UserId == request.UserId);
if (member == null)
+ {
return Result.Failure(new Error("Chat.NotFound", "Member not found"));
+ }
member.TogglePin();
_chatRepository.Update(chat);
diff --git a/apps/server-net/src/Modules/Chats/Application/Chats/Update/UpdateChat.cs b/apps/server-net/src/Modules/Chats/Application/Chats/Update/UpdateChat.cs
index 393c1e5..4c89b3f 100644
--- a/apps/server-net/src/Modules/Chats/Application/Chats/Update/UpdateChat.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Chats/Update/UpdateChat.cs
@@ -25,12 +25,21 @@ internal sealed class UpdateChatCommandHandler : ICommandHandler> Handle(UpdateChatCommand request, CancellationToken cancellationToken)
{
var chat = await _chatRepository.GetByIdAsync(request.ChatId, cancellationToken);
- if (chat == null || !chat.Members.Any(m => m.UserId == request.UserId))
+ if (chat == null || !chat.Members.Any(m => m.UserId == request.UserId))
+ {
return Result.Failure(new Error("Chat.NotFound", "Chat not found or access denied"));
+ }
+
+ if (request.Name != null)
+ {
+ chat.UpdateName(request.Name);
+ }
+
+ if (request.Description != null)
+ {
+ chat.UpdateDescription(request.Description);
+ }
- if (request.Name != null) chat.UpdateName(request.Name);
- if (request.Description != null) chat.UpdateDescription(request.Description);
-
_chatRepository.Update(chat);
await _uow.SaveChangesAsync(cancellationToken);
diff --git a/apps/server-net/src/Modules/Chats/Application/DTOs/SendMessageRequest.cs b/apps/server-net/src/Modules/Chats/Application/DTOs/SendMessageRequest.cs
index 01d66e8..7cbfa31 100644
--- a/apps/server-net/src/Modules/Chats/Application/DTOs/SendMessageRequest.cs
+++ b/apps/server-net/src/Modules/Chats/Application/DTOs/SendMessageRequest.cs
@@ -4,8 +4,8 @@ using System.Collections.Generic;
namespace Knot.Modules.Chats.Application.DTOs;
public sealed record SendMessageRequest(
- string? Content,
- string Type,
+ string? Content,
+ string Type,
List? Attachments = null,
Guid? ReplyToId = null,
string? Quote = null,
diff --git a/apps/server-net/src/Modules/Chats/Application/Messages/Delete/DeleteMessagesCommand.cs b/apps/server-net/src/Modules/Chats/Application/Messages/Delete/DeleteMessagesCommand.cs
index 25fc868..4e66696 100644
--- a/apps/server-net/src/Modules/Chats/Application/Messages/Delete/DeleteMessagesCommand.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Messages/Delete/DeleteMessagesCommand.cs
@@ -20,7 +20,7 @@ public sealed class DeleteMessagesCommandHandler : ICommandHandler _hubContext;
public DeleteMessagesCommandHandler(
- IMessageRepository messageRepository,
+ IMessageRepository messageRepository,
IChatsUnitOfWork unitOfWork,
IHubContext hubContext)
{
@@ -34,7 +34,10 @@ public sealed class DeleteMessagesCommandHandler : ICommandHandler {
+ var filteredMedia = m.Media.Where(media =>
+ {
var mediaType = media.Type?.ToLower() ?? "file";
var isGif = mediaType == "image" && (media.Url.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase) || media.Url.EndsWith(".gif", StringComparison.OrdinalIgnoreCase));
- if (filterType == "media") return (mediaType == "image" || mediaType == "video") && !isGif;
- if (filterType == "gifs") return isGif;
- if (filterType == "files") return mediaType != "image" && mediaType != "video" && mediaType != "link";
+ if (filterType == "media")
+ {
+ return (mediaType == "image" || mediaType == "video") && !isGif;
+ }
+
+ if (filterType == "gifs")
+ {
+ return isGif;
+ }
+
+ if (filterType == "files")
+ {
+ return mediaType != "image" && mediaType != "video" && mediaType != "link";
+ }
+
return true;
}).ToList();
diff --git a/apps/server-net/src/Modules/Chats/Application/Messages/Read/ReadMessagesCommandHandler.cs b/apps/server-net/src/Modules/Chats/Application/Messages/Read/ReadMessagesCommandHandler.cs
index 5da1166..3dd9147 100644
--- a/apps/server-net/src/Modules/Chats/Application/Messages/Read/ReadMessagesCommandHandler.cs
+++ b/apps/server-net/src/Modules/Chats/Application/Messages/Read/ReadMessagesCommandHandler.cs
@@ -26,7 +26,7 @@ public sealed class ReadMessagesCommandHandler : ICommandHandler> Handle(UploadFileCommand request, CancellationToken cancellationToken)
{
- if (request.Length == 0) return Result.Failure(new Error("File.Empty", "No file uploaded"));
+ if (request.Length == 0)
+ {
+ return Result.Failure(new Error("File.Empty", "No file uploaded"));
+ }
var maxMb = _settingsService.Current.MaxFileSizeMb;
if (request.Length > maxMb * 1024 * 1024)
+ {
return Result.Failure(new Error("File.TooLarge", $"File exceeds the maximum allowed size of {maxMb}MB."));
+ }
var fileId = await _fileStorage.UploadFileAsync(request.FileStream, request.FileName, request.ContentType);
-
+
return Result.Success(new UploadFileResponseDto("/api/files/" + fileId, request.FileName, request.Length));
}
}
diff --git a/apps/server-net/src/Modules/Chats/Application/TelegramImport/AnalyzeImportCommand.cs b/apps/server-net/src/Modules/Chats/Application/TelegramImport/AnalyzeImportCommand.cs
index c95ec2f..ed4861a 100644
--- a/apps/server-net/src/Modules/Chats/Application/TelegramImport/AnalyzeImportCommand.cs
+++ b/apps/server-net/src/Modules/Chats/Application/TelegramImport/AnalyzeImportCommand.cs
@@ -27,10 +27,14 @@ internal sealed class AnalyzeImportCommandHandler : ICommandHandler> Handle(AnalyzeImportCommand request, CancellationToken cancellationToken)
{
if (request.FileStream == null || request.FileStream.Length == 0)
+ {
return Result.Failure(new Error("File.Empty", "No file uploaded"));
-
+ }
+
if (!request.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
+ {
return Result.Failure(new Error("File.InvalidExtension", "Must be a ZIP archive"));
+ }
var token = Guid.NewGuid();
var tempPath = Path.Combine(Path.GetTempPath(), $"{token}.zip");
@@ -54,7 +58,10 @@ internal sealed class AnalyzeImportCommandHandler : ICommandHandler> Handle(ExecuteImportCommand request, CancellationToken cancellationToken)
{
if (!TelegramImportState.TempZips.TryGetValue(request.Token, out var tempPath))
+ {
return Result.Failure(new Error("Import.Expired", "Session not found or expired"));
+ }
if (!System.IO.File.Exists(tempPath))
+ {
return Result.Failure(new Error("Import.Missing", "ZIP file lost"));
+ }
var myId = request.CurrentUserId;
var targetUserIds = request.Mapping.Values.Distinct().Where(id => id != Guid.Empty).ToList();
- if (!targetUserIds.Contains(myId)) targetUserIds.Add(myId);
+ if (!targetUserIds.Contains(myId))
+ {
+ targetUserIds.Add(myId);
+ }
Guid chatId = Guid.Empty;
var chatMembers = targetUserIds;
@@ -71,7 +78,7 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler c.Type == ChatType.Personal && c.Members.All(m => chatMembers.Contains(m.UserId)) && c.Members.Count == chatMembers.Count);
-
+
if (personalChat != null)
{
chatId = personalChat.Id;
@@ -79,10 +86,18 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler id != myId);
- if (friendId == Guid.Empty) friendId = myId;
+ if (friendId == Guid.Empty)
+ {
+ friendId = myId;
+ }
+
var command = new CreateChatCommand(string.Empty, ChatType.Personal, new List { myId, friendId });
var res = await _sender.Send(command, cancellationToken);
- if (res.IsFailure) return Result.Failure(new Error("Import.CreateChatFailed", res.Error.Description ?? res.Error.Code));
+ if (res.IsFailure)
+ {
+ return Result.Failure(new Error("Import.CreateChatFailed", res.Error.Description ?? res.Error.Code));
+ }
+
chatId = res.Value;
}
}
@@ -90,7 +105,11 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler(new Error("Import.CreateChatFailed", res.Error.Description ?? res.Error.Code));
+ if (res.IsFailure)
+ {
+ return Result.Failure(new Error("Import.CreateChatFailed", res.Error.Description ?? res.Error.Code));
+ }
+
chatId = res.Value;
}
@@ -100,7 +119,7 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler e.FullName.EndsWith(".html", StringComparison.OrdinalIgnoreCase) && e.Name.StartsWith("messages", StringComparison.OrdinalIgnoreCase))
- .OrderBy(e =>
+ .OrderBy(e =>
{
var name = e.Name.ToLower().Replace("messages", "").Replace(".html", "");
return string.IsNullOrEmpty(name) ? 0 : int.TryParse(name, out var num) ? num : 999999;
@@ -119,10 +138,16 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler .text") ?? node.QuerySelector(".text:not(.forwarded .text)"))
: node.QuerySelector(".text");
@@ -168,7 +200,7 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler" + html + "");
content = tempDoc.Body?.TextContent.Trim() ?? "";
}
-
+
DateTime createdAt = lastCreatedAt;
var titleNodes = node.QuerySelectorAll("[title]");
bool parsed = false;
@@ -178,11 +210,11 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler= 10 && char.IsDigit(dateStr[0]) && char.IsDigit(dateStr[1]))
{
var cleanStr = dateStr.Replace("UTC", "", StringComparison.OrdinalIgnoreCase).Trim();
-
+
if (DateTimeOffset.TryParseExact(cleanStr, "dd.MM.yyyy HH:mm:ss zzz", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out var dto))
{
createdAt = dto.UtcDateTime;
@@ -223,10 +255,13 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler" + fHtml + "");
fwdContent = tempDoc.Body?.TextContent.Trim() ?? "";
}
-
+
if (forwardedFromId == null)
{
- content = string.IsNullOrEmpty(content)
- ? $"[Переслано от {fwdName}]:\n{fwdContent}"
+ content = string.IsNullOrEmpty(content)
+ ? $"[Переслано от {fwdName}]:\n{fwdContent}"
: $"{content}\n\n[Переслано от {fwdName}]:\n{fwdContent}";
}
else if (string.IsNullOrEmpty(content))
@@ -282,7 +317,7 @@ internal sealed class ExecuteImportCommandHandler : ICommandHandler(options =>
options.UseNpgsql(connectionString));
@@ -30,7 +30,7 @@ public static class DependencyInjection
services.AddScoped();
// Регистрация MediatR для этого модуля
- services.AddMediatR(config =>
+ services.AddMediatR(config =>
config.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly));
return services;
diff --git a/apps/server-net/src/Modules/Chats/Domain/Chat.cs b/apps/server-net/src/Modules/Chats/Domain/Chat.cs
index 834fe59..2977dce 100644
--- a/apps/server-net/src/Modules/Chats/Domain/Chat.cs
+++ b/apps/server-net/src/Modules/Chats/Domain/Chat.cs
@@ -80,7 +80,11 @@ public sealed class Chat : AggregateRoot
public void AddMember(Guid userId, string role = "member")
{
- if (_members.Any(m => m.UserId == userId)) return;
+ if (_members.Any(m => m.UserId == userId))
+ {
+ return;
+ }
+
_members.Add(new ChatMember(Id, userId, role));
RaiseDomainEvent(new ChatMemberAddedDomainEvent(Id, userId));
}
@@ -88,7 +92,10 @@ public sealed class Chat : AggregateRoot
public void RemoveMember(Guid userId)
{
var member = _members.FirstOrDefault(m => m.UserId == userId);
- if (member != null) _members.Remove(member);
+ if (member != null)
+ {
+ _members.Remove(member);
+ }
}
public void UpdateName(string name) => Name = name;
diff --git a/apps/server-net/src/Modules/Chats/Domain/ReadReceipt.cs b/apps/server-net/src/Modules/Chats/Domain/ReadReceipt.cs
index e5dae44..1bf5a5f 100644
--- a/apps/server-net/src/Modules/Chats/Domain/ReadReceipt.cs
+++ b/apps/server-net/src/Modules/Chats/Domain/ReadReceipt.cs
@@ -7,7 +7,7 @@ public sealed class ReadReceipt : Entity
public Guid MessageId { get; private set; }
public Guid UserId { get; private set; }
public DateTime ReadAt { get; private set; }
-
+
// Для EF Core
private ReadReceipt() : base(Guid.Empty) { }
diff --git a/apps/server-net/src/Modules/Chats/Infrastructure/Handlers/ChatCreatedDomainEventHandler.cs b/apps/server-net/src/Modules/Chats/Infrastructure/Handlers/ChatCreatedDomainEventHandler.cs
index 5b27349..27aa7a5 100644
--- a/apps/server-net/src/Modules/Chats/Infrastructure/Handlers/ChatCreatedDomainEventHandler.cs
+++ b/apps/server-net/src/Modules/Chats/Infrastructure/Handlers/ChatCreatedDomainEventHandler.cs
@@ -16,7 +16,7 @@ public sealed class ChatCreatedDomainEventHandler : INotificationHandler hubContext,
+ IHubContext hubContext,
IChatRepository chatRepository,
IUserDisplayNameProvider displayNameProvider)
{
@@ -52,7 +52,7 @@ public sealed class ChatCreatedDomainEventHandler : INotificationHandler hubContext,
+ IHubContext hubContext,
IMessageRepository messageRepository,
IUserDisplayNameProvider displayNameProvider)
{
@@ -29,10 +29,13 @@ public sealed class MessageSentDomainEventHandler : INotificationHandler new {
- m.Id,
- m.Type,
- m.Url,
+ Media = message.Media.Select(m => new
+ {
+ m.Id,
+ m.Type,
+ m.Url,
Filename = m.Filename,
- Size = m.Size
+ Size = m.Size
}).ToList(),
Sender = senderObj,
ReadBy = new List