Fix IRC listener relay of bodies and modes, and JOIN names (closes #127)
check / check (push) Canceled after 0s

The IRC listener relayed only the first line of a PRIVMSG or NOTICE
body; it now sends one line per body line. A relayed MODE change now
carries its key, limit or mask, each value its own parameter, also in
the echo to the user who made it. CR, LF and NUL are removed from each
parameter and from each whole line sent to an IRC listener connection,
so no stored value can start a line of its own. The channel name check
moved into service.JoinChannel, so the IRC listener's JOIN refuses the
same names with 403.

Model: opus-5-5
This commit is contained in:
2026-10-20 11:24:55 +00:00
committed by sneak
parent 4ab320ab2d
commit 65ae37d97a
10 changed files with 345 additions and 46 deletions
+15 -14
View File
@@ -2667,7 +2667,9 @@ IRC_LISTEN_ADDR: ""
- **CAP negotiation**: `CAP LS` gets an empty capability list and `CAP END` is
ignored, for compatibility with modern clients.
- **Channel prefixes**: Channels must start with `#`. `JOIN` prepends it if
omitted; other commands use the name as given.
omitted; other commands use the name as given. As over the HTTP API, `JOIN`
answers a name that is not `#` followed by 1–63 letters, digits, `_` or `-`
with ERR_NOSUCHCHANNEL (403).
- **First joiner**: The first user to join a channel is automatically granted
operator status (`@`).
- **Channel modes**: `+i` (invite-only), `+m` (moderated), `+n` (no external),
@@ -2689,21 +2691,20 @@ IRC_LISTEN_ADDR: ""
Messages sent by IRC clients appear in channels visible to HTTP/JSON API clients
and vice versa. The IRC listener and HTTP API share the same database, broker,
and session infrastructure, so a user connected via IRC and a user connected via
the HTTP API can talk in the same channels, with these gaps today:
the HTTP API can talk in the same channels.
- An IRC listener user receives only the first line of a multi-line `body`.
- A `+k`, `+l` or `+b` change made over the HTTP API reaches IRC listener
members without its key, limit or mask.
- The IRC listener's `JOIN` accepts any channel name, while over the HTTP API a
name that is not `#` followed by 1–63 letters, digits, `_` or `-` gets
ERR_NOSUCHCHANNEL (403), so HTTP API users cannot join such a channel.
- The IRC listener does not pass on a `PRIVMSG`, `NOTICE`, `JOIN`, `PART`,
`NICK` or `QUIT` whose sender's nick matches the user's own nick ignoring
case, so an IRC listener user `alice` never sees these from `Alice`, although
nicks are case-sensitive.
Each line of a multi-line `body` reaches an IRC listener user as its own
`PRIVMSG` or `NOTICE` line. A CR, LF or NUL inside a line is removed before it
is sent, so it cannot start a line of its own. A mode change made over the HTTP
API reaches IRC listener members as an IRC `MODE` line with its value as a
separate parameter, e.g. `MODE #general +k secretpass` or
`MODE #general +o bob`.
https://git.eeqj.de/sneak/neoirc/issues/127 tracks the first three and
https://git.eeqj.de/sneak/neoirc/issues/128 the last.
One gap remains: the IRC listener does not pass on a `PRIVMSG`, `NOTICE`,
`JOIN`, `PART`, `NICK` or `QUIT` whose sender's nick matches the user's own nick
ignoring case, so an IRC listener user `alice` never sees these from `Alice`,
although nicks are case-sensitive. https://git.eeqj.de/sneak/neoirc/issues/128
tracks it.
### Docker Usage