From ed23b0bd6fb2a2e600e8f38ac404176803c71d18 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 e855ac28ee..3e74118f0f 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 5e230ad7b7..c8b60f7b9f 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 d04352e4cc..aabbd06797 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 f31de2b7f4..10566339e5 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 b4216d9d92..0bb9e05c53 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 };