diff --git a/packages/backend/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts index b94a019da4..f603529fe7 100644 --- a/packages/backend/src/server/api/endpoints/notes/conversation.ts +++ b/packages/backend/src/server/api/endpoints/notes/conversation.ts @@ -10,6 +10,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { CacheService } from '@/core/CacheService.js'; +import { isUserRelated } from '@/misc/is-user-related.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -54,6 +56,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private getterService: GetterService, + private cacheService: CacheService, ) { super(meta, paramDef, async (ps, me) => { const note = await this.getterService.getNote(ps.noteId).catch(err => { @@ -61,13 +64,21 @@ export default class extends Endpoint { // eslint- throw err; }); + const [ + userIdsWhoMeMuting, + userIdsWhoBlockingMe, + ] = me ? await Promise.all([ + this.cacheService.userMutingsCache.fetch(me.id), + this.cacheService.userBlockedCache.fetch(me.id), + ]) : [new Set(), new Set()]; + const conversation: MiNote[] = []; let i = 0; const get = async (id: any) => { i++; const p = await this.notesRepository.findOneBy({ id }); - if (p == null) return; + if (p == null || (me && (isUserRelated(note, userIdsWhoBlockingMe) || isUserRelated(note, userIdsWhoMeMuting)))) return; if (i > ps.offset!) { conversation.push(p); diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts index bc6cbe242f..3901aa418a 100644 --- a/packages/backend/src/server/api/endpoints/notes/featured.ts +++ b/packages/backend/src/server/api/endpoints/notes/featured.ts @@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; import { FeaturedService } from '@/core/FeaturedService.js'; +import { QueryService } from '@/core/QueryService.js'; export const meta = { tags: ['notes'], @@ -49,6 +50,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private featuredService: FeaturedService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { let noteIds: string[]; @@ -83,11 +85,13 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); + this.queryService.generateVisibilityQuery(query, me); + if (me) this.queryService.generateMutedUserQuery(query, me); + if (me) this.queryService.generateBlockedUserQuery(query, me); + const notes = await query.getMany(); notes.sort((a, b) => a.id > b.id ? -1 : 1); - // TODO: ミュート等考慮 - return await this.noteEntityService.packMany(notes, me); }); } diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index 4425d4593c..abf6df8253 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -8,6 +8,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { SearchService } from '@/core/SearchService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { RoleService } from '@/core/RoleService.js'; +import { CacheService } from '@/core/CacheService.js'; +import { isUserRelated } from '@/misc/is-user-related.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -60,6 +62,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private searchService: SearchService, private roleService: RoleService, + private cacheService: CacheService, ) { super(meta, paramDef, async (ps, me) => { const policies = await this.roleService.getUserPolicies(me ? me.id : null); @@ -67,7 +70,15 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.unavailable); } - const notes = await this.searchService.searchNote(ps.query, me, { + const [ + userIdsWhoMeMuting, + userIdsWhoBlockingMe, + ] = me ? await Promise.all([ + this.cacheService.userMutingsCache.fetch(me.id), + this.cacheService.userBlockedCache.fetch(me.id), + ]) : [new Set(), new Set()]; + + const notes = (await this.searchService.searchNote(ps.query, me, { userId: ps.userId, channelId: ps.channelId, host: ps.host, @@ -75,7 +86,7 @@ export default class extends Endpoint { // eslint- untilId: ps.untilId, sinceId: ps.sinceId, limit: ps.limit, - }); + })).filter(note => !(me && (isUserRelated(note, userIdsWhoBlockingMe) || isUserRelated(note, userIdsWhoMeMuting)))); return await this.noteEntityService.packMany(notes, me); }); diff --git a/packages/backend/src/server/api/endpoints/users/featured-notes.ts b/packages/backend/src/server/api/endpoints/users/featured-notes.ts index dec0b7a122..c73aad8f10 100644 --- a/packages/backend/src/server/api/endpoints/users/featured-notes.ts +++ b/packages/backend/src/server/api/endpoints/users/featured-notes.ts @@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; import { FeaturedService } from '@/core/FeaturedService.js'; +import { QueryService } from '@/core/QueryService.js'; export const meta = { tags: ['notes'], @@ -46,6 +47,7 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private featuredService: FeaturedService, + private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { let noteIds = await this.featuredService.getPerUserNotesRanking(ps.userId, 50); @@ -69,11 +71,13 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); + this.queryService.generateVisibilityQuery(query, me); + if (me) this.queryService.generateMutedUserQuery(query, me); + if (me) this.queryService.generateBlockedUserQuery(query, me); + const notes = await query.getMany(); notes.sort((a, b) => a.id > b.id ? -1 : 1); - // TODO: ミュート等考慮 - return await this.noteEntityService.packMany(notes, me); }); } diff --git a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts index d6fb65cecb..dd323e84af 100644 --- a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts +++ b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts @@ -11,6 +11,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { CacheService } from '@/core/CacheService.js'; +import { isUserRelated } from '@/misc/is-user-related.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -66,6 +68,7 @@ export default class extends Endpoint { // eslint- private userEntityService: UserEntityService, private getterService: GetterService, + private cacheService: CacheService, ) { super(meta, paramDef, async (ps, me) => { // Lookup user @@ -92,13 +95,20 @@ export default class extends Endpoint { // eslint- return []; } - // TODO ミュートを考慮 - const replyTargetNotes = await this.notesRepository.find({ + const [ + userIdsWhoMeMuting, + userIdsWhoBlockingMe, + ] = me ? await Promise.all([ + this.cacheService.userMutingsCache.fetch(me.id), + this.cacheService.userBlockedCache.fetch(me.id), + ]) : [new Set(), new Set()]; + + const replyTargetNotes = (await this.notesRepository.find({ where: { id: In(recentNotes.map(p => p.replyId)), }, select: ['userId'], - }); + })).filter(note => !(me && (isUserRelated(note, userIdsWhoBlockingMe) || isUserRelated(note, userIdsWhoMeMuting)))); const repliedUsers: any = {}; diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index 7924b3382f..a7ede033f5 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -815,7 +815,7 @@ describe('ユーザー', () => { }); test.each([ { label: '「見つけやすくする」がOFFのユーザーが含まれる', user: (): User => userNotExplorable }, - { label: 'ミュートユーザーが含まれる', user: (): User => userMutedByAlice }, + { label: 'ミュートユーザーが含まれない', user: (): User => userMutedByAlice, excluded: true }, { label: 'ブロックされているユーザーが含まれる', user: (): User => userBlockedByAlice }, { label: 'ブロックしてきているユーザーが含まれない', user: (): User => userBlockingAlice, excluded: true }, { label: '承認制ユーザーが含まれる', user: (): User => userLocking },