fix(backend): ブロックした相手から自分のノートが見えないように(/users/featured-notes, /users/notes) (#12511)
* fix: ブロックした相手から自分のノートが見えないように(ユーザー,チャンネル) * Update CHANGELOG.md * /users/featured-notesでもブロックを考慮するように * cacheServiceを使うように * /channels/timeline.tsで必要のないnoteFilterを持たないように * Update CHANGELOG.md * FanoutTimelineEndpointServiceへの対応 - ブロックされている場合は、/users/notesでノートが表示されない - ミュートしている場合は、ノートが表示される
This commit is contained in:
parent
bcf6b7f5ee
commit
e6d01e33e6
3 changed files with 21 additions and 4 deletions
|
@ -62,6 +62,7 @@
|
||||||
- Fix: ユーザのノート一覧にてインスタンスミュートが効かない問題
|
- Fix: ユーザのノート一覧にてインスタンスミュートが効かない問題
|
||||||
- Fix: チャンネルのノート一覧にてインスタンスミュートが効かない問題
|
- Fix: チャンネルのノート一覧にてインスタンスミュートが効かない問題
|
||||||
- Fix: 「みつける」が年越し時に壊れる問題を修正
|
- Fix: 「みつける」が年越し時に壊れる問題を修正
|
||||||
|
- Fix: アカウントをブロックした際に、自身のユーザーのページでノートが相手に表示される問題を修正
|
||||||
|
|
||||||
## 2023.11.1
|
## 2023.11.1
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ type TimelineOptions = {
|
||||||
redisTimelines: FanoutTimelineName[],
|
redisTimelines: FanoutTimelineName[],
|
||||||
noteFilter?: (note: MiNote) => boolean,
|
noteFilter?: (note: MiNote) => boolean,
|
||||||
alwaysIncludeMyNotes?: boolean;
|
alwaysIncludeMyNotes?: boolean;
|
||||||
|
ignoreAuthorFromBlock?: boolean;
|
||||||
ignoreAuthorFromMute?: boolean;
|
ignoreAuthorFromMute?: boolean;
|
||||||
excludeNoFiles?: boolean;
|
excludeNoFiles?: boolean;
|
||||||
excludeReplies?: boolean;
|
excludeReplies?: boolean;
|
||||||
|
@ -113,7 +114,7 @@ export class FanoutTimelineEndpointService {
|
||||||
|
|
||||||
const parentFilter = filter;
|
const parentFilter = filter;
|
||||||
filter = (note) => {
|
filter = (note) => {
|
||||||
if (isUserRelated(note, userIdsWhoBlockingMe, ps.ignoreAuthorFromMute)) return false;
|
if (isUserRelated(note, userIdsWhoBlockingMe, ps.ignoreAuthorFromBlock)) return false;
|
||||||
if (isUserRelated(note, userIdsWhoMeMuting, ps.ignoreAuthorFromMute)) return false;
|
if (isUserRelated(note, userIdsWhoMeMuting, ps.ignoreAuthorFromMute)) return false;
|
||||||
if (isPureRenote(note) && isUserRelated(note, userIdsWhoMeMutingRenotes, ps.ignoreAuthorFromMute)) return false;
|
if (isPureRenote(note) && isUserRelated(note, userIdsWhoMeMutingRenotes, ps.ignoreAuthorFromMute)) return false;
|
||||||
if (isInstanceMuted(note, userMutedInstances)) return false;
|
if (isInstanceMuted(note, userMutedInstances)) return false;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { FeaturedService } from '@/core/FeaturedService.js';
|
import { FeaturedService } from '@/core/FeaturedService.js';
|
||||||
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
|
import { isUserRelated } from '@/misc/is-user-related.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['notes'],
|
tags: ['notes'],
|
||||||
|
@ -46,6 +48,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
|
||||||
private noteEntityService: NoteEntityService,
|
private noteEntityService: NoteEntityService,
|
||||||
private featuredService: FeaturedService,
|
private featuredService: FeaturedService,
|
||||||
|
private cacheService: CacheService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
let noteIds = await this.featuredService.getPerUserNotesRanking(ps.userId, 50);
|
let noteIds = await this.featuredService.getPerUserNotesRanking(ps.userId, 50);
|
||||||
|
@ -60,6 +63,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [
|
||||||
|
userIdsWhoMeMuting,
|
||||||
|
userIdsWhoBlockingMe,
|
||||||
|
] = me ? await Promise.all([
|
||||||
|
this.cacheService.userMutingsCache.fetch(me.id),
|
||||||
|
this.cacheService.userBlockedCache.fetch(me.id),
|
||||||
|
]) : [new Set<string>(), new Set<string>()];
|
||||||
|
|
||||||
const query = this.notesRepository.createQueryBuilder('note')
|
const query = this.notesRepository.createQueryBuilder('note')
|
||||||
.where('note.id IN (:...noteIds)', { noteIds: noteIds })
|
.where('note.id IN (:...noteIds)', { noteIds: noteIds })
|
||||||
.innerJoinAndSelect('note.user', 'user')
|
.innerJoinAndSelect('note.user', 'user')
|
||||||
|
@ -69,10 +80,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
.leftJoinAndSelect('renote.user', 'renoteUser')
|
.leftJoinAndSelect('renote.user', 'renoteUser')
|
||||||
.leftJoinAndSelect('note.channel', 'channel');
|
.leftJoinAndSelect('note.channel', 'channel');
|
||||||
|
|
||||||
const notes = await query.getMany();
|
const notes = (await query.getMany()).filter(note => {
|
||||||
notes.sort((a, b) => a.id > b.id ? -1 : 1);
|
if (me && isUserRelated(note, userIdsWhoBlockingMe, false)) return false;
|
||||||
|
if (me && isUserRelated(note, userIdsWhoMeMuting, true)) return false;
|
||||||
|
|
||||||
// TODO: ミュート等考慮
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
notes.sort((a, b) => a.id > b.id ? -1 : 1);
|
||||||
|
|
||||||
return await this.noteEntityService.packMany(notes, me);
|
return await this.noteEntityService.packMany(notes, me);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue