From c7040b77b5c53f72e8b3d1e4ad57c32499768880 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Thu, 27 Jul 2023 07:15:58 -0400 Subject: [PATCH] export visibility check --- packages/backend/src/db/scylla.ts | 28 ++++++++++++++++++- .../backend/src/server/api/common/getters.ts | 28 +++++-------------- packages/backend/src/services/user-cache.ts | 4 +++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/packages/backend/src/db/scylla.ts b/packages/backend/src/db/scylla.ts index dbd1cd2d2d..bc9d688397 100644 --- a/packages/backend/src/db/scylla.ts +++ b/packages/backend/src/db/scylla.ts @@ -3,7 +3,8 @@ import type { PopulatedEmoji } from "@/misc/populate-emojis.js"; import type { Note } from "@/models/entities/note.js"; import type { NoteReaction } from "@/models/entities/note-reaction.js"; import { Client, types } from "cassandra-driver"; -import { noteVisibilities } from "@/types.js"; +import type { User } from "@/models/entities/user.js"; +import { LocalFollowingsCache } from "@/misc/cache.js"; function newClient(): Client | null { if (!config.scylla) { @@ -182,3 +183,28 @@ export function parseScyllaReaction(row: types.Row): ScyllaNoteReaction { emoji: row.get("emoji"), }; } + +export async function isVisible( + note: ScyllaNote, + user: { id: User["id"] } | null, +): Promise { + let visible = false; + + if ( + ["public", "home"].includes(note.visibility) // public post + ) { + visible = true; + } else if (user) { + const cache = await LocalFollowingsCache.init(user.id); + + visible = + note.userId === user.id || // my own post + note.visibleUserIds.includes(user.id) || // visible to me + note.mentions.includes(user.id) || // mentioned me + (note.visibility === "followers" && + (await cache.isFollowing(note.userId))) || // following + note.replyUserId === user.id; // replied to myself + } + + return visible; +} diff --git a/packages/backend/src/server/api/common/getters.ts b/packages/backend/src/server/api/common/getters.ts index b3259d2035..b873914294 100644 --- a/packages/backend/src/server/api/common/getters.ts +++ b/packages/backend/src/server/api/common/getters.ts @@ -3,8 +3,12 @@ import type { User } from "@/models/entities/user.js"; import type { Note } from "@/models/entities/note.js"; import { Notes, Users } from "@/models/index.js"; import { generateVisibilityQuery } from "./generate-visibility-query.js"; -import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js"; -import { LocalFollowingsCache } from "@/misc/cache.js"; +import { + isVisible, + parseScyllaNote, + prepared, + scyllaClient, +} from "@/db/scylla.js"; /** * Get note for API processing, taking into account visibility. @@ -22,25 +26,7 @@ export async function getNote( ); if (result.rowLength > 0) { const candidate = parseScyllaNote(result.first()); - let valid = false; - - if ( - ["public", "home"].includes(candidate.visibility) // public post - ) { - valid = true; - } else if (me) { - const cache = await LocalFollowingsCache.init(me.id); - - valid = - candidate.userId === me.id || // my own post - candidate.visibleUserIds.includes(me.id) || // visible to me - candidate.mentions.includes(me.id) || // mentioned me - (candidate.visibility === "followers" && - (await cache.isFollowing(candidate.userId))) || // following - candidate.replyUserId === me.id; // replied to myself - } - - if (valid) { + if (await isVisible(candidate, me)) { note = candidate; } } diff --git a/packages/backend/src/services/user-cache.ts b/packages/backend/src/services/user-cache.ts index ed700185df..2eff8ba11f 100644 --- a/packages/backend/src/services/user-cache.ts +++ b/packages/backend/src/services/user-cache.ts @@ -20,6 +20,10 @@ export const uriPersonCache = new Cache( "uriPerson", 60 * 30, ); +export const userDenormalizedCache = new Cache( + "userDenormalized", + 60 * 30, +); subscriber.on("message", async (_, data) => { const obj = JSON.parse(data);