feat: add password protection for channels

- Updated IChatService to include password parameter in JoinChannelAsync method.
- Modified ChannelDto and related models to support password functionality.
- Implemented password handling in ChannelService for channel creation and membership validation.
- Enhanced IrcCommandHandler to manage channel join requests with passwords.
- Added ChannelPasswordDialog for user input when joining protected channels.
- Created database migration to add PasswordHash column to Channels table.
- Updated tests to cover new password functionality in channel joining and management.
This commit is contained in:
HueByte
2026-07-16 03:13:03 +02:00
parent 15187c4665
commit 3ca9dbfd91
31 changed files with 1056 additions and 96 deletions
@@ -6,8 +6,9 @@ public interface IChannelService
{
// Channel CRUD
Task<PaginatedResponse<ChannelDto>> GetChannelsAsync(Guid userId, int offset, int limit);
Task<ChannelOperationResult> CreateChannelAsync(Guid creatorUserId, string name, string? topic, bool isPublic);
Task<ChannelOperationResult> CreateChannelAsync(Guid creatorUserId, string name, string? topic, bool isPublic, string? password = null);
Task<ChannelOperationResult> UpdateTopicAsync(Guid callerUserId, string channelName, string? topic);
Task<ChannelOperationResult> SetChannelPasswordAsync(Guid callerUserId, string channelName, string? password);
Task<ChannelOperationResult> DeleteChannelAsync(Guid callerUserId, string channelName);
// Channel queries
@@ -16,7 +17,7 @@ public interface IChannelService
Task<ChannelDto?> GetChannelByNameAsync(string channelName);
// Membership
Task<(bool Success, string? Error)> EnsureChannelMembershipAsync(Guid userId, string channelName);
Task<(bool Success, string? Error, bool PasswordRequired)> EnsureChannelMembershipAsync(Guid userId, string channelName, string? password = null);
}
public record ChannelListItem(string Name, string? Topic, int OnlineCount);
public record ChannelListItem(string Name, string? Topic, int OnlineCount, bool IsPublic = true, bool IsProtected = false);