mirror of
https://github.com/Govor-team/Govor.git
synced 2026-09-21 02:10:56 +00:00
Add read receipts and editing limits
Introduced message read tracking with a dedicated MessageReadingService, SignalR read request/response contracts, and hub notification flow for read receipts. Added configurable message edit constraints through MessageEditingOptions and a shared INowDateTimeProvider so timestamps are consistent across the app. Also fixed recipient validation in message removal and improved push token upsert behavior by matching the correct user/session record.
This commit is contained in:
@@ -3,18 +3,24 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Govor.Domain;
|
||||
using Govor.Domain.Models.Messages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Govor.Application.Messages;
|
||||
|
||||
public class MessageEditingService : IMessageEditingService
|
||||
{
|
||||
private readonly GovorDbContext _dbContext;
|
||||
private readonly GovorDbContext _dbContext;
|
||||
private readonly ILogger<MessageEditingService> _logger;
|
||||
private readonly MessageEditingOptions _options;
|
||||
|
||||
public MessageEditingService(GovorDbContext dbContext, ILogger<MessageEditingService> logger)
|
||||
public MessageEditingService(
|
||||
GovorDbContext dbContext,
|
||||
ILogger<MessageEditingService> logger,
|
||||
IOptions<MessageEditingOptions> options)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
_options = options.Value;
|
||||
}
|
||||
|
||||
public async Task<EditMessageResult> EditMessageAsync(EditMessage editParams)
|
||||
@@ -25,15 +31,47 @@ public class MessageEditingService : IMessageEditingService
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
return new EditMessageResult(false, new KeyNotFoundException("Message not found."), null);
|
||||
return new EditMessageResult(
|
||||
false,
|
||||
new KeyNotFoundException("Message not found."),
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
if (message.SenderId != editParams.EditorId)
|
||||
{
|
||||
_logger.LogWarning("User {EditorId} unauthorized to edit message {MessageId}", editParams.EditorId, editParams.MessageId);
|
||||
return new EditMessageResult(false, new UnauthorizedAccessException("User is not authorized to edit this message."), null);
|
||||
_logger.LogWarning(
|
||||
"User {EditorId} unauthorized to edit message {MessageId}",
|
||||
editParams.EditorId,
|
||||
editParams.MessageId);
|
||||
|
||||
return new EditMessageResult(
|
||||
false,
|
||||
new UnauthorizedAccessException(
|
||||
"User is not authorized to edit this message."),
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
// Проверяем время, прошедшее с момента отправки
|
||||
var now = DateTime.UtcNow;
|
||||
var editDeadline = message.SentAt.AddMinutes(
|
||||
_options.MaxEditTimeMinutes);
|
||||
|
||||
if (now > editDeadline && _options.Enabled)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"Message {MessageId} cannot be edited. " +
|
||||
"Edit time limit of {MaxEditTimeMinutes} minutes has expired.",
|
||||
message.Id,
|
||||
_options.MaxEditTimeMinutes);
|
||||
|
||||
return new EditMessageResult(
|
||||
false,
|
||||
new InvalidOperationException(
|
||||
$"Message can only be edited within " +
|
||||
$"{_options.MaxEditTimeMinutes} minutes after sending."),
|
||||
null);
|
||||
}
|
||||
|
||||
var originalMessageSnapshot = new Message
|
||||
{
|
||||
Id = message.Id,
|
||||
@@ -44,14 +82,20 @@ public class MessageEditingService : IMessageEditingService
|
||||
ReplyToMessageId = message.ReplyToMessageId,
|
||||
MediaAttachments = message.MediaAttachments?.ToList() ?? []
|
||||
};
|
||||
|
||||
|
||||
message.EncryptedContent = editParams.NewContent;
|
||||
message.IsEdited = true;
|
||||
message.EditedAt = editParams.EditedAt;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation("Message {MessageId} edited successfully.", editParams.MessageId);
|
||||
return new EditMessageResult(true, null, originalMessageSnapshot);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Message {MessageId} edited successfully.",
|
||||
editParams.MessageId);
|
||||
|
||||
return new EditMessageResult(
|
||||
true,
|
||||
null,
|
||||
originalMessageSnapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user