Files
FrozenFriendsYume/packages/backend/built/services/blocking/create.js
T
2026-07-26 18:25:37 +09:00

128 lines
4.9 KiB
JavaScript

import { publishMainStream, publishUserEvent } from "../stream.js";
import { renderActivity } from "../../remote/activitypub/renderer/index.js";
import renderFollow from "../../remote/activitypub/renderer/follow.js";
import renderUndo from "../../remote/activitypub/renderer/undo.js";
import { renderBlock } from "../../remote/activitypub/renderer/block.js";
import { deliver } from "../../queue/index.js";
import renderReject from "../../remote/activitypub/renderer/reject.js";
import { Blockings, Users, FollowRequests, Followings, UserListJoinings, UserLists } from "../../models/index.js";
import { perUserFollowingChart } from "../chart/index.js";
import { genId } from "../../misc/gen-id.js";
import { getActiveWebhooks } from "../../misc/webhook-cache.js";
import { webhookDeliver } from "../../queue/index.js";
export default async function(blocker, blockee, groupId = null) {
await Promise.all([
cancelRequest(blocker, blockee),
cancelRequest(blockee, blocker),
unFollow(blocker, blockee),
unFollow(blockee, blocker),
removeFromList(blockee, blocker)
]);
const blocking = {
id: genId(),
createdAt: new Date(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
groupId
};
await Blockings.insert(blocking);
if (Users.isLocalUser(blocker) && Users.isRemoteUser(blockee)) {
const content = renderActivity(renderBlock(blocking));
deliver(blocker, content, blockee.inbox);
}
}
async function cancelRequest(follower, followee) {
const request = await FollowRequests.findOneBy({
followeeId: followee.id,
followerId: follower.id
});
if (request == null) {
return;
}
await FollowRequests.delete({
followeeId: followee.id,
followerId: follower.id
});
if (Users.isLocalUser(followee)) {
Users.pack(followee, followee, {
detail: true
}).then((packed)=>publishMainStream(followee.id, "meUpdated", packed));
}
if (Users.isLocalUser(follower)) {
Users.pack(followee, follower, {
detail: true
}).then(async (packed)=>{
publishUserEvent(follower.id, "unfollow", packed);
publishMainStream(follower.id, "unfollow", packed);
const webhooks = (await getActiveWebhooks()).filter((x)=>x.userId === follower.id && x.on.includes("unfollow"));
for (const webhook of webhooks){
webhookDeliver(webhook, "unfollow", {
user: packed
});
}
});
}
// リモートにフォローリクエストをしていたらUndoFollow送信
if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
const content = renderActivity(renderUndo(renderFollow(follower, followee), follower));
deliver(follower, content, followee.inbox);
}
// リモートからフォローリクエストを受けていたらReject送信
if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
const content = renderActivity(renderReject(renderFollow(follower, followee, request.requestId), followee));
deliver(followee, content, follower.inbox);
}
}
async function unFollow(follower, followee) {
const following = await Followings.findOneBy({
followerId: follower.id,
followeeId: followee.id
});
if (following == null) {
return;
}
await Promise.all([
Followings.delete(following.id),
Users.decrement({
id: follower.id
}, "followingCount", 1),
Users.decrement({
id: followee.id
}, "followersCount", 1),
perUserFollowingChart.update(follower, followee, false)
]);
// Publish unfollow event
if (Users.isLocalUser(follower)) {
Users.pack(followee, follower, {
detail: true
}).then(async (packed)=>{
publishUserEvent(follower.id, "unfollow", packed);
publishMainStream(follower.id, "unfollow", packed);
const webhooks = (await getActiveWebhooks()).filter((x)=>x.userId === follower.id && x.on.includes("unfollow"));
for (const webhook of webhooks){
webhookDeliver(webhook, "unfollow", {
user: packed
});
}
});
}
// リモートにフォローをしていたらUndoFollow送信
if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
const content = renderActivity(renderUndo(renderFollow(follower, followee), follower));
deliver(follower, content, followee.inbox);
}
}
async function removeFromList(listOwner, user) {
const userLists = await UserLists.findBy({
userId: listOwner.id
});
for (const userList of userLists){
await UserListJoinings.delete({
userListId: userList.id,
userId: user.id
});
}
}