From db52926594c67e26420dbd0f4c0038e119749af1 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Sat, 3 Dec 2022 01:23:02 +0100 Subject: [PATCH] Implement recieve moveTo Untested, hopefully it works.. Signed-off-by: cutestnekoaqua --- packages/backend/src/misc/fetch-meta.ts | 4 +- .../remote/activitypub/kernel/block/index.ts | 4 +- .../src/remote/activitypub/kernel/index.ts | 25 +++++++- .../remote/activitypub/kernel/move/index.ts | 63 +++++++++++++++++++ .../backend/src/remote/activitypub/type.ts | 4 +- packages/backend/src/server/index.ts | 3 +- packages/backend/src/server/nodeinfo.ts | 9 +-- 7 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 packages/backend/src/remote/activitypub/kernel/move/index.ts diff --git a/packages/backend/src/misc/fetch-meta.ts b/packages/backend/src/misc/fetch-meta.ts index e855ac28e..3e74118f0 100644 --- a/packages/backend/src/misc/fetch-meta.ts +++ b/packages/backend/src/misc/fetch-meta.ts @@ -7,7 +7,7 @@ export async function fetchMeta(noCache = false): Promise { if (!noCache && cache) return cache; return await db.transaction(async transactionalEntityManager => { - // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する + // New IDs are prioritized because multiple records may have been created due to past bugs. const metas = await transactionalEntityManager.find(Meta, { order: { id: 'DESC', @@ -20,7 +20,7 @@ export async function fetchMeta(noCache = false): Promise { cache = meta; return meta; } else { - // metaが空のときfetchMetaが同時に呼ばれるとここが同時に呼ばれてしまうことがあるのでフェイルセーフなupsertを使う + // If fetchMeta is called at the same time when meta is empty, this part may be called at the same time, so use fail-safe upsert. const saved = await transactionalEntityManager .upsert( Meta, diff --git a/packages/backend/src/remote/activitypub/kernel/block/index.ts b/packages/backend/src/remote/activitypub/kernel/block/index.ts index 5e230ad7b..c8b60f7b9 100644 --- a/packages/backend/src/remote/activitypub/kernel/block/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/block/index.ts @@ -5,7 +5,7 @@ import DbResolver from '../../db-resolver.js'; import { Users } from '@/models/index.js'; export default async (actor: CacheableRemoteUser, activity: IBlock): Promise => { - // ※ activity.objectにブロック対象があり、それは存在するローカルユーザーのはず + // ※ There is a block target in activity.object, which should be a local user that exists. const dbResolver = new DbResolver(); const blockee = await dbResolver.getUserFromApId(activity.object); @@ -15,7 +15,7 @@ export default async (actor: CacheableRemoteUser, activity: IBlock): Promise => { + // ※ There is a block target in activity.object, which should be a local user that exists. + + const dbResolver = new DbResolver(); + let new_acc = await dbResolver.getUserFromApId(activity.target); + if (!new_acc) new_acc = await getRemoteUser(activity.target); + + let old_acc = await dbResolver.getUserFromApId(activity.actor); + if (!old_acc) new_acc = await getRemoteUser(activity.actor); + + if (!new_acc || new_acc.uri === null) { + return `move: new acc not found`; + } + if (!old_acc || old_acc.uri === null) { + return `move: old acc not found`; + } + await updatePerson(new_acc.uri); + await updatePerson(old_acc.uri); + new_acc = await getRemoteUser(new_acc.uri); + old_acc = await getRemoteUser(old_acc.uri); + + if(old_acc === null || old_acc.uri === null || !new_acc?.alsoKnownAs?.includes(old_acc.uri)) return `move: accounts invalid`; + + old_acc.movedToUri = new_acc?.uri + + const query = makePaginationQuery(Followings.createQueryBuilder('following')) + .andWhere('following.followeeId = :userId', { userId: old_acc.id }) + .innerJoinAndSelect('following.follower', 'follower'); + + const followings = await query + .getMany(); + + followings.forEach(following => { + if(!following.follower?.host) { + let follower = following.follower; + deleteFollowing(follower!, old_acc!); + try { + create(follower!, new_acc!); + } catch (e) { + if (e instanceof IdentifiableError) { + if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); + if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked); + } + throw e; + } + } + }) + + return `ok`; +}; diff --git a/packages/backend/src/remote/activitypub/type.ts b/packages/backend/src/remote/activitypub/type.ts index d04352e4c..aabbd0679 100644 --- a/packages/backend/src/remote/activitypub/type.ts +++ b/packages/backend/src/remote/activitypub/type.ts @@ -160,7 +160,7 @@ export interface IActor extends IObject { alsoKnownAs?: string[]; discoverable?: boolean; inbox: string; - sharedInbox?: string; // 後方互換性のため + sharedInbox?: string; // backward compatibility.. ig publicKey?: { id: string; publicKeyPem: string; @@ -283,6 +283,7 @@ export interface IFlag extends IActivity { export interface IMove extends IActivity { type: 'Move'; + target: IObject | string; } export const isCreate = (object: IObject): object is ICreate => getApType(object) === 'Create'; @@ -299,3 +300,4 @@ export const isLike = (object: IObject): object is ILike => getApType(object) == export const isAnnounce = (object: IObject): object is IAnnounce => getApType(object) === 'Announce'; export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block'; export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag'; +export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move'; diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index f31de2b7f..10566339e 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -19,7 +19,7 @@ import { genIdenticon } from '@/misc/gen-identicon.js'; import { createTemp } from '@/misc/create-temp.js'; import { publishMainStream } from '@/services/stream.js'; import * as Acct from '@/misc/acct.js'; -import { envOption } from '../env.js'; +import { envOption } from '@/env'; import activityPub from './activitypub.js'; import nodeinfo from './nodeinfo.js'; import wellKnown from './well-known.js'; @@ -164,5 +164,6 @@ export default () => new Promise(resolve => { } }); + // @ts-ignore server.listen(config.port, resolve); }); diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index b4216d9d9..0bb9e05c5 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -11,11 +11,11 @@ const router = new Router(); const nodeinfo2_1path = '/nodeinfo/2.1'; const nodeinfo2_0path = '/nodeinfo/2.0'; -export const links = [/* (awaiting release) { - rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1', +export const links = [{ + rel: 'https://nodeinfo.diaspora.software/ns/schema/2.1', href: config.url + nodeinfo2_1path -}, */{ - rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', +}, { + rel: 'https://nodeinfo.diaspora.software/ns/schema/2.0', href: config.url + nodeinfo2_0path, }]; @@ -96,6 +96,7 @@ router.get(nodeinfo2_1path, async ctx => { router.get(nodeinfo2_0path, async ctx => { const base = await cache.fetch(null, () => nodeinfo2()); + // @ts-ignore delete base.software.repository; ctx.body = { version: '2.0', ...base };