Make an IRC listener connection follow its session's nick (closes #184)
check / check (push) Canceled after 0s

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, the connection first takes
the nick its session holds in the database. 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, as the relay already did.

Model: opus-5-5
This commit is contained in:
2026-10-21 14:04:22 +00:00
parent 129d87d578
commit d90962c960
5 changed files with 176 additions and 45 deletions
+11 -11
View File
@@ -81,7 +81,7 @@ func (c *Conn) handleNick(
}
oldMask := c.hostmask()
oldNick := c.nick
oldNick := c.currentNick()
err := c.svc.ChangeNick(
ctx, c.sessionID, c.clientID, oldNick, newNick,
@@ -129,7 +129,7 @@ func (c *Conn) handlePrivmsg(
if strings.HasPrefix(target, "#") {
_, err := c.svc.SendChannelMessage(
ctx, c.sessionID, c.clientID, c.nick,
ctx, c.sessionID, c.clientID, c.currentNick(),
msg.Command, target, body, nil,
)
if err != nil {
@@ -137,7 +137,7 @@ func (c *Conn) handlePrivmsg(
}
} else {
result, err := c.svc.SendDirectMessage(
ctx, c.sessionID, c.clientID, c.nick,
ctx, c.sessionID, c.clientID, c.currentNick(),
msg.Command, target, body, nil,
)
if err != nil {
@@ -199,7 +199,7 @@ func (c *Conn) joinChannel(
channel, key string,
) {
result, err := c.svc.JoinChannel(
ctx, c.sessionID, c.clientID, c.nick, channel, key,
ctx, c.sessionID, c.clientID, c.currentNick(), channel, key,
)
if err != nil {
c.sendIRCError(err)
@@ -337,7 +337,7 @@ func (c *Conn) partChannel(
channel, reason string,
) {
err := c.svc.PartChannel(
ctx, c.sessionID, c.clientID, c.nick, channel, reason,
ctx, c.sessionID, c.clientID, c.currentNick(), channel, reason,
)
if err != nil {
c.sendIRCError(err)
@@ -401,7 +401,7 @@ func (c *Conn) handleTopic(
newTopic := msg.Params[1]
err := c.svc.SetTopic(
ctx, c.sessionID, c.clientID, c.nick, channel, newTopic,
ctx, c.sessionID, c.clientID, c.currentNick(), channel, newTopic,
)
if err != nil {
c.sendIRCError(err)
@@ -708,7 +708,7 @@ func (c *Conn) applyChannelModes(
c.send(FormatMessage(c.hostmask(), "MODE", params...))
c.svc.BroadcastMode(
ctx, c.clientID, c.nick, channel, chID, modeReply,
ctx, c.clientID, c.currentNick(), channel, chID, modeReply,
)
}
}
@@ -1185,7 +1185,7 @@ func (c *Conn) handleKick(
}
err := c.svc.KickUser(
ctx, c.sessionID, c.clientID, c.nick,
ctx, c.sessionID, c.clientID, c.currentNick(),
channel, targetNick, reason,
)
if err != nil {
@@ -1225,7 +1225,7 @@ func (c *Conn) handlePassPostReg(
return
}
c.sendFromServer("NOTICE", c.nick,
c.sendFromServer("NOTICE", c.currentNick(),
"Password set. You can reconnect using "+
"PASS <password> with your nick.",
)
@@ -1249,7 +1249,7 @@ func (c *Conn) handleInvite(
channel := msg.Params[1]
targetID, err := c.svc.InviteUser(
ctx, c.sessionID, c.nick, targetNick, channel,
ctx, c.sessionID, c.currentNick(), targetNick, channel,
)
if err != nil {
c.sendIRCError(err)
@@ -1266,7 +1266,7 @@ func (c *Conn) handleInvite(
body, _ := json.Marshal([]string{channel}) //nolint:errchkjson
_, _, _ = c.svc.FanOut( //nolint:dogsled // fire-and-forget broadcast
ctx, "INVITE", c.nick, targetNick, targetID, 0,
ctx, "INVITE", c.currentNick(), targetNick, targetID, 0,
nil, body, nil, []int64{targetID}, 0,
)
}