Tier 2: Ban system, invite-only, secret, channel key, user limit (+b/+i/+s/+k/+l) #86

Closed
opened 2026-03-22 11:04:58 +01:00 by clawbot · 1 comment
Collaborator

Overview

Implement the second tier of IRC channel features. These are important for real-world IRC operation but less immediately visible than Tier 1.

Blocked by: #85 (Tier 1 must be merged first)

Requirements

1. Ban System (+b)

Schema:

CREATE TABLE channel_bans (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    channel_id INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    mask TEXT NOT NULL,
    set_by TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(channel_id, mask)
);

Commands:

  • MODE #channel +b nick!user@host — add ban (only +o)
  • MODE #channel -b nick!user@host — remove ban (only +o)
  • MODE #channel +b (no args) — list bans (RPL_BANLIST / RPL_ENDOFBANLIST)
  • Ban matching on JOIN: prevent banned users from joining
  • Ban matching on PRIVMSG: prevent banned users from sending
  • Wildcard matching: *!*@*.example.com, badnick!*@*, etc.

2. Invite-Only (+i)

  • Add is_invite_only INTEGER NOT NULL DEFAULT 0 to channels table
  • MODE #channel +i — only +o can set
  • When +i is active, users can only JOIN if invited
  • INVITE command: INVITE nick #channel (only +o can invite)
  • Invited users stored in memory (or DB table) with channel association
  • Invite cleared after JOIN
  • ERR_INVITEONLYCHAN (473) for uninvited JOIN attempts

3. Secret (+s)

  • Add is_secret INTEGER NOT NULL DEFAULT 0 to channels table
  • MODE #channel +s — only +o can set
  • Secret channels hidden from LIST response (for non-members)
  • Secret channels hidden from WHOIS channel list (for non-members)

4. Channel Key (+k)

  • Add channel_key TEXT NOT NULL DEFAULT '' to channels table
  • MODE #channel +k password — set key (only +o)
  • MODE #channel -k * — remove key (only +o)
  • JOIN #channel password — key required to join
  • ERR_BADCHANNELKEY (475) for wrong/missing key

5. User Limit (+l)

  • Add user_limit INTEGER NOT NULL DEFAULT 0 to channels table (0 = no limit)
  • MODE #channel +l 50 — set limit (only +o)
  • MODE #channel -l — remove limit (only +o)
  • ERR_CHANNELISFULL (471) when limit reached

Testing

  • Ban add/remove/list/match with wildcards
  • Ban enforcement on JOIN and PRIVMSG
  • Invite-only JOIN rejection and INVITE acceptance
  • Secret channel filtering from LIST and WHOIS
  • Channel key validation on JOIN
  • User limit enforcement

Scope

Do NOT start this until #85 (Tier 1) is merged. Tier 3 comes after this.

## Overview Implement the second tier of IRC channel features. These are important for real-world IRC operation but less immediately visible than Tier 1. **Blocked by:** [#85](https://git.eeqj.de/sneak/chat/issues/85) (Tier 1 must be merged first) ## Requirements ### 1. Ban System (+b) **Schema:** ```sql CREATE TABLE channel_bans ( id INTEGER PRIMARY KEY AUTOINCREMENT, channel_id INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE, mask TEXT NOT NULL, set_by TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(channel_id, mask) ); ``` **Commands:** - `MODE #channel +b nick!user@host` — add ban (only +o) - `MODE #channel -b nick!user@host` — remove ban (only +o) - `MODE #channel +b` (no args) — list bans (RPL_BANLIST / RPL_ENDOFBANLIST) - Ban matching on JOIN: prevent banned users from joining - Ban matching on PRIVMSG: prevent banned users from sending - Wildcard matching: `*!*@*.example.com`, `badnick!*@*`, etc. ### 2. Invite-Only (+i) - Add `is_invite_only INTEGER NOT NULL DEFAULT 0` to `channels` table - `MODE #channel +i` — only +o can set - When +i is active, users can only JOIN if invited - INVITE command: `INVITE nick #channel` (only +o can invite) - Invited users stored in memory (or DB table) with channel association - Invite cleared after JOIN - `ERR_INVITEONLYCHAN` (473) for uninvited JOIN attempts ### 3. Secret (+s) - Add `is_secret INTEGER NOT NULL DEFAULT 0` to `channels` table - `MODE #channel +s` — only +o can set - Secret channels hidden from LIST response (for non-members) - Secret channels hidden from WHOIS channel list (for non-members) ### 4. Channel Key (+k) - Add `channel_key TEXT NOT NULL DEFAULT ''` to `channels` table - `MODE #channel +k password` — set key (only +o) - `MODE #channel -k *` — remove key (only +o) - `JOIN #channel password` — key required to join - `ERR_BADCHANNELKEY` (475) for wrong/missing key ### 5. User Limit (+l) - Add `user_limit INTEGER NOT NULL DEFAULT 0` to `channels` table (0 = no limit) - `MODE #channel +l 50` — set limit (only +o) - `MODE #channel -l` — remove limit (only +o) - `ERR_CHANNELISFULL` (471) when limit reached ## Testing - Ban add/remove/list/match with wildcards - Ban enforcement on JOIN and PRIVMSG - Invite-only JOIN rejection and INVITE acceptance - Secret channel filtering from LIST and WHOIS - Channel key validation on JOIN - User limit enforcement ## Scope Do NOT start this until [#85](https://git.eeqj.de/sneak/chat/issues/85) (Tier 1) is merged. [Tier 3](https://git.eeqj.de/sneak/chat/issues/87) comes after this.
clawbot added this to the 1.0 milestone 2026-03-22 11:04:58 +01:00
clawbot self-assigned this 2026-03-22 11:04:58 +01:00
Owner

ok, you can proceed on this @clawbot - tier 1 is done and merged

ok, you can proceed on this @clawbot - tier 1 is done and merged
sneak closed this issue 2026-03-25 22:38:46 +01:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/chat#86