From ad7a950f44c02128307440b8b663c25ab7e82362 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sun, 13 Aug 2023 01:04:24 -0400 Subject: [PATCH] fix: properly filter posts --- packages/backend/src/db/cql.ts | 2 +- .../server/api/endpoints/notes/children.ts | 63 +++++++++++++++++-- .../api/endpoints/notes/conversation.ts | 10 ++- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/db/cql.ts b/packages/backend/src/db/cql.ts index c807e322d7..102367ee8a 100644 --- a/packages/backend/src/db/cql.ts +++ b/packages/backend/src/db/cql.ts @@ -48,7 +48,7 @@ export const scyllaQueries = { byId: `SELECT * FROM note WHERE "id" = ?`, byUserId: `SELECT * FROM note_by_user_id WHERE "userId" IN ?`, byRenoteId: `SELECT * FROM note_by_renote_id WHERE "renoteId" = ?`, - byReplyId: `SELECT * FROM note_by_reply_id WHERE "replyId" = ?` + byReplyId: `SELECT * FROM note WHERE "replyId" = ?` }, delete: `DELETE FROM note WHERE "createdAtDate" = ? AND "createdAt" = ? AND "userId" = ? AND "userHost" = ? AND "visibility" = ?`, update: { diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts index 1c1a496f41..aacfa0b331 100644 --- a/packages/backend/src/server/api/endpoints/notes/children.ts +++ b/packages/backend/src/server/api/endpoints/notes/children.ts @@ -1,12 +1,27 @@ -import { Notes } from "@/models/index.js"; +import { Notes, UserProfiles } from "@/models/index.js"; import define from "../../define.js"; import { makePaginationQuery } from "../../common/make-pagination-query.js"; import { generateVisibilityQuery } from "../../common/generate-visibility-query.js"; import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js"; import { generateBlockedUserQuery } from "../../common/generate-block-query.js"; -import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js"; +import { + filterBlockedUser, + filterMutedNote, + filterMutedUser, + filterVisibility, + parseScyllaNote, + prepared, + scyllaClient, +} from "@/db/scylla.js"; import { getNote } from "@/server/api/common/getters.js"; import type { Note } from "@/models/entities/note.js"; +import { + InstanceMutingsCache, + LocalFollowingsCache, + UserBlockedCache, + UserMutingsCache, + userWordMuteCache, +} from "@/misc/cache.js"; export const meta = { tags: ["notes"], @@ -42,7 +57,34 @@ export const paramDef = { export default define(meta, paramDef, async (ps, user) => { if (scyllaClient) { - const root = await getNote(ps.noteId, user).catch(() => null); + let [ + followingUserIds, + mutedUserIds, + mutedInstances, + blockerIds, + ]: string[][] = []; + let mutedWords: string[][] = []; + if (user) { + [followingUserIds, mutedUserIds, mutedInstances, mutedWords, blockerIds] = + await Promise.all([ + LocalFollowingsCache.init(user.id).then((cache) => cache.getAll()), + UserMutingsCache.init(user.id).then((cache) => cache.getAll()), + InstanceMutingsCache.init(user.id).then((cache) => cache.getAll()), + userWordMuteCache + .fetchMaybe(user.id, () => + UserProfiles.findOne({ + select: ["mutedWords"], + where: { userId: user.id }, + }).then((profile) => profile?.mutedWords), + ) + .then((words) => words ?? []), + UserBlockedCache.init(user.id).then((cache) => cache.getAll()), + ]); + } + + const root = await getNote(ps.noteId, user, followingUserIds).catch( + () => null, + ); if (!root) { return await Notes.packMany([]); } @@ -65,7 +107,18 @@ export default define(meta, paramDef, async (ps, user) => { { prepare: true }, ); if (result.rowLength > 0) { - const replies = result.rows.map(parseScyllaNote); + let replies = result.rows.map(parseScyllaNote); + replies = await filterVisibility(replies, user, followingUserIds); + if (user) { + replies = await filterMutedUser( + replies, + user, + mutedUserIds, + mutedInstances, + ); + replies = await filterMutedNote(replies, user, mutedWords); + replies = await filterBlockedUser(replies, user, blockerIds); + } foundReplies.push(...replies); queue.push(...replies); depth++; @@ -73,7 +126,7 @@ export default define(meta, paramDef, async (ps, user) => { } } - return await Notes.packMany(foundReplies.slice(0, ps.limit), user, { + return await Notes.packMany(foundReplies, user, { detail: false, scyllaNote: true, }); diff --git a/packages/backend/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts index c74da2ec71..0d2f8158e0 100644 --- a/packages/backend/src/server/api/endpoints/notes/conversation.ts +++ b/packages/backend/src/server/api/endpoints/notes/conversation.ts @@ -3,6 +3,7 @@ import { Notes } from "@/models/index.js"; import define from "../../define.js"; import { ApiError } from "../../error.js"; import { getNote } from "../../common/getters.js"; +import { LocalFollowingsCache } from "@/misc/cache.js"; export const meta = { tags: ["notes"], @@ -47,7 +48,12 @@ export const paramDef = { } as const; export default define(meta, paramDef, async (ps, user) => { - const note = await getNote(ps.noteId, user).catch((err) => { + let followingIds: string[] = []; + if (user) { + followingIds = await LocalFollowingsCache.init(user.id).then(cache => cache.getAll()); + } + + const note = await getNote(ps.noteId, user, followingIds).catch((err) => { if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") throw new ApiError(meta.errors.noSuchNote); throw err; @@ -58,7 +64,7 @@ export default define(meta, paramDef, async (ps, user) => { async function get(id: string) { i++; - const p = await getNote(id, user).catch((e) => { + const p = await getNote(id, user, followingIds).catch((e) => { if (e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") return null; throw e; });