diff --git a/DysonNetwork.Sphere/Chat/ChatController.cs b/DysonNetwork.Sphere/Chat/ChatController.cs index c5bd144..2a16591 100644 --- a/DysonNetwork.Sphere/Chat/ChatController.cs +++ b/DysonNetwork.Sphere/Chat/ChatController.cs @@ -12,6 +12,7 @@ using Grpc.Core; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using NodaTime; namespace DysonNetwork.Sphere.Chat; @@ -246,6 +247,7 @@ public partial class ChatController( public async Task SendMessage([FromBody] SendMessageRequest request, Guid roomId) { if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized(); + var accountId = Guid.Parse(currentUser.Id); request.Content = TextSanitizer.Sanitize(request.Content); if (string.IsNullOrWhiteSpace(request.Content) && @@ -254,9 +256,12 @@ public partial class ChatController( !request.PollId.HasValue) return BadRequest("You cannot send an empty message."); - var member = await crs.GetRoomMember(Guid.Parse(currentUser.Id), roomId); + var now = SystemClock.Instance.GetCurrentInstant(); + var member = await crs.GetRoomMember(accountId, roomId); if (member == null) return StatusCode(403, "You need to be a member to send messages here."); + if (member.TimeoutUntil.HasValue && member.TimeoutUntil.Value > now) + return StatusCode(403, "You has been timed out in this chat."); // Validate fund if provided if (request.FundId.HasValue) @@ -382,6 +387,7 @@ public partial class ChatController( public async Task UpdateMessage([FromBody] SendMessageRequest request, Guid roomId, Guid messageId) { if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized(); + var accountId = Guid.Parse(currentUser.Id); request.Content = TextSanitizer.Sanitize(request.Content); @@ -392,9 +398,11 @@ public partial class ChatController( if (message == null) return NotFound(); - var accountId = Guid.Parse(currentUser.Id); + var now = SystemClock.Instance.GetCurrentInstant(); if (message.Sender.AccountId != accountId) return StatusCode(403, "You can only edit your own messages."); + if (message.Sender.TimeoutUntil.HasValue && message.Sender.TimeoutUntil.Value > now) + return StatusCode(403, "You has been timed out in this chat."); if (string.IsNullOrWhiteSpace(request.Content) && (request.AttachmentsId == null || request.AttachmentsId.Count == 0) && @@ -402,23 +410,6 @@ public partial class ChatController( !request.PollId.HasValue) return BadRequest("You cannot send an empty message."); - // Validate reply and forward message IDs exist - if (request.RepliedMessageId.HasValue) - { - var repliedMessage = await db.ChatMessages - .FirstOrDefaultAsync(m => m.Id == request.RepliedMessageId.Value && m.ChatRoomId == roomId); - if (repliedMessage == null) - return BadRequest("The message you're replying to does not exist."); - } - - if (request.ForwardedMessageId.HasValue) - { - var forwardedMessage = await db.ChatMessages - .FirstOrDefaultAsync(m => m.Id == request.ForwardedMessageId.Value); - if (forwardedMessage == null) - return BadRequest("The message you're forwarding does not exist."); - } - // Update mentions based on new content and references var updatedMentions = await ExtractMentionedUsersAsync(request.Content, request.RepliedMessageId, request.ForwardedMessageId, roomId, accountId); diff --git a/DysonNetwork.Sphere/Chat/ChatService.cs b/DysonNetwork.Sphere/Chat/ChatService.cs index 97d66c6..27c4afc 100644 --- a/DysonNetwork.Sphere/Chat/ChatService.cs +++ b/DysonNetwork.Sphere/Chat/ChatService.cs @@ -707,14 +707,7 @@ public partial class ChatService( if (content is not null) message.Content = content; - if (meta is not null) - message.Meta = meta; - - if (repliedMessageId.HasValue) - message.RepliedMessageId = repliedMessageId; - - if (forwardedMessageId.HasValue) - message.ForwardedMessageId = forwardedMessageId; + // Update do not override meta, replies to and forwarded to if (attachmentsId is not null) await UpdateFileReferencesForMessageAsync(message, attachmentsId); diff --git a/DysonNetwork.Sphere/Chat/RealtimeCallController.cs b/DysonNetwork.Sphere/Chat/RealtimeCallController.cs index c3abbd3..954a77c 100644 --- a/DysonNetwork.Sphere/Chat/RealtimeCallController.cs +++ b/DysonNetwork.Sphere/Chat/RealtimeCallController.cs @@ -4,6 +4,7 @@ using DysonNetwork.Sphere.Chat.Realtime; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using NodaTime; using Swashbuckle.AspNetCore.Annotations; namespace DysonNetwork.Sphere.Chat; @@ -81,8 +82,11 @@ public class RealtimeCallController( .Where(m => m.AccountId == accountId && m.ChatRoomId == roomId && m.JoinedAt != null && m.LeaveAt == null) .FirstOrDefaultAsync(); + var now = SystemClock.Instance.GetCurrentInstant(); if (member == null) return StatusCode(403, "You need to be a member to join a call."); + if (member.TimeoutUntil.HasValue && member.TimeoutUntil.Value > now) + return StatusCode(403, "You has been timed out in this chat."); // Get ongoing call var ongoingCall = await cs.GetCallOngoingAsync(roomId); @@ -150,12 +154,16 @@ public class RealtimeCallController( if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized(); var accountId = Guid.Parse(currentUser.Id); + var now = SystemClock.Instance.GetCurrentInstant(); + var member = await db.ChatMembers .Where(m => m.AccountId == accountId && m.ChatRoomId == roomId && m.JoinedAt != null && m.LeaveAt == null) .Include(m => m.ChatRoom) .FirstOrDefaultAsync(); if (member == null) return StatusCode(403, "You need to be a member to start a call."); + if (member.TimeoutUntil.HasValue && member.TimeoutUntil.Value > now) + return StatusCode(403, "You has been timed out in this chat."); var ongoingCall = await cs.GetCallOngoingAsync(roomId); if (ongoingCall is not null) return StatusCode(423, "There is already an ongoing call inside the chatroom.");