feat: exclude notes by suspended user from FTT timeline endpoint

This commit is contained in:
anatawa12 2025-04-07 21:46:17 +09:00
parent b0c0d1b294
commit 1ec8d02e13
No known key found for this signature in database
GPG Key ID: 9CA909848B8E4EA6
3 changed files with 19 additions and 0 deletions

View File

@ -33,6 +33,7 @@ type TimelineOptions = {
excludeNoFiles?: boolean; excludeNoFiles?: boolean;
excludeReplies?: boolean; excludeReplies?: boolean;
excludePureRenotes: boolean; excludePureRenotes: boolean;
ignoreAuthorFromUserSuspension?: boolean;
dbFallback: (untilId: string | null, sinceId: string | null, limit: number) => Promise<MiNote[]>, dbFallback: (untilId: string | null, sinceId: string | null, limit: number) => Promise<MiNote[]>,
}; };
@ -119,6 +120,19 @@ export class FanoutTimelineEndpointService {
}; };
} }
{
const parentFilter = filter;
filter = (note) => {
if (!ps.ignoreAuthorFromUserSuspension) {
if (note.user!.isSuspended) return false;
}
if (note.userId !== note.renoteUserId && note.renoteUser?.isSuspended) return false;
if (note.userId !== note.replyUserId && note.replyUser?.isSuspended) return false;
return parentFilter(note);
};
}
const redisTimeline: MiNote[] = []; const redisTimeline: MiNote[] = [];
let readFromRedis = 0; let readFromRedis = 0;
let lastSuccessfulRate = 1; // rateをキャッシュする let lastSuccessfulRate = 1; // rateをキャッシュする

View File

@ -229,6 +229,10 @@ export class MiNote {
comment: '[Denormalized]', comment: '[Denormalized]',
}) })
public renoteUserHost: string | null; public renoteUserHost: string | null;
// some query includes the following fields
public renoteUser?: MiUser | null;
public replyUser?: MiUser | null;
//#endregion //#endregion
constructor(data: Partial<MiNote>) { constructor(data: Partial<MiNote>) {

View File

@ -129,6 +129,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
redisTimelines, redisTimelines,
useDbFallback: true, useDbFallback: true,
ignoreAuthorFromMute: true, ignoreAuthorFromMute: true,
ignoreAuthorFromUserSuspension: true,
excludeReplies: ps.withChannelNotes && !ps.withReplies, // userTimelineWithChannel may include replies excludeReplies: ps.withChannelNotes && !ps.withReplies, // userTimelineWithChannel may include replies
excludeNoFiles: ps.withChannelNotes && ps.withFiles, // userTimelineWithChannel may include notes without files excludeNoFiles: ps.withChannelNotes && ps.withFiles, // userTimelineWithChannel may include notes without files
excludePureRenotes: !ps.withRenotes, excludePureRenotes: !ps.withRenotes,