From 06be4e108ba3edb71aa1362376660bc5dc9ee064 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 10 Sep 2023 19:22:45 +0200 Subject: [PATCH] Fix updating remote user host for remote AP implementations that don't support webfinger uri queries --- .../src/remote/activitypub/models/person.ts | 8 +++++--- packages/backend/src/remote/resolve-user.ts | 20 +++++++++++++++++++ .../federation/update-remote-user.ts | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 4f913b50d..73743bec7 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -48,7 +48,7 @@ import Resolver from "../resolver.js"; import { extractApHashtags } from "./tag.js"; import { resolveNote, extractEmojis } from "./note.js"; import { resolveImage } from "./image.js"; -import { getSubjectHostFromUri } from "@/remote/resolve-user.js" +import { getSubjectHostFromUri, getSubjectHostFromRemoteUser } from "@/remote/resolve-user.js" const logger = apLogger; @@ -425,11 +425,13 @@ export async function createPerson( * @param uri URI of Person * @param resolver Resolver * @param hint Hint of Person object (If this value is a valid Person, it is used for updating without Remote resolve) + * @param userHint Hint of IRemoteUser object, used for updating user information for remotes that only support webfinger with acct: query */ export async function updatePerson( uri: string, resolver?: Resolver | null, hint?: IObject, + userHint?: IRemoteUser, ): Promise { if (typeof uri !== "string") throw new Error("uri is not string"); @@ -452,10 +454,10 @@ export async function updatePerson( const person = validateActor(object, uri); - const host = await getSubjectHostFromUri(uri); - logger.info(`Updating the Person: ${person.id}`); + const host = await getSubjectHostFromUri(uri) ?? await getSubjectHostFromRemoteUser(userHint); + // Fetch avatar and header image const [avatar, banner] = await Promise.all( [person.icon, person.image].map((img) => diff --git a/packages/backend/src/remote/resolve-user.ts b/packages/backend/src/remote/resolve-user.ts index 7efaa26d6..b9edbd560 100644 --- a/packages/backend/src/remote/resolve-user.ts +++ b/packages/backend/src/remote/resolve-user.ts @@ -187,6 +187,26 @@ export async function getSubjectHostFromUri(uri: string): Promise } } +export async function getSubjectHostFromAcct(acct: string): Promise { + try { + const res = await resolveUserWebFinger(acct.toLowerCase()); + const finalAcct = subjectToAcct(res.subject); + const m = finalAcct.match(/^([^@]+)@(.*)/); + if (!m) { + return null; + } + return m[2]; + } + catch { + return null; + } +} + + +export async function getSubjectHostFromRemoteUser(user: IRemoteUser | undefined): Promise { + return user ? getSubjectHostFromAcct(`${user.username}@${user.host}`) : null; +} + async function resolveUserWebFinger(acctLower: string, recurse: boolean = true): Promise<{ subject: string, self: { diff --git a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts index f4c3f6d18..9d6e4a7db 100644 --- a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts +++ b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts @@ -18,5 +18,5 @@ export const paramDef = { export default define(meta, paramDef, async (ps) => { const user = await getRemoteUser(ps.userId); - await updatePerson(user.uri!); + await updatePerson(user.uri!, undefined, undefined, user); });