was added firebase nitifying

This commit is contained in:
Artemy
2026-03-01 16:48:06 +07:00
parent 76d7280c71
commit eab0d746b8
60 changed files with 2335 additions and 1149 deletions
@@ -16,9 +16,10 @@ namespace Govor.Application.Services.Messages;
public class MessageCommandService : IMessageCommandService
{
private readonly IMessagesRepository _messagesRepository;
private readonly IUsersRepository _usersRepository;
private readonly IGroupsRepository _groupsRepository;
private readonly IPrivateChatsRepository _privateChats;
private readonly IPrivateChatsRepository _privateChatsRepository;
private readonly IUsersRepository _usersRepository;
private readonly IGroupsRepository _groupsRepository;
private readonly IUserPrivateChatsCreator _privateChatsCreator;
private readonly IVerifyFriendship _verifyFriendship;
private readonly IMediaService _mediaService;
private readonly ILogger<MessageCommandService> _logger;
@@ -27,77 +28,39 @@ public class MessageCommandService : IMessageCommandService
IMessagesRepository messagesRepository,
IUsersRepository usersRepository,
IGroupsRepository groupsRepository,
IPrivateChatsRepository privateChatsRepository,
IUserPrivateChatsCreator privateChatsCreator,
IVerifyFriendship verifyFriendship,
IPrivateChatsRepository privateChats,
IMediaService mediaService,
ILogger<MessageCommandService> logger)
{
_messagesRepository = messagesRepository;
_usersRepository = usersRepository;
_groupsRepository = groupsRepository;
_privateChatsRepository = privateChatsRepository;
_privateChatsCreator = privateChatsCreator;
_verifyFriendship = verifyFriendship;
_privateChats = privateChats;
_mediaService = mediaService;
_logger = logger;
}
public async Task<SendMessageResult> SendMessageAsync(SendMessage sendParams)
{
Guid recipientId;
try
{
// Validate recipient
if (sendParams.RecipientType == RecipientType.User)
var recipientId = sendParams.RecipientType switch
{
if (!await _usersRepository.ExistsByIdAsync(sendParams.RecipientId))
{
if (!_privateChats.Exist(sendParams.RecipientId))
{
_logger.LogWarning("Attempt to send message to non-existent user {RecipientId}", sendParams.RecipientId);
return new SendMessageResult(false, new KeyNotFoundException($"Recipient user {sendParams.RecipientId} not found."), default);
}
else
{
recipientId = sendParams.RecipientId;
}
}
else
{
// Verify friendship for private messages
await _verifyFriendship.VerifyAsync(sendParams.FromUserId, sendParams.RecipientId);
recipientId = await GetPrivateChatsIdAsync(sendParams.FromUserId, sendParams.RecipientId);
}
}
else if (sendParams.RecipientType == RecipientType.Group)
{
if (!_groupsRepository.Exist(sendParams.RecipientId))
{
_logger.LogWarning("Attempt to send message to non-existent group {GroupId}", sendParams.RecipientId);
return new SendMessageResult(false, new KeyNotFoundException($"Recipient group {sendParams.RecipientId} not found."), default);
}
// TODO: Optionally, verify if sender is a member of the group
bool isMember = await _groupsRepository.IsUserMemberOfGroupAsync(sendParams.FromUserId, sendParams.RecipientId);
if (!isMember)
{
_logger.LogWarning("User {UserId} attempted to send message to group {GroupId} but is not a member", sendParams.FromUserId, sendParams.RecipientId);
return new SendMessageResult(false, new UnauthorizedAccessException("Sender is not a member of the group."), default);
}
recipientId = sendParams.RecipientId;
}
else
{
_logger.LogError("Invalid recipient type specified: {RecipientType}", sendParams.RecipientType);
return new SendMessageResult(false, new ArgumentException("Invalid recipient type."), default);
}
RecipientType.User => await HandleUserRecipientAsync(sendParams),
RecipientType.Group => await HandleGroupRecipientAsync(sendParams),
_ => throw new ArgumentException("Invalid recipient type.")
};
var messageId = Guid.NewGuid();
var message = new Message
{
Id = messageId,
SenderId = sendParams.FromUserId,
RecipientId = recipientId,
RecipientId = recipientId,
RecipientType = sendParams.RecipientType,
EncryptedContent = sendParams.EncryptContent,
SentAt = sendParams.SendAt,
@@ -111,44 +74,61 @@ public class MessageCommandService : IMessageCommandService
}).ToList() ?? new List<MediaAttachments>()
};
// If there is media, we link them.
if (sendParams.Media != null && sendParams.Media.Any())
{
// Attach media
if (sendParams.Media?.Any() == true)
foreach (var media in sendParams.Media)
{
await _mediaService.AttachToMessageAsync(media.MediaId, messageId);
}
}
await _messagesRepository.AddAsync(message);
_logger.LogInformation("Message {MessageId} from {SenderId} to {RecipientId} ({RecipientType}) saved successfully.", messageId, sendParams.FromUserId, sendParams.RecipientId, sendParams.RecipientType);
_logger.LogInformation(
"Message {MessageId} from {SenderId} to {RecipientId} ({RecipientType}) saved successfully.",
messageId, sendParams.FromUserId, sendParams.RecipientId, sendParams.RecipientType);
return new SendMessageResult(true, null, message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error sending message from {SenderId} to {RecipientId} ({RecipientType})", sendParams.FromUserId, sendParams.RecipientId, sendParams.RecipientType);
_logger.LogError(
ex,
"Error sending message from {SenderId} to {RecipientId} ({RecipientType})",
sendParams.FromUserId, sendParams.RecipientId, sendParams.RecipientType);
return new SendMessageResult(false, ex, default);
}
}
private async Task<Guid> GetPrivateChatsIdAsync(Guid userA, Guid userB)
private async Task<Guid> HandleUserRecipientAsync(SendMessage sendParams)
{
Guid recipientId;
// Makes new PrivateChat if not exist
if (!_privateChats.Exist(userA, userB))
var privateChat = await _privateChatsRepository.GetByIdAsync(sendParams.RecipientId);
if (privateChat == null)
{
recipientId = Guid.NewGuid();
await _privateChats.AddAsync(new PrivateChat()
{ Id = recipientId, UserAId = userA, UserBId = userB });
}
else
{
recipientId = (await _privateChats.GetByMembersAsync(userA, userB)).Id;
_logger.LogWarning("Private chat {ChatId} not found", sendParams.RecipientId);
throw new KeyNotFoundException($"Private chat {sendParams.RecipientId} not found.");
}
return recipientId;
return privateChat.Id;
}
private async Task<Guid> HandleGroupRecipientAsync(SendMessage sendParams)
{
if (!_groupsRepository.Exist(sendParams.RecipientId))
{
_logger.LogWarning("Attempt to send message to non-existent group {GroupId}", sendParams.RecipientId);
throw new KeyNotFoundException($"Recipient group {sendParams.RecipientId} not found.");
}
var isMember = await _groupsRepository.IsUserMemberOfGroupAsync(sendParams.FromUserId, sendParams.RecipientId);
if (!isMember)
{
_logger.LogWarning("User {UserId} attempted to send message to group {GroupId} but is not a member",
sendParams.FromUserId, sendParams.RecipientId);
throw new UnauthorizedAccessException("Sender is not a member of the group.");
}
return sendParams.RecipientId;
}
//TODO: Full Cleanup all them:
public async Task<EditMessageResult> EditMessageAsync(EditMessage editParams)
{
try
@@ -157,13 +137,16 @@ public class MessageCommandService : IMessageCommandService
if (message.SenderId != editParams.EditorId)
{
_logger.LogWarning("User {EditorId} attempted to edit message {MessageId} not sent by them (sender was {SenderId})", editParams.EditorId, editParams.MessageId, message.SenderId);
return new EditMessageResult(false, new UnauthorizedAccessException("User is not authorized to edit this message."), null);
_logger.LogWarning(
"User {EditorId} attempted to edit message {MessageId} not sent by them (sender was {SenderId})",
editParams.EditorId, editParams.MessageId, message.SenderId);
return new EditMessageResult(false,
new UnauthorizedAccessException("User is not authorized to edit this message."), null);
}
/*if (message.SentAt < DateTime.UtcNow.AddMinutes(-15))
throw new Exception("Edit time limit exceeded");*/
var originalMessageForNotification = new Message
{
Id = message.Id,
@@ -174,7 +157,7 @@ public class MessageCommandService : IMessageCommandService
ReplyToMessageId = message.ReplyToMessageId,
Reactions = message.Reactions,
MediaAttachments = message.MediaAttachments,
MessageViews = message.MessageViews,
MessageViews = message.MessageViews
};
message.EncryptedContent = editParams.NewContent;
@@ -182,12 +165,14 @@ public class MessageCommandService : IMessageCommandService
message.EditedAt = editParams.EditedAt;
await _messagesRepository.UpdateAsync(message);
_logger.LogInformation("Message {MessageId} edited successfully by user {EditorId}", editParams.MessageId, editParams.EditorId);
_logger.LogInformation("Message {MessageId} edited successfully by user {EditorId}", editParams.MessageId,
editParams.EditorId);
return new EditMessageResult(true, default, originalMessageForNotification);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error editing message {MessageId} by user {EditorId}", editParams.MessageId, editParams.EditorId);
_logger.LogError(ex, "Error editing message {MessageId} by user {EditorId}", editParams.MessageId,
editParams.EditorId);
return new EditMessageResult(false, ex, default);
}
}
@@ -221,7 +206,7 @@ public class MessageCommandService : IMessageCommandService
Id = message.Id,
SenderId = message.SenderId,
RecipientId = message.RecipientId,
RecipientType = message.RecipientType,
RecipientType = message.RecipientType
};
await _messagesRepository.RemoveAsync(deleteParams.MessageId);
@@ -236,7 +221,8 @@ public class MessageCommandService : IMessageCommandService
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting message {MessageId} by user {DeleterId}", deleteParams.MessageId, deleteParams.DeleterId);
_logger.LogError(ex, "Error deleting message {MessageId} by user {DeleterId}", deleteParams.MessageId,
deleteParams.DeleterId);
return new DeleteMessageResult(false, ex, default);
}
}