From 981d708bcb6aecaf4988c90feea1889ec9fa9128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=AC=B4=EB=9D=BC=EC=BF=A0=EB=AA=A8?= Date: Mon, 13 May 2024 22:56:54 +0900 Subject: [PATCH] fix(SearchService): private note is showing on search result --- packages/backend/src/core/SearchService.ts | 40 +++++++++++++++------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index ad69307d8..58d7f2300 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -16,6 +16,7 @@ import { isUserRelated } from '@/misc/is-user-related.js'; import { CacheService } from '@/core/CacheService.js'; import { QueryService } from '@/core/QueryService.js'; import { IdService } from '@/core/IdService.js'; +import { UserEntityService } from './entities/UserEntityService.js'; import type { Index, MeiliSearch } from 'meilisearch'; type K = string; @@ -76,6 +77,7 @@ export class SearchService { @Inject(DI.notesRepository) private notesRepository: NotesRepository, + private userEntityService: UserEntityService, private cacheService: CacheService, private queryService: QueryService, private idService: IdService, @@ -149,13 +151,35 @@ export class SearchService { @bindThis public async unindexNote(note: MiNote): Promise { - if (!['home', 'public'].includes(note.visibility)) return; + // if (!['home', 'public'].includes(note.visibility)) return; if (this.meilisearch) { this.meilisearchNoteIndex!.deleteDocument(note.id); } } + @bindThis + private async filter(me: MiUser | null, note: MiNote): Promise { + const [ + userIdsWhoMeMuting, + userIdsWhoBlockingMe, + ] = me ? await Promise.all([ + this.cacheService.userMutingsCache.fetch(me.id), + this.cacheService.userBlockedCache.fetch(me.id), + ]) : [new Set(), new Set()]; + if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; + if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; + if (['followers', 'specified'].includes(note.visibility)) { + if (!me) return false; + if (note.visibility === 'followers') { + const relationship = await this.userEntityService.getRelation(me.id, note.userId); + if (relationship.isFollowing) return true; + } + if (!note.visibleUserIds.includes(me.id) && !note.mentions.includes(me.id)) return false; + } + return true; + } + @bindThis public async searchNote(q: string, me: MiUser | null, opts: { userId?: MiNote['userId'] | null; @@ -190,20 +214,10 @@ export class SearchService { limit: pagination.limit, }); if (res.hits.length === 0) return []; - 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.notesRepository.findBy({ id: In(res.hits.map(x => x.id)), - })).filter(note => { - if (me && isUserRelated(note, userIdsWhoBlockingMe)) return false; - if (me && isUserRelated(note, userIdsWhoMeMuting)) return false; - return true; - }); + })).filter(async note => (await this.filter(me, note))); return notes.sort((a, b) => a.id > b.id ? -1 : 1); } else { const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), pagination.sinceId, pagination.untilId);