forum: let non-members preview topic replies in a public channel

ListChannelReplies used getChannelForMemberOrLinkedGuest, so messages.getReplies
was member-only. ListChannelHistory (flat history) uses getChannelForViewer and
already allows a public channel's non-members to preview it. The mismatch meant
that on a public forum you could preview the flat history but not the topics -
and after leaving, tdesktop's topic view got CHANNEL_PRIVATE and sat on
"Loading..." forever instead of rendering a preview.

Switch the primary channel lookup in ListChannelReplies (both stores) to the
viewer-scope path. Private channels still return CHANNEL_PRIVATE to non-members;
the broadcast comment-thread lookup is unchanged.
This commit is contained in:
Astra 2026-09-09 14:43:59 +01:00
parent 7d280b6f8a
commit 7083faa786
3 changed files with 26 additions and 2 deletions

View file

@ -67,10 +67,14 @@ func TestGetForumTopicsVisibleToPublicNonMember(t *testing.T) {
t.Fatalf("getForumTopics as non-member: %v", err)
}
titles := map[string]bool{}
testTopicID := 0
for _, tc := range res.Topics {
switch topic := tc.(type) {
case *tg.ForumTopic:
titles[topic.Title] = true
if topic.Title == "Test" {
testTopicID = topic.ID
}
case *tg.ForumTopicDeleted:
}
}
@ -81,6 +85,19 @@ func TestGetForumTopicsVisibleToPublicNonMember(t *testing.T) {
t.Fatalf("non-member did not see the Test topic: %+v", res.Topics)
}
// A non-member can also read the replies inside a topic (preview), the same
// way ListChannelHistory lets them preview a public group's flat history.
if testTopicID == 0 {
t.Fatal("no Test topic id to open")
}
if _, err := r.onMessagesGetReplies(outsiderCtx, &tg.MessagesGetRepliesRequest{
Peer: forumPeer,
MsgID: testTopicID,
Limit: 20,
}); err != nil {
t.Fatalf("getReplies as non-member of a public forum: %v", err)
}
// The forum's own channel must come back with left=true so the client still
// offers a Join button instead of treating the forum as already joined.
var forumChat *tg.Channel
@ -110,4 +127,7 @@ func TestGetForumTopicsVisibleToPublicNonMember(t *testing.T) {
if _, err := r.onMessagesGetForumTopics(outsiderCtx, &tg.MessagesGetForumTopicsRequest{Peer: privPeer, Limit: 100}); err == nil {
t.Fatal("non-member read a private forum's topic list")
}
if _, err := r.onMessagesGetReplies(outsiderCtx, &tg.MessagesGetRepliesRequest{Peer: privPeer, MsgID: 1, Limit: 20}); err == nil {
t.Fatal("non-member read a private forum topic's replies")
}
}