Merge pull request 'fix: followers transfer via account migration' (#9822) from nmkj/calckey:fix-move into develop
Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9822
This commit is contained in:
commit
49c44771e5
|
@ -1,19 +1,14 @@
|
||||||
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
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 { Followings, Users } from "@/models/index.js";
|
||||||
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
|
import {
|
||||||
import deleteFollowing from "@/services/following/delete.js";
|
resolvePerson,
|
||||||
|
updatePerson,
|
||||||
|
} from "@/remote/activitypub/models/person.js";
|
||||||
import create from "@/services/following/create.js";
|
import create from "@/services/following/create.js";
|
||||||
import { getUser } from "@/server/api/common/getters.js";
|
import deleteFollowing from "@/services/following/delete.js";
|
||||||
import { IdentifiableError } from "@/misc/identifiable-error.js";
|
|
||||||
import { ApiError } from "@/server/api/error.js";
|
import type { IMove } from "../../type.js";
|
||||||
import { meta } from "@/server/api/endpoints/following/create.js";
|
import { getApHrefNullable } from "../../type.js";
|
||||||
import { IObject } from "../../type.js";
|
|
||||||
import type { IMove, IActor } from "../../type.js";
|
|
||||||
import Resolver from "@/remote/activitypub/resolver.js";
|
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
actor: CacheableRemoteUser,
|
actor: CacheableRemoteUser,
|
||||||
|
@ -21,68 +16,46 @@ export default async (
|
||||||
): Promise<string> => {
|
): Promise<string> => {
|
||||||
// ※ There is a block target in activity.object, which should be a local user that exists.
|
// ※ There is a block target in activity.object, which should be a local user that exists.
|
||||||
|
|
||||||
const dbResolver = new DbResolver();
|
// fetch the new and old accounts
|
||||||
const resolver = new Resolver();
|
const targetUri = getApHrefNullable(activity.target);
|
||||||
let new_acc = await dbResolver.getUserFromApId(activity.target);
|
if (!targetUri) return "move: target uri is null";
|
||||||
let actor_new;
|
const new_acc = await resolvePerson(targetUri);
|
||||||
if (!new_acc)
|
if (!actor.uri) return "move: actor uri is null";
|
||||||
actor_new = (await resolver.resolve(<string>activity.target)) as IActor;
|
const old_acc = await resolvePerson(actor.uri);
|
||||||
|
|
||||||
if (
|
// update them if they're remote
|
||||||
(!new_acc || new_acc.uri === null) &&
|
if (new_acc.uri) await updatePerson(new_acc.uri);
|
||||||
(!actor_new || actor_new.id === null)
|
if (old_acc.uri) await updatePerson(old_acc.uri);
|
||||||
) {
|
|
||||||
return "move: new acc not found";
|
// 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();
|
// add target uri to movedToUri in order to indicate that the user has moved
|
||||||
|
await Users.update(old_acc.id, { movedToUri: targetUri });
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// follow the new account and unfollow the old one
|
||||||
const followings = await Followings.findBy({
|
const followings = await Followings.findBy({
|
||||||
followeeId: followee.id,
|
followeeId: old_acc.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
followings.forEach(async (following) => {
|
followings.forEach(async (following) => {
|
||||||
//if follower is local
|
// If follower is local
|
||||||
if (!following.followerHost) {
|
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 {
|
try {
|
||||||
await create(follower!, followeeNew);
|
const follower = await Users.findOneBy({ id: following.followerId });
|
||||||
} catch (e) {
|
if (!follower) return;
|
||||||
|
await create(follower, new_acc);
|
||||||
|
await deleteFollowing(follower, old_acc);
|
||||||
|
} catch {
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { resolveUser } from "@/remote/resolve-user.js";
|
||||||
import { DAY } from "@/const.js";
|
import { DAY } from "@/const.js";
|
||||||
import DeliverManager from "@/remote/activitypub/deliver-manager.js";
|
import DeliverManager from "@/remote/activitypub/deliver-manager.js";
|
||||||
import { renderActivity } from "@/remote/activitypub/renderer/index.js";
|
import { renderActivity } from "@/remote/activitypub/renderer/index.js";
|
||||||
import { genId } from "@/misc/gen-id.js";
|
|
||||||
import define from "../../define.js";
|
import define from "../../define.js";
|
||||||
import { ApiError } from "../../error.js";
|
import { ApiError } from "../../error.js";
|
||||||
import { apiLogger } from "../../logger.js";
|
import { apiLogger } from "../../logger.js";
|
||||||
|
@ -81,7 +80,7 @@ export const paramDef = {
|
||||||
|
|
||||||
function moveActivity(toUrl: string, fromUrl: string) {
|
function moveActivity(toUrl: string, fromUrl: string) {
|
||||||
const activity = {
|
const activity = {
|
||||||
id: genId(),
|
id: null,
|
||||||
actor: fromUrl,
|
actor: fromUrl,
|
||||||
type: "Move",
|
type: "Move",
|
||||||
object: fromUrl,
|
object: fromUrl,
|
||||||
|
|
Loading…
Reference in New Issue