diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b9ae480af..7e8f90ed78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - Fix: ユーザーのプロフィール画面をアドレス入力などで直接表示した際に概要タブの描画に失敗する問題の修正( #15032 ) - Fix: 起動前の疎通チェックが機能しなくなっていた問題を修正 (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/737) +- Fix: ユーザーミュートにおいて、ノート内のメンションが考慮されていなかった問題を修正 + - これにより、第三者から自分に対するノートを意図せず取り逃してしまう可能性があったため、通知欄ではメンションを考慮しないままになっています ## 2024.11.0 diff --git a/packages/backend/src/core/QueryService.ts b/packages/backend/src/core/QueryService.ts index c4feeaf971..5794b15445 100644 --- a/packages/backend/src/core/QueryService.ts +++ b/packages/backend/src/core/QueryService.ts @@ -127,13 +127,18 @@ export class QueryService { } @bindThis - public generateMutedUserQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }, exclude?: { id: MiUser['id'] }): void { + public generateMutedUserQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }, exclude?: { id: MiUser['id'] }, checkMentions = true): void { const mutingQuery = this.mutingsRepository.createQueryBuilder('muting') .select('muting.muteeId') .where('muting.muterId = :muterId', { muterId: me.id }); + const mutingArrayQuery = this.mutingsRepository.createQueryBuilder('muting') + .select('array_agg(muting.muteeId)', 'muting.muteeIdArray') + .where('muting.muterId = :muterId', { muterId: me.id }); + if (exclude) { mutingQuery.andWhere('muting.muteeId != :excludeId', { excludeId: exclude.id }); + mutingArrayQuery.andWhere('muting.muteeId != :excludeId', { excludeId: exclude.id }); } const mutingInstanceQuery = this.userProfilesRepository.createQueryBuilder('user_profile') @@ -172,7 +177,18 @@ export class QueryService { .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.renoteUserHost)`); })); + // 投稿に含まれるメンションの相手をミュートしていない + if (checkMentions) { + q.andWhere(new Brackets(qb => { + qb + .where('note.mentions IS NULL') + .orWhere(`NOT EXISTS (${ mutingQuery.getQuery() })`) + .orWhere(`NOT (note.mentions && (${ mutingArrayQuery.getQuery() }))`); + })); + } + q.setParameters(mutingQuery.getParameters()); + q.setParameters(mutingArrayQuery.getParameters()); q.setParameters(mutingInstanceQuery.getParameters()); } diff --git a/packages/backend/src/misc/is-user-related.ts b/packages/backend/src/misc/is-user-related.ts index 862d6e6a38..87faedd1ca 100644 --- a/packages/backend/src/misc/is-user-related.ts +++ b/packages/backend/src/misc/is-user-related.ts @@ -12,6 +12,10 @@ export function isUserRelated(note: any, userIds: Set, ignoreAuthor = fa return true; } + if (note.mentions != null && note.mentions.filter((userId: string) => userId !== note.userId && userIds.has(userId)).length > 0) { + return true; + } + if (note.reply != null && note.reply.userId !== note.userId && userIds.has(note.reply.userId)) { return true; } diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts index 5558dd3a8b..8e138bc880 100644 --- a/packages/backend/src/server/api/endpoints/notes/mentions.ts +++ b/packages/backend/src/server/api/endpoints/notes/mentions.ts @@ -74,7 +74,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateMutedUserQuery(query, me, undefined, false); // 通知系ではメンションを確認しないようにする this.queryService.generateMutedNoteThreadQuery(query, me); this.queryService.generateBlockedUserQuery(query, me);