feat: Add invite codes and message replies functionality

- Introduced a new migration to add InviteCodes table and ReplyToMessageId column in Messages.
- Updated ChatHub to support replying to messages.
- Enhanced ChatService to handle message replies and validate reply targets.
- Modified UserService to implement invite-only registration mode with invite code consumption.
- Added configuration options for registration modes in appsettings.
- Created unit tests for new features including invite code registration and message reply formatting.
This commit is contained in:
HueByte
2026-07-17 19:47:57 +02:00
parent bb987dda82
commit 3281064720
44 changed files with 2484 additions and 74 deletions
+3 -2
View File
@@ -15,8 +15,9 @@ public interface IChatService
// Messaging. originConnectionId identifies the connection the message came from so
// broadcasters can avoid echoing it back to that one connection (IRC convention);
// the sender's other sessions still receive it.
Task<string?> SendMessageAsync(Guid userId, string username, string channelName, string content, string? originConnectionId = null);
// the sender's other sessions still receive it. replyToMessageId references the message
// being replied to; it must exist in the same channel.
Task<string?> SendMessageAsync(Guid userId, string username, string channelName, string content, string? originConnectionId = null, Guid? replyToMessageId = null);
Task<List<MessageDto>> GetChannelHistoryAsync(string channelName, int count, int offset = 0);
// Presence
+3 -1
View File
@@ -4,7 +4,9 @@ namespace EchoHub.Core.Contracts;
public interface IUserService
{
Task<UserOperationResult> RegisterUserAsync(string username, string password, string? displayName = null);
// inviteCode is required when the server runs with Server:Registration = "invite";
// "closed" refuses all new accounts. Both REST and the IRC gateway funnel through here.
Task<UserOperationResult> RegisterUserAsync(string username, string password, string? displayName = null, string? inviteCode = null);
Task<UserOperationResult> AuthenticateUserAsync(string username, string password);
Task<UserProfileDto?> GetUserProfileAsync(string username);
Task<UserProfileDto?> GetUserByIdAsync(Guid userId);