Bind history to the recipient session and channel, not the name (closes #148)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
History was selected by msg_to, so whoever next held a released nick, or created a deleted channel again under its old name, could read the earlier holder's messages. Each message row now records the session a DM or INVITE was sent to (to_session_id) and the channel a channel message was sent to (to_channel_id), and GET /api/v1/history selects by those ids. A session's DM history now also follows it across nick changes. Model: opus-5-5
This commit is contained in:
@@ -1671,6 +1671,101 @@ func TestHistoryUnknownBefore(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestHistoryReusedNick checks that a user who takes a nick
|
||||
// released by QUIT does not get the DMs sent to its previous
|
||||
// holder.
|
||||
func TestHistoryReusedNick(t *testing.T) {
|
||||
const victim = "victimV"
|
||||
|
||||
tserver := newTestServer(t)
|
||||
senderToken := tserver.createSession("dmA")
|
||||
victimToken := tserver.createSession(victim)
|
||||
newcomerToken := tserver.createSession("newcomer")
|
||||
|
||||
tserver.sendCommand(senderToken, map[string]any{
|
||||
commandKey: privmsgCmd,
|
||||
toKey: victim,
|
||||
bodyKey: []string{"for the first victimV only"},
|
||||
})
|
||||
|
||||
_, msgs := tserver.getHistory(victimToken, victim, "", 10)
|
||||
if len(msgs) != 1 {
|
||||
t.Fatalf("expected 1 DM for %s, got %d", victim, len(msgs))
|
||||
}
|
||||
|
||||
tserver.sendCommand(victimToken, map[string]any{
|
||||
commandKey: irc.CmdQuit,
|
||||
})
|
||||
|
||||
_, result := tserver.sendCommand(newcomerToken, map[string]any{
|
||||
commandKey: irc.CmdNick,
|
||||
bodyKey: []string{victim},
|
||||
})
|
||||
if result[nickKey] != victim {
|
||||
t.Fatalf("expected nick %s, got %v", victim, result)
|
||||
}
|
||||
|
||||
status, msgs := tserver.getHistory(newcomerToken, victim, "", 10)
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", status)
|
||||
}
|
||||
|
||||
if len(msgs) != 0 {
|
||||
t.Fatalf("expected no history, got %v", msgs)
|
||||
}
|
||||
}
|
||||
|
||||
// TestHistoryRecreatedChannel checks that a channel created
|
||||
// again under the name of a deleted one starts with no
|
||||
// history, even when the old one had a key.
|
||||
func TestHistoryRecreatedChannel(t *testing.T) {
|
||||
const channel = "#priv"
|
||||
|
||||
tserver := newTestServer(t)
|
||||
ownerToken := tserver.createSession("roomR")
|
||||
strangerToken := tserver.createSession("stranger")
|
||||
|
||||
tserver.sendCommand(ownerToken, map[string]any{
|
||||
commandKey: joinCmd, toKey: channel,
|
||||
})
|
||||
tserver.sendCommand(ownerToken, map[string]any{
|
||||
commandKey: irc.CmdMode,
|
||||
toKey: channel,
|
||||
bodyKey: []string{"+k", "topsecret"},
|
||||
})
|
||||
tserver.sendCommand(ownerToken, map[string]any{
|
||||
commandKey: privmsgCmd,
|
||||
toKey: channel,
|
||||
bodyKey: []string{"members only"},
|
||||
})
|
||||
|
||||
_, msgs := tserver.getHistory(ownerToken, channel, "", 10)
|
||||
if len(msgs) != 1 {
|
||||
t.Fatalf("expected 1 message, got %d", len(msgs))
|
||||
}
|
||||
|
||||
// The last member leaving deletes the channel.
|
||||
tserver.sendCommand(ownerToken, map[string]any{
|
||||
commandKey: irc.CmdPart, toKey: channel,
|
||||
})
|
||||
|
||||
_, result := tserver.sendCommand(strangerToken, map[string]any{
|
||||
commandKey: joinCmd, toKey: channel,
|
||||
})
|
||||
if result[statusKey] != joinedStatus {
|
||||
t.Fatalf("expected the join to succeed, got %v", result)
|
||||
}
|
||||
|
||||
status, msgs := tserver.getHistory(strangerToken, channel, "", 10)
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", status)
|
||||
}
|
||||
|
||||
if len(msgs) != 0 {
|
||||
t.Fatalf("expected no history, got %v", msgs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChannelList(t *testing.T) {
|
||||
tserver := newTestServer(t)
|
||||
token := tserver.createSession("lister")
|
||||
|
||||
Reference in New Issue
Block a user