suppress notification from silenced users and instances
This commit is contained in:
parent
9535bbcf89
commit
784f632b99
4 changed files with 35 additions and 35 deletions
|
@ -6,11 +6,13 @@ import {
|
||||||
NoteThreadMutings,
|
NoteThreadMutings,
|
||||||
UserProfiles,
|
UserProfiles,
|
||||||
Users,
|
Users,
|
||||||
|
Followings,
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
import { genId } from "@/misc/gen-id.js";
|
import { genId } from "@/misc/gen-id.js";
|
||||||
import type { User } from "@/models/entities/user.js";
|
import type { User } from "@/models/entities/user.js";
|
||||||
import type { Notification } from "@/models/entities/notification.js";
|
import type { Notification } from "@/models/entities/notification.js";
|
||||||
import { sendEmailNotification } from "./send-email-notification.js";
|
import { sendEmailNotification } from "./send-email-notification.js";
|
||||||
|
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
||||||
|
|
||||||
export async function createNotification(
|
export async function createNotification(
|
||||||
notifieeId: User["id"],
|
notifieeId: User["id"],
|
||||||
|
@ -21,6 +23,26 @@ export async function createNotification(
|
||||||
return null;
|
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 profile = await UserProfiles.findOneBy({ userId: notifieeId });
|
||||||
|
|
||||||
const isMuted = profile?.mutingNotificationTypes.includes(type);
|
const isMuted = profile?.mutingNotificationTypes.includes(type);
|
||||||
|
|
|
@ -80,7 +80,13 @@ export default async function (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
|
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);
|
deliver(follower, content, followee.inbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,11 +205,12 @@ export default async (
|
||||||
data.visibility = "home";
|
data.visibility = "home";
|
||||||
}
|
}
|
||||||
|
|
||||||
const inSilencedInstance =
|
|
||||||
Users.isRemoteUser(user) && (await shouldSilenceInstance(user.host));
|
|
||||||
|
|
||||||
// Enforce home visibility if the user is in a silenced instance.
|
// 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";
|
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);
|
const note = await insertNote(user, data, tags, emojis, mentionedUsers);
|
||||||
|
|
||||||
res(note);
|
res(note);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
Notes,
|
Notes,
|
||||||
Emojis,
|
Emojis,
|
||||||
Blockings,
|
Blockings,
|
||||||
Followings,
|
|
||||||
} from "@/models/index.js";
|
} from "@/models/index.js";
|
||||||
import { IsNull, Not } from "typeorm";
|
import { IsNull, Not } from "typeorm";
|
||||||
import { perUserReactionsChart } from "@/services/chart/index.js";
|
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 { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
|
||||||
import type { NoteReaction } from "@/models/entities/note-reaction.js";
|
import type { NoteReaction } from "@/models/entities/note-reaction.js";
|
||||||
import { IdentifiableError } from "@/misc/identifiable-error.js";
|
import { IdentifiableError } from "@/misc/identifiable-error.js";
|
||||||
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
user: { id: User["id"]; host: User["host"] },
|
user: { id: User["id"]; host: User["host"] },
|
||||||
|
@ -121,24 +119,7 @@ export default async (
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create notification if the reaction target is a local user.
|
// Create notification if the reaction target is a local user.
|
||||||
if (
|
if (note.userHost === null) {
|
||||||
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,
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
)))
|
|
||||||
) {
|
|
||||||
createNotification(note.userId, "reaction", {
|
createNotification(note.userId, "reaction", {
|
||||||
notifierId: user.id,
|
notifierId: user.id,
|
||||||
note: note,
|
note: note,
|
||||||
|
|
Loading…
Reference in a new issue