diff --git a/packages/backend/src/services/create-notification.ts b/packages/backend/src/services/create-notification.ts index f6545b131c..e2dd3fc332 100644 --- a/packages/backend/src/services/create-notification.ts +++ b/packages/backend/src/services/create-notification.ts @@ -6,11 +6,13 @@ import { NoteThreadMutings, UserProfiles, Users, + Followings, } from "@/models/index.js"; import { genId } from "@/misc/gen-id.js"; import type { User } from "@/models/entities/user.js"; import type { Notification } from "@/models/entities/notification.js"; import { sendEmailNotification } from "./send-email-notification.js"; +import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; export async function createNotification( notifieeId: User["id"], @@ -21,6 +23,26 @@ export async function createNotification( return null; } + if ( + data.notifierId && + ["mention", "reply", "renote", "quote", "reaction"].includes(type) + ) { + const notifier = await Users.findOneBy({ id: data.notifierId }); + // suppress if the notifier does not exist or is silenced. + if (!notifier) return null; + + // suppress if the notifier is silenced or in a silenced instance, and not followed by the notifiee. + if ( + (notifier.isSilenced || + (Users.isRemoteUser(notifier) && + (await shouldSilenceInstance(notifier.host)))) && + !(await Followings.exist({ + where: { followerId: notifieeId, followeeId: data.notifierId }, + })) + ) + return null; + } + const profile = await UserProfiles.findOneBy({ userId: notifieeId }); const isMuted = profile?.mutingNotificationTypes.includes(type); diff --git a/packages/backend/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts index 27f9144d0e..50dbd9b3be 100644 --- a/packages/backend/src/services/following/requests/create.ts +++ b/packages/backend/src/services/following/requests/create.ts @@ -80,7 +80,13 @@ export default async function ( } if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) { - const content = renderActivity(renderFollow(follower, followee, requestId ?? `${config.url}/follows/${followRequest.id}`)); + const content = renderActivity( + renderFollow( + follower, + followee, + requestId ?? `${config.url}/follows/${followRequest.id}`, + ), + ); deliver(follower, content, followee.inbox); } } diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index ad50bd97a4..f1164c9c6e 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -205,11 +205,12 @@ export default async ( data.visibility = "home"; } - const inSilencedInstance = - Users.isRemoteUser(user) && (await shouldSilenceInstance(user.host)); - // Enforce home visibility if the user is in a silenced instance. - if (data.visibility === "public" && inSilencedInstance) { + if ( + data.visibility === "public" && + Users.isRemoteUser(user) && + (await shouldSilenceInstance(user.host)) + ) { data.visibility = "home"; } @@ -317,16 +318,6 @@ export default async ( } } - // Remove from mention the local users who aren't following the remote user in the silenced instance. - if (inSilencedInstance) { - const relations = await Followings.findBy([ - { followeeId: user.id, followerHost: IsNull() }, // a local user following the silenced user - ]).then((rels) => rels.map((rel) => rel.followerId)); - mentionedUsers = mentionedUsers.filter((mentioned) => - relations.includes(mentioned.id), - ); - } - const note = await insertNote(user, data, tags, emojis, mentionedUsers); res(note); diff --git a/packages/backend/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts index 20a724f3da..277393eb41 100644 --- a/packages/backend/src/services/note/reaction/create.ts +++ b/packages/backend/src/services/note/reaction/create.ts @@ -12,7 +12,6 @@ import { Notes, Emojis, Blockings, - Followings, } from "@/models/index.js"; import { IsNull, Not } from "typeorm"; import { perUserReactionsChart } from "@/services/chart/index.js"; @@ -22,7 +21,6 @@ import deleteReaction from "./delete.js"; import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js"; import type { NoteReaction } from "@/models/entities/note-reaction.js"; import { IdentifiableError } from "@/misc/identifiable-error.js"; -import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; export default async ( user: { id: User["id"]; host: User["host"] }, @@ -121,24 +119,7 @@ export default async ( }); // Create notification if the reaction target is a local user. - if ( - note.userHost === null && - // if a local user reacted, or - (Users.isLocalUser(user) || - // if a remote user not in a silenced instance reacted - (Users.isRemoteUser(user) && - // if a remote user is in a silenced instance and the target is a local follower. - !( - (await shouldSilenceInstance(user.host)) && - !(await Followings.exist({ - where: { - followerId: note.userId, - followerHost: IsNull(), - followeeId: user.id, - }, - })) - ))) - ) { + if (note.userHost === null) { createNotification(note.userId, "reaction", { notifierId: user.id, note: note,