diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts index 29ac726efc..d47e6f3007 100644 --- a/packages/backend/src/server/activitypub.ts +++ b/packages/backend/src/server/activitypub.ts @@ -10,7 +10,7 @@ import { renderPerson } from "@/remote/activitypub/renderer/person.js"; import renderEmoji from "@/remote/activitypub/renderer/emoji.js"; import { inbox as processInbox } from "@/queue/index.js"; import { isSelfHost, toPuny } from "@/misc/convert-host.js"; -import { Notes, Users, Emojis, NoteReactions } from "@/models/index.js"; +import { Notes, Users, Emojis, NoteReactions, FollowRequests } from "@/models/index.js"; import type { ILocalUser, User } from "@/models/entities/user.js"; import { renderLike } from "@/remote/activitypub/renderer/like.js"; import { getUserKeypair } from "@/misc/keypair-store.js"; @@ -330,7 +330,7 @@ router.get("/likes/:like", async (ctx) => { }); // follow -router.get("/follows/:follower/:followee", async (ctx) => { +router.get("/follows/:follower/:followee", async (ctx: Router.RouterContext) => { const verify = await checkFetch(ctx.req); if (verify !== 200) { ctx.status = verify; @@ -365,4 +365,47 @@ router.get("/follows/:follower/:followee", async (ctx) => { setResponseType(ctx); }); +// follow request +router.get("/follows/:followRequestId", async (ctx: Router.RouterContext) => { + const verify = await checkFetch(ctx.req); + if (verify !== 200) { + ctx.status = verify; + return; + } + + const followRequest = await FollowRequests.findOneBy({ + id: ctx.params.followRequestId, + }); + + if (followRequest == null) { + ctx.status = 404; + return; + } + + const [follower, followee] = await Promise.all([ + Users.findOneBy({ + id: followRequest.followerId, + host: IsNull(), + }), + Users.findOneBy({ + id: followRequest.followeeId, + host: Not(IsNull()), + }), + ]); + + if (follower == null || followee == null) { + ctx.status = 404; + return; + } + + const meta = await fetchMeta(); + if (meta.secureMode || meta.privateMode) { + ctx.set("Cache-Control", "private, max-age=0, must-revalidate"); + } else { + ctx.set("Cache-Control", "public, max-age=180"); + } + ctx.body = renderActivity(renderFollow(follower, followee)); + setResponseType(ctx); +}); + export default router; diff --git a/packages/backend/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts index 8b2e86ab5b..27f9144d0e 100644 --- a/packages/backend/src/services/following/requests/create.ts +++ b/packages/backend/src/services/following/requests/create.ts @@ -6,6 +6,7 @@ import type { User } from "@/models/entities/user.js"; import { Blockings, FollowRequests, Users } from "@/models/index.js"; import { genId } from "@/misc/gen-id.js"; import { createNotification } from "../../create-notification.js"; +import config from "@/config/index.js"; export default async function ( follower: { @@ -79,7 +80,7 @@ export default async function ( } if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) { - const content = renderActivity(renderFollow(follower, followee)); + const content = renderActivity(renderFollow(follower, followee, requestId ?? `${config.url}/follows/${followRequest.id}`)); deliver(follower, content, followee.inbox); } }