From 32bbde49a8446922803c9022bcbf3239816444c8 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 29 Nov 2020 22:12:06 -0500 Subject: [PATCH] fix #1409 Record INVITE in DM history for the benefit of offline always-on clients --- irc/channel.go | 21 +++++++++++++++------ irc/client.go | 37 ++++++++++++++++++++++++++++++++++++- irc/handlers.go | 33 ++++++++------------------------- irc/history/history.go | 1 + 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index b231ff46..ae53b558 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1507,24 +1507,33 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf invitee.Invite(chcfname, createdAt) } + details := inviter.Details() + tDetails := invitee.Details() + tnick := invitee.Nick() + message := utils.MakeMessage("") + item := history.Item{ + Type: history.Invite, + Message: message, + Params: [1]string{chname}, + } + for _, member := range channel.Members() { if member == inviter || member == invitee || !channel.ClientIsAtLeast(member, modes.Halfop) { continue } for _, session := range member.Sessions() { if session.capabilities.Has(caps.InviteNotify) { - session.Send(nil, inviter.NickMaskString(), "INVITE", invitee.Nick(), chname) + session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "INVITE", tnick, chname) } } } - cnick := inviter.Nick() - tnick := invitee.Nick() - rb.Add(nil, inviter.server.name, RPL_INVITING, cnick, tnick, chname) - invitee.Send(nil, inviter.NickMaskString(), "INVITE", tnick, chname) + rb.Add(nil, inviter.server.name, RPL_INVITING, details.nick, tnick, chname) + invitee.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "INVITE", tnick, chname) if away, awayMessage := invitee.Away(); away { - rb.Add(nil, inviter.server.name, RPL_AWAY, cnick, tnick, awayMessage) + rb.Add(nil, inviter.server.name, RPL_AWAY, details.nick, tnick, awayMessage) } + inviter.addHistoryItem(invitee, item, &details, &tDetails, channel.server.Config()) } // Uninvite rescinds a channel invitation, if the inviter can do so. diff --git a/irc/client.go b/irc/client.go index 7c214339..8f428f49 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1055,6 +1055,13 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I for _, item := range items { var command string switch item.Type { + case history.Invite: + if hasEventPlayback { + rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "INVITE", item.Params[0]) + } else { + rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), stripMaskFromNick(item.Nick), item.Params[0])) + } + continue case history.Privmsg: command = "PRIVMSG" case history.Notice: @@ -1088,7 +1095,7 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I rb.EndNestedBatch(batchID) if !complete { - rb.Add(nil, "HistServ", "NOTICE", nick, client.t("Some additional message history may have been lost")) + rb.Add(nil, histservService.prefix, "NOTICE", nick, client.t("Some additional message history may have been lost")) } } @@ -1862,6 +1869,34 @@ func (client *Client) historyStatus(config *Config) (status HistoryStatus, targe return } +func (client *Client) addHistoryItem(target *Client, item history.Item, details, tDetails *ClientDetails, config *Config) (err error) { + if !itemIsStorable(&item, config) { + return + } + + item.Nick = details.nickMask + item.AccountName = details.accountName + targetedItem := item + targetedItem.Params[0] = tDetails.nick + + cStatus, _ := client.historyStatus(config) + tStatus, _ := target.historyStatus(config) + // add to ephemeral history + if cStatus == HistoryEphemeral { + targetedItem.CfCorrespondent = tDetails.nickCasefolded + client.history.Add(targetedItem) + } + if tStatus == HistoryEphemeral && client != target { + item.CfCorrespondent = details.nickCasefolded + target.history.Add(item) + } + if cStatus == HistoryPersistent || tStatus == HistoryPersistent { + targetedItem.CfCorrespondent = "" + client.server.historyDB.AddDirectMessage(details.nickCasefolded, details.account, tDetails.nickCasefolded, tDetails.account, targetedItem) + } + return nil +} + func (client *Client) handleRegisterTimeout() { client.Quit(fmt.Sprintf("Registration timeout: %v", RegisterTimeout), nil) client.destroy(nil) diff --git a/irc/handlers.go b/irc/handlers.go index 67ce5c89..57d6829e 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -2138,37 +2138,20 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi } } + if !allowedPlusR { + return + } + config := server.Config() if !config.History.Enabled { return } item := history.Item{ - Type: histType, - Message: message, - Nick: nickMaskString, - AccountName: accountName, - Tags: tags, - } - if !itemIsStorable(&item, config) || !allowedPlusR { - return - } - targetedItem := item - targetedItem.Params[0] = tnick - cStatus, _ := client.historyStatus(config) - tStatus, _ := user.historyStatus(config) - // add to ephemeral history - if cStatus == HistoryEphemeral { - targetedItem.CfCorrespondent = tDetails.nickCasefolded - client.history.Add(targetedItem) - } - if tStatus == HistoryEphemeral && client != user { - item.CfCorrespondent = details.nickCasefolded - user.history.Add(item) - } - if cStatus == HistoryPersistent || tStatus == HistoryPersistent { - targetedItem.CfCorrespondent = "" - server.historyDB.AddDirectMessage(details.nickCasefolded, details.account, tDetails.nickCasefolded, tDetails.account, targetedItem) + Type: histType, + Message: message, + Tags: tags, } + client.addHistoryItem(user, item, &details, &tDetails, config) } } diff --git a/irc/history/history.go b/irc/history/history.go index 9d09c92f..896b9920 100644 --- a/irc/history/history.go +++ b/irc/history/history.go @@ -23,6 +23,7 @@ const ( Tagmsg Nick Topic + Invite ) const (