From 42b555e5e429b42aea8ed9ae129722191b349fd1 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Fri, 2 Jun 2023 15:47:13 +0200 Subject: [PATCH] activitypub: handle incoming Update Note activities Changelog: Added --- .../remote/activitypub/kernel/update/index.ts | 5 +- .../remote/activitypub/kernel/update/note.ts | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/remote/activitypub/kernel/update/note.ts diff --git a/packages/backend/src/remote/activitypub/kernel/update/index.ts b/packages/backend/src/remote/activitypub/kernel/update/index.ts index d34965db2..96367af0a 100644 --- a/packages/backend/src/remote/activitypub/kernel/update/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/update/index.ts @@ -1,9 +1,10 @@ import { IRemoteUser } from '@/models/entities/user.js'; -import { getApId, getApType, IUpdate, isActor } from '@/remote/activitypub/type.js'; +import { getApId, getOneApId, getApType, IUpdate, isActor, isPost } from '@/remote/activitypub/type.js'; import { apLogger } from '@/remote/activitypub/logger.js'; import { updateQuestion } from '@/remote/activitypub/models/question.js'; import { Resolver } from '@/remote/activitypub/resolver.js'; import { updatePerson } from '@/remote/activitypub/models/person.js'; +import { update as updateNote } from '@/remote/activitypub/kernel/update/note.js'; /** * Updateアクティビティを捌きます @@ -30,6 +31,8 @@ export default async (actor: IRemoteUser, activity: IUpdate, resolver: Resolver) } else if (getApType(object) === 'Question') { await updateQuestion(object, resolver).catch(e => console.log(e)); return 'ok: Question updated'; + } else if (isPost(object)) { + return await updateNote(actor, object, resolver); } else { return `skip: Unknown type: ${getApType(object)}`; } diff --git a/packages/backend/src/remote/activitypub/kernel/update/note.ts b/packages/backend/src/remote/activitypub/kernel/update/note.ts new file mode 100644 index 000000000..1c1140241 --- /dev/null +++ b/packages/backend/src/remote/activitypub/kernel/update/note.ts @@ -0,0 +1,50 @@ +import { IRemoteUser } from '@/models/entities/user.js'; +import { getApId } from '@/remote/activitypub/type.js'; +import { Resolver } from '@/remote/activitypub/resolver.js'; +import { Notes } from '@/models/index.js'; +import createNote from '@/remote/activitypub/kernel/create/note.js'; +import { getApLock } from '@/misc/app-lock.js'; +import { updateNote } from '@/remote/activitypub/models/note.js'; + +export async function update(actor: IRemoteUser, note: IObject, resolver: Resolver): Promise { + // check whether note exists + const uri = getApId(note); + const exists = await Notes.findOneBy({ uri }); + + if (exists == null) { + // does not yet exist, handle as if this was a create activity + // and since this is not a direct creation, handle it silently + createNote(resolver, actor, note, true); + + const unlock = await getApLock(uri); + try { + // if creating was successful... + const existsNow = await Notes.findOneByOrFail({ uri }); + // set the updatedAt timestamp since the note was changed + await Notes.update(existsNow.id, { updatedAt: new Date() }); + return 'ok: unknown note created and marked as updated'; + } catch (e) { + return `skip: updated note unknown and creating rejected: ${e.message}`; + } finally { + unlock(); + } + } else { + // check that actor is authorized to update this note + if (actor.id !== exists.userId) { + return 'skip: actor not authorized to update Note'; + } + // this does not redo the checks from the Create Note kernel + // since if the note made it into the database, we assume + // those checks must have been passed before. + + const unlock = await getApLock(uri); + try { + await updateNote(note, actor, resolver); + return 'ok: note updated'; + } catch (e) { + return `skip: update note rejected: ${e.message}`; + } finally { + unlock(); + } + } +}