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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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:
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)*!*@*.example.com,badnick!*@*, etc.2. Invite-Only (+i)
is_invite_only INTEGER NOT NULL DEFAULT 0tochannelstableMODE #channel +i— only +o can setINVITE nick #channel(only +o can invite)ERR_INVITEONLYCHAN(473) for uninvited JOIN attempts3. Secret (+s)
is_secret INTEGER NOT NULL DEFAULT 0tochannelstableMODE #channel +s— only +o can set4. Channel Key (+k)
channel_key TEXT NOT NULL DEFAULT ''tochannelstableMODE #channel +k password— set key (only +o)MODE #channel -k *— remove key (only +o)JOIN #channel password— key required to joinERR_BADCHANNELKEY(475) for wrong/missing key5. User Limit (+l)
user_limit INTEGER NOT NULL DEFAULT 0tochannelstable (0 = no limit)MODE #channel +l 50— set limit (only +o)MODE #channel -l— remove limit (only +o)ERR_CHANNELISFULL(471) when limit reachedTesting
Scope
Do NOT start this until #85 (Tier 1) is merged. Tier 3 comes after this.
ok, you can proceed on this @clawbot - tier 1 is done and merged