diff --git a/internal/rpc/forum_topics_preview_rpc_test.go b/internal/rpc/forum_topics_preview_rpc_test.go index 3dd6b8ba..8bceefba 100644 --- a/internal/rpc/forum_topics_preview_rpc_test.go +++ b/internal/rpc/forum_topics_preview_rpc_test.go @@ -67,14 +67,10 @@ 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: } } @@ -85,19 +81,6 @@ 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 @@ -127,7 +110,4 @@ 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") - } } diff --git a/internal/store/memory/channel_topics.go b/internal/store/memory/channel_topics.go index 173c4a37..f8f76d41 100644 --- a/internal/store/memory/channel_topics.go +++ b/internal/store/memory/channel_topics.go @@ -501,9 +501,7 @@ func (s *ChannelStore) GetForumTopicsByID(_ context.Context, viewerUserID, chann func (s *ChannelStore) ListChannelReplies(_ context.Context, viewerUserID int64, filter domain.ChannelRepliesFilter) (domain.ChannelHistory, error) { s.mu.RLock() defer s.mu.RUnlock() - // Viewer scope (not strict membership): non-members can preview topic - // replies in a public channel/supergroup, matching ListChannelHistory. - source, member, _, err := s.channelForViewerLocked(viewerUserID, filter.ChannelID) + source, member, err := s.channelAndMemberOrLinkedGuestLocked(viewerUserID, filter.ChannelID) if err != nil { return domain.ChannelHistory{}, err } diff --git a/internal/store/postgres/channel_topics.go b/internal/store/postgres/channel_topics.go index a3b3fc7c..92297ab2 100644 --- a/internal/store/postgres/channel_topics.go +++ b/internal/store/postgres/channel_topics.go @@ -588,9 +588,7 @@ ORDER BY pinned DESC, pinned_order DESC, date DESC, topic_id DESC`, channelID, m } func (s *ChannelStore) ListChannelReplies(ctx context.Context, viewerUserID int64, filter domain.ChannelRepliesFilter) (domain.ChannelHistory, error) { - // Viewer口径(非严格 member):公开频道/超级群的非成员可预览话题回复,与 - // ListChannelHistory 一致。私有频道非成员仍是 ErrChannelPrivate。 - source, member, _, err := s.getChannelForViewer(ctx, s.db, viewerUserID, filter.ChannelID) + source, member, err := s.getChannelForMemberOrLinkedGuest(ctx, s.db, viewerUserID, filter.ChannelID) if err != nil { return domain.ChannelHistory{}, err }