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
@@ -16,6 +16,7 @@ public class ChannelListSource : IListDataSource
{
private readonly List<string> _channelNames = [];
private readonly Dictionary<string, int> _unreadCounts = [];
private readonly HashSet<string> _protectedChannels = [];
private string _activeChannel = string.Empty;
public event NotifyCollectionChangedEventHandler? CollectionChanged;
@@ -28,13 +29,17 @@ public class ChannelListSource : IListDataSource
private static readonly Attribute NormalAttr = new(Color.DarkGray, Color.None);
private static readonly Attribute BadgeAttr = new(Color.BrightYellow, Color.None);
public void Update(List<string> channels, Dictionary<string, int> unread, string activeChannel)
public void Update(List<string> channels, Dictionary<string, int> unread, string activeChannel,
IReadOnlySet<string>? protectedChannels = null)
{
_channelNames.Clear();
_channelNames.AddRange(channels);
_unreadCounts.Clear();
foreach (var kv in unread)
_unreadCounts[kv.Key] = kv.Value;
_protectedChannels.Clear();
if (protectedChannels is not null)
_protectedChannels.UnionWith(protectedChannels);
_activeChannel = activeChannel;
MaxItemLength = channels.Count > 0 ? channels.Max(c => c.Length + 6) : 0;
if (!SuspendCollectionChangedEvent)
@@ -57,7 +62,8 @@ public class ChannelListSource : IListDataSource
var normalAttr = listView.GetAttributeForRole(VisualRole.Normal);
var focusAttr = listView.GetAttributeForRole(VisualRole.Focus);
var prefix = isActive ? "> " : " ";
var channelText = $"#{name}";
// Trailing * marks password-protected (+k) channels
var channelText = _protectedChannels.Contains(name) ? $"#{name}*" : $"#{name}";
var badge = hasUnread ? $" ({unread})" : "";
// Resolve Transparent backgrounds to the view's actual background