From 9dcccbc8e1cafe4c486178977e71bbef23d5e225 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 23 Oct 2023 15:29:42 +0900 Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E8=87=AA=E5=88=86=E3=81=AE?= =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=AD=E3=83=BC=E3=81=97=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=82=8B=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E8=87=AA?= =?UTF-8?q?=E5=88=86=E3=81=AE=E3=83=95=E3=82=A9=E3=83=AD=E3=83=BC=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=81=84=E3=81=AA=E3=81=84=E3=83=A6=E3=83=BC=E3=82=B6?= =?UTF-8?q?=E3=83=BC=E3=81=AE=20visibility:=20followers=20=E3=81=AA?= =?UTF-8?q?=E6=8A=95=E7=A8=BF=E3=81=B8=E3=81=AE=E8=BF=94=E4=BF=A1=E3=81=8C?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=AA=E3=83=BC=E3=83=9F=E3=83=B3=E3=82=B0?= =?UTF-8?q?=E3=81=A7=E6=B5=81=E3=82=8C=E3=81=A6=E3=81=8F=E3=82=8B=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #12117 --- CHANGELOG.md | 1 + .../src/server/api/stream/channels/home-timeline.ts | 12 ++++++++---- .../server/api/stream/channels/hybrid-timeline.ts | 12 ++++++++---- .../src/server/api/stream/channels/user-list.ts | 12 ++++++++---- packages/backend/test/e2e/streaming.ts | 4 ++++ 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 678fa86a1e..be58f83408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - Enhance: RedisへのTLのキャッシュをオフにできるように - Fix: リストTLに自分のフォロワー限定投稿が含まれない問題を修正 - Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正 +- Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正 ## 2023.10.2 diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 46071e82fa..1c882c8d8a 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -59,11 +59,15 @@ class HomeTimelineChannel extends Channel { if (!note.visibleUserIds!.includes(this.user!.id)) return; } - // 関係ない返信は除外 - if (note.reply && !this.following[note.userId]?.withReplies) { + if (note.reply) { const reply = note.reply; - // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 - if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + if (this.following[note.userId]?.withReplies) { + // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く + if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return; + } else { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + } } if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return; diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 2722ebcd50..aa3fc75092 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -73,11 +73,15 @@ class HybridTimelineChannel extends Channel { // Ignore notes from instances the user has muted if (isInstanceMuted(note, new Set(this.userProfile!.mutedInstances))) return; - // 関係ない返信は除外 - if (note.reply && !this.following[note.userId]?.withReplies && !this.withReplies) { + if (note.reply) { const reply = note.reply; - // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 - if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + if ((this.following[note.userId]?.withReplies ?? false) || this.withReplies) { + // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く + if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return; + } else { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + } } if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return; diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index 68927987d6..4b6628df6f 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -90,11 +90,15 @@ class UserListChannel extends Channel { if (!note.visibleUserIds!.includes(this.user!.id)) return; } - // 関係ない返信は除外 - if (note.reply && !this.membershipsMap[note.userId]?.withReplies) { + if (note.reply) { const reply = note.reply; - // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 - if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + if (this.membershipsMap[note.userId]?.withReplies) { + // 自分のフォローしていないユーザーの visibility: followers な投稿への返信は弾く + if (reply.visibility === 'followers' && !Object.hasOwn(this.following, reply.userId)) return; + } else { + // 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合 + if (reply.userId !== this.user!.id && !isMe && reply.userId !== note.userId) return; + } } // 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する diff --git a/packages/backend/test/e2e/streaming.ts b/packages/backend/test/e2e/streaming.ts index f0b51d4356..f9f385e2b2 100644 --- a/packages/backend/test/e2e/streaming.ts +++ b/packages/backend/test/e2e/streaming.ts @@ -159,6 +159,10 @@ describe('Streaming', () => { }); */ + test('フォローしているユーザーのフォローしていないユーザーの visibility: followers な投稿への返信が流れない', async () => { + // TODO + }); + test('フォローしていないユーザーの投稿は流れない', async () => { const fired = await waitFire( kyoko, 'homeTimeline', // kyoko:home