diff --git a/packages/backend/src/remote/activitypub/audience.ts b/packages/backend/src/remote/activitypub/audience.ts index 210d47573..aa70c25b2 100644 --- a/packages/backend/src/remote/activitypub/audience.ts +++ b/packages/backend/src/remote/activitypub/audience.ts @@ -9,6 +9,7 @@ import type { CacheableUser, } from "@/models/entities/user.js"; import { User } from "@/models/entities/user.js"; +import { RecursionLimiter } from "@/models/repositories/user-profile.js"; type Visibility = "public" | "home" | "followers" | "specified"; @@ -23,6 +24,7 @@ export async function parseAudience( to?: ApObject, cc?: ApObject, resolver?: Resolver, + limiter: RecursionLimiter = new RecursionLimiter(20) ): Promise { const toGroups = groupingAudience(getApIds(to), actor); const ccGroups = groupingAudience(getApIds(cc), actor); @@ -33,7 +35,7 @@ export async function parseAudience( const mentionedUsers = ( await Promise.all( others.map((id) => - limit(() => resolvePerson(id, resolver).catch(() => null)), + limit(() => resolvePerson(id, resolver, limiter).catch(() => null)), ), ) ).filter((x): x is CacheableUser => x != null); diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index 243947b32..713de0f45 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -176,7 +176,7 @@ export async function createNote( return null; } - const noteAudience = await parseAudience(actor, note.to, note.cc); + const noteAudience = await parseAudience(actor, note.to, note.cc, undefined, limiter); let visibility = noteAudience.visibility; const visibleUsers = noteAudience.visibleUsers; @@ -394,6 +394,7 @@ export async function createNote( url: url, }, silent, + limiter ); } diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index c41897c34..a451730bb 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -67,6 +67,7 @@ import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; import meilisearch from "../../db/meilisearch.js"; import { redisClient } from "@/db/redis.js"; import { Mutex } from "redis-semaphore"; +import { RecursionLimiter } from "@/models/repositories/user-profile.js"; const mutedWordsCache = new Cache< { userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[] @@ -167,6 +168,7 @@ export default async ( }, data: Option, silent = false, + limiter: RecursionLimiter = new RecursionLimiter(20) ) => // rome-ignore lint/suspicious/noAsyncPromiseExecutor: FIXME new Promise(async (res, rej) => { @@ -292,7 +294,7 @@ export default async ( emojis = data.apEmojis || extractCustomEmojisFromMfm(combinedTokens); mentionedUsers = - data.apMentions || (await extractMentionedUsers(user, combinedTokens)); + data.apMentions || (await extractMentionedUsers(user, combinedTokens, limiter)); } tags = tags @@ -925,6 +927,7 @@ function incNotesCountOfUser(user: { id: User["id"] }) { export async function extractMentionedUsers( user: { host: User["host"] }, tokens: mfm.MfmNode[], + limiter: RecursionLimiter = new RecursionLimiter(20) ): Promise { if (tokens == null) return []; @@ -933,7 +936,7 @@ export async function extractMentionedUsers( let mentionedUsers = ( await Promise.all( mentions.map((m) => - resolveUser(m.username, m.host || user.host).catch(() => null), + resolveUser(m.username, m.host || user.host, undefined, limiter).catch(() => null), ), ) ).filter((x) => x != null) as User[];