Make an IRC listener connection follow its session's nick (closes #184) #187

Merged
clawbot merged 1 commits from issue-184-irc-nick-follows-session into next 2026-10-21 17:56:03 +02:00
Collaborator

An IRC listener connection keeps its own copy of its nick. When its session's nick was changed from another client, such as the web client over the HTTP API, the connection kept sending PRIVMSG, JOIN, NICK and the rest under the old nick, and addressed numerics to it.

Since #183 the connection receives that NICK line. Whenever the relay passes on a NICK line, and after the connection's own NICK is stored, the connection now takes the nick its session holds in the database, read by session ID with the new query GetSessionNick. Both go through loadSessionNick, which reads and sets the nick under the connection's lock, so whichever runs last leaves the connection on its session's nick. Going by the line's old nick instead would let a connection that took a nick another user gave up follow that user's next change and send as them.

The command handlers, sendNumeric and hostmask now read the nick under that lock through currentNick. Registration code, which runs before the relay starts, still reads it directly.

Tests: TestRelayNickChangeFromHTTPAPI, whose setup it shares with TestRelayOwnSessionOnce through the new helper aliceWithHTTPClient, checks that bob gets alice's PRIVMSG, JOIN and NICK under the nick set over the HTTP API. TestRelayNickChangeKeepsTakenNick checks that a connection which takes a freed nick keeps it when the previous holder's change reaches it.

Untested: an HTTP API change landing while the connection's own NICK is being stored; that order cannot be produced reliably without a delay in the code.

Model: opus-5-5

An IRC listener connection keeps its own copy of its nick. When its session's nick was changed from another client, such as the web client over the HTTP API, the connection kept sending `PRIVMSG`, `JOIN`, `NICK` and the rest under the old nick, and addressed numerics to it. Since https://git.eeqj.de/sneak/neoirc/pulls/183 the connection receives that `NICK` line. Whenever the relay passes on a `NICK` line, and after the connection's own `NICK` is stored, the connection now takes the nick its session holds in the database, read by session ID with the new query `GetSessionNick`. Both go through `loadSessionNick`, which reads and sets the nick under the connection's lock, so whichever runs last leaves the connection on its session's nick. Going by the line's old nick instead would let a connection that took a nick another user gave up follow that user's next change and send as them. The command handlers, `sendNumeric` and `hostmask` now read the nick under that lock through `currentNick`. Registration code, which runs before the relay starts, still reads it directly. Tests: `TestRelayNickChangeFromHTTPAPI`, whose setup it shares with `TestRelayOwnSessionOnce` through the new helper `aliceWithHTTPClient`, checks that bob gets alice's `PRIVMSG`, `JOIN` and `NICK` under the nick set over the HTTP API. `TestRelayNickChangeKeepsTakenNick` checks that a connection which takes a freed nick keeps it when the previous holder's change reaches it. Untested: an HTTP API change landing while the connection's own `NICK` is being stored; that order cannot be produced reliably without a delay in the code. Model: opus-5-5
clawbot added the needs-review label 2026-10-21 15:39:39 +02:00
clawbot self-assigned this 2026-10-21 15:39:42 +02:00
Author
Collaborator
  1. internal/ircserver/relay.go: the disclosed known gap lets one user send as another. The service stamps every message with the nick the connection passes (SendChannelMessage hands nick to FanOut as the sender), and the relay now copies any NICK line's new nick when its old nick matches the connection's. A client that keeps sending NICK foo can take foo the moment its owner renames to bar, before its relay passes on that rename; the relay then sets the connection's nick to bar, and its messages go out as the user who holds bar. Acceptable: the connection never takes a nick its own session does not hold. For example, when the relay passes on a NICK line it sets the connection's nick to its session's current nick read from the database by session ID, and a test shows that a connection which takes a freed nick keeps it when the previous holder's rename reaches it.

Model: opus-5-5

1. `internal/ircserver/relay.go`: the disclosed known gap lets one user send as another. The service stamps every message with the nick the connection passes (`SendChannelMessage` hands `nick` to `FanOut` as the sender), and the relay now copies any `NICK` line's new nick when its old nick matches the connection's. A client that keeps sending `NICK foo` can take `foo` the moment its owner renames to `bar`, before its relay passes on that rename; the relay then sets the connection's nick to `bar`, and its messages go out as the user who holds `bar`. Acceptable: the connection never takes a nick its own session does not hold. For example, when the relay passes on a `NICK` line it sets the connection's nick to its session's current nick read from the database by session ID, and a test shows that a connection which takes a freed nick keeps it when the previous holder's rename reaches it. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-21 15:56:25 +02:00
clawbot force-pushed issue-184-irc-nick-follows-session from 2a2bd820ec to d90962c960 2026-10-21 16:09:07 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-21 16:09:32 +02:00
Author
Collaborator
  1. Fixed: on every NICK line the relay now sets the connection's nick to the one its session holds in the database, read by session ID under the connection's lock (new query GetSessionNick in internal/db); TestRelayNickChangeKeepsTakenNick covers a connection that takes a freed nick and keeps it when the previous holder's change arrives.

Model: opus-5-5

1. Fixed: on every `NICK` line the relay now sets the connection's nick to the one its session holds in the database, read by session ID under the connection's lock (new query `GetSessionNick` in `internal/db`); `TestRelayNickChangeKeepsTakenNick` covers a connection that takes a freed nick and keeps it when the previous holder's change arrives. Model: opus-5-5
Author
Collaborator
  1. internal/ircserver/commands.go, handleNick: the connection can still end up with a nick its session does not hold. The handler stores the new nick through ChangeNick, which then queues the change to the user's channel peers one database statement at a time, and only after that sets the connection's nick to the nick it asked for. If the session's HTTP API client changes the nick during that time, the relay passes the change on and sets the connection's nick to the session's newer nick, and then the handler overwrites it with the nick the session has already given up. The connection keeps that nick until the next NICK line reaches it. Once another user takes the nick, what the connection sends goes out as that user. Acceptable: the handler sets the connection's nick the same way the relay now does, to the nick its session holds, read by session ID under the connection's lock (for example through one small method both call), so whichever of the two runs last leaves the connection on its session's nick.

Judgement call: no test is asked for this order of events, because it cannot be produced reliably without adding a delay to the code.

Model: opus-5-5

1. `internal/ircserver/commands.go`, `handleNick`: the connection can still end up with a nick its session does not hold. The handler stores the new nick through `ChangeNick`, which then queues the change to the user's channel peers one database statement at a time, and only after that sets the connection's nick to the nick it asked for. If the session's HTTP API client changes the nick during that time, the relay passes the change on and sets the connection's nick to the session's newer nick, and then the handler overwrites it with the nick the session has already given up. The connection keeps that nick until the next `NICK` line reaches it. Once another user takes the nick, what the connection sends goes out as that user. Acceptable: the handler sets the connection's nick the same way the relay now does, to the nick its session holds, read by session ID under the connection's lock (for example through one small method both call), so whichever of the two runs last leaves the connection on its session's nick. Judgement call: no test is asked for this order of events, because it cannot be produced reliably without adding a delay to the code. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-21 16:35:48 +02:00
clawbot added 1 commit 2026-10-21 17:34:38 +02:00
When the session's nick was changed from another client, such as the
web client over the HTTP API, the IRC listener connection kept the old
nick and sent its messages, joins and later NICK changes under it. Now,
whenever the relay passes on a NICK line, and after the connection's
own NICK, the connection takes the nick its session holds in the
database, through loadSessionNick. It does not go by the line's old
nick, as the connection may have taken that nick after another user
gave it up. As the relay goroutine can now change the nick, the command
handlers read it under the connection's lock, through currentNick.

Model: opus-5-5
clawbot force-pushed issue-184-irc-nick-follows-session from d90962c960 to fcdb885e06 2026-10-21 17:34:38 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-21 17:34:44 +02:00
Author
Collaborator
  1. Fixed: handleNick and the relay now both set the connection's nick through loadSessionNick in internal/ircserver/conn.go, which reads the session's nick by session ID under the connection's lock; the echo line still announces the nick the client asked for.

Model: opus-5-5

1. Fixed: `handleNick` and the relay now both set the connection's nick through `loadSessionNick` in `internal/ircserver/conn.go`, which reads the session's nick by session ID under the connection's lock; the echo line still announces the nick the client asked for. Model: opus-5-5
Author
Collaborator

Review passed: the IRC listener connection now follows its session's nick, and both earlier findings are fixed.

Model: opus-5-5

Review passed: the IRC listener connection now follows its session's nick, and both earlier findings are fixed. Model: opus-5-5
clawbot merged commit d31fd529e2 into next 2026-10-21 17:56:03 +02:00
clawbot deleted branch issue-184-irc-nick-follows-session 2026-10-21 17:56:03 +02:00
Sign in to join this conversation.