diff --git a/packages/backend/src/remote/activitypub/kernel/move/index.ts b/packages/backend/src/remote/activitypub/kernel/move/index.ts index 47a55b8ab..690b84b0e 100644 --- a/packages/backend/src/remote/activitypub/kernel/move/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/move/index.ts @@ -1,19 +1,14 @@ import type { CacheableRemoteUser } from "@/models/entities/user.js"; -import { IRemoteUser, User } from "@/models/entities/user.js"; -import DbResolver from "@/remote/activitypub/db-resolver.js"; -import { getRemoteUser } from "@/server/api/common/getters.js"; -import { updatePerson } from "@/remote/activitypub/models/person.js"; import { Followings, Users } from "@/models/index.js"; -import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js"; -import deleteFollowing from "@/services/following/delete.js"; +import { + resolvePerson, + updatePerson, +} from "@/remote/activitypub/models/person.js"; import create from "@/services/following/create.js"; -import { getUser } from "@/server/api/common/getters.js"; -import { IdentifiableError } from "@/misc/identifiable-error.js"; -import { ApiError } from "@/server/api/error.js"; -import { meta } from "@/server/api/endpoints/following/create.js"; -import { IObject } from "../../type.js"; -import type { IMove, IActor } from "../../type.js"; -import Resolver from "@/remote/activitypub/resolver.js"; +import deleteFollowing from "@/services/following/delete.js"; + +import type { IMove } from "../../type.js"; +import { getApHrefNullable } from "../../type.js"; export default async ( actor: CacheableRemoteUser, @@ -21,68 +16,46 @@ export default async ( ): Promise => { // ※ There is a block target in activity.object, which should be a local user that exists. - const dbResolver = new DbResolver(); - const resolver = new Resolver(); - let new_acc = await dbResolver.getUserFromApId(activity.target); - let actor_new; - if (!new_acc) - actor_new = (await resolver.resolve(activity.target)) as IActor; + // fetch the new and old accounts + const targetUri = getApHrefNullable(activity.target); + if (!targetUri) return "move: target uri is null"; + const new_acc = await resolvePerson(targetUri); + if (!actor.uri) return "move: actor uri is null"; + const old_acc = await resolvePerson(actor.uri); - if ( - (!new_acc || new_acc.uri === null) && - (!actor_new || actor_new.id === null) - ) { - return "move: new acc not found"; + // update them if they're remote + if (new_acc.uri) await updatePerson(new_acc.uri); + if (old_acc.uri) await updatePerson(old_acc.uri); + + // check if alsoKnownAs of the new account is valid + let isValidMove = true; + if (old_acc.uri) { + if (!new_acc.alsoKnownAs?.includes(old_acc.uri)) { + isValidMove = false; + } + } else if (!new_acc.alsoKnownAs?.includes(old_acc.id)) { + isValidMove = false; + } + if (!isValidMove) { + return "skip: accounts invalid"; } - const newUri = new_acc ? new_acc.uri : actor_new?.url?.toString(); - - if (newUri === null || newUri === undefined) - return "move: new acc not found #2"; - - await updatePerson(newUri); - await updatePerson(actor.uri!); - - new_acc = await dbResolver.getUserFromApId(newUri); - const old = await dbResolver.getUserFromApId(actor.uri!); - - if ( - old === null || - old.uri === null || - !new_acc?.alsoKnownAs?.includes(old.uri) - ) - return "move: accounts invalid"; - - old.movedToUri = new_acc.uri; - - const followee = await getUser(actor.id).catch((e) => { - if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff") - throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - - const followeeNew = await getUser(new_acc.id).catch((e) => { - if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff") - throw new ApiError(meta.errors.noSuchUser); - throw e; - }); + // add target uri to movedToUri in order to indicate that the user has moved + await Users.update(old_acc.id, { movedToUri: targetUri }); + // follow the new account and unfollow the old one const followings = await Followings.findBy({ - followeeId: followee.id, + followeeId: old_acc.id, }); - followings.forEach(async (following) => { - //if follower is local + // If follower is local if (!following.followerHost) { - const follower = await getUser(following.followerId).catch((e) => { - if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff") - throw new ApiError(meta.errors.noSuchUser); - throw e; - }); - await deleteFollowing(follower!, followee); try { - await create(follower!, followeeNew); - } catch (e) { + const follower = await Users.findOneBy({ id: following.followerId }); + if (!follower) return; + await create(follower, new_acc); + await deleteFollowing(follower, old_acc); + } catch { /* empty */ } } diff --git a/packages/backend/src/server/api/endpoints/i/move.ts b/packages/backend/src/server/api/endpoints/i/move.ts index bfeba0459..3d947063f 100644 --- a/packages/backend/src/server/api/endpoints/i/move.ts +++ b/packages/backend/src/server/api/endpoints/i/move.ts @@ -3,7 +3,6 @@ import { resolveUser } from "@/remote/resolve-user.js"; import { DAY } from "@/const.js"; import DeliverManager from "@/remote/activitypub/deliver-manager.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import { genId } from "@/misc/gen-id.js"; import define from "../../define.js"; import { ApiError } from "../../error.js"; import { apiLogger } from "../../logger.js"; @@ -81,7 +80,7 @@ export const paramDef = { function moveActivity(toUrl: string, fromUrl: string) { const activity = { - id: genId(), + id: null, actor: fromUrl, type: "Move", object: fromUrl,