From 61445d3d87169011a6c317f710737bb7e4090aee Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 17 Oct 2024 11:05:27 -0400 Subject: [PATCH] feat: send Update(Note) on chat message deletion and restoration, serving Tombstone if deleted re: #12853 --- src/activitypub/inbox.js | 13 +++++++++++-- src/activitypub/mocks.js | 14 ++++++++++++-- src/api/activitypub.js | 12 +++++++++--- src/messaging/delete.js | 4 ++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/activitypub/inbox.js b/src/activitypub/inbox.js index 90ed9d6a22..ed33d00e90 100644 --- a/src/activitypub/inbox.js +++ b/src/activitypub/inbox.js @@ -107,8 +107,11 @@ inbox.update = async (req) => { } case isMessage: { - const roomId = await messaging.getMessageField(object.id, 'roomId'); + const [roomId, deleted] = await messaging.getMessageFields(object.id, ['roomId', 'deleted']); await messaging.editMessage(actor, object.id, roomId, object.content); + if (deleted) { + await api.chats.restoreMessage({ uid: actor }, { mid: object.id }); + } break; } @@ -140,8 +143,9 @@ inbox.update = async (req) => { } case 'Tombstone': { - const [isNote/* , isActor */] = await Promise.all([ + const [isNote, isMessage/* , isActor */] = await Promise.all([ posts.exists(object.id), + messaging.messageExists(object.id), // db.isSortedSetMember('usersRemote:lastCrawled', object.id), ]); @@ -151,6 +155,11 @@ inbox.update = async (req) => { break; } + case isMessage: { + await api.chats.deleteMessage({ uid: actor }, { mid: object.id }); + break; + } + // case isActor: { // console.log('actor'); // break; diff --git a/src/activitypub/mocks.js b/src/activitypub/mocks.js index 90ba7b478d..09f6eeb934 100644 --- a/src/activitypub/mocks.js +++ b/src/activitypub/mocks.js @@ -451,10 +451,20 @@ Mocks.notes.public = async (post) => { }; Mocks.notes.private = async ({ messageObj }) => { - // todo: deleted messages + const id = `${nconf.get('url')}/message/${messageObj.mid}`; + + // Return a tombstone for a deleted message + if (messageObj.deleted === 1) { + return Mocks.tombstone({ + id, + formerType: 'Note', + attributedTo: `${nconf.get('url')}/uid/${messageObj.fromuid}`, + // context: `${nconf.get('url')}/topic/${post.topic.tid}`, + }); + } + let uids = await messaging.getUidsInRoom(messageObj.roomId, 0, -1); uids = uids.filter(uid => String(uid) !== String(messageObj.fromuid)); // no author - const id = `${nconf.get('url')}/message/${messageObj.mid}`; const to = new Set(uids.map(uid => (utils.isNumber(uid) ? `${nconf.get('url')}/uid/${uid}` : uid))); const published = messageObj.timestampISO; const updated = messageObj.edited ? messageObj.editedISO : undefined; diff --git a/src/api/activitypub.js b/src/api/activitypub.js index db4493f565..24a8504bb2 100644 --- a/src/api/activitypub.js +++ b/src/api/activitypub.js @@ -288,16 +288,22 @@ activitypubApi.update.note = enabledCheck(async (caller, { post }) => { }); activitypubApi.update.privateNote = enabledCheck(async (caller, { messageObj }) => { + if (!utils.isNumber(messageObj.mid)) { + return; + } + const { roomId } = messageObj; - let targets = await messaging.getUidsInRoom(roomId, 0, -1); - targets = targets.filter(uid => !utils.isNumber(uid)); // remote uids only + let uids = await messaging.getUidsInRoom(roomId, 0, -1); + uids = uids.filter(uid => String(uid) !== String(messageObj.fromuid)); // no author + const to = uids.map(uid => (utils.isNumber(uid) ? `${nconf.get('url')}/uid/${uid}` : uid)); + const targets = uids.filter(uid => !utils.isNumber(uid)); // remote uids only const object = await activitypub.mocks.notes.private({ messageObj }); const payload = { id: `${object.id}#activity/create/${Date.now()}`, type: 'Update', - to: object.to, + to, object, }; diff --git a/src/messaging/delete.js b/src/messaging/delete.js index 1c16ceddc1..9e0f23c797 100644 --- a/src/messaging/delete.js +++ b/src/messaging/delete.js @@ -2,6 +2,7 @@ const sockets = require('../socket.io'); const plugins = require('../plugins'); +const api = require('../api'); module.exports = function (Messaging) { Messaging.deleteMessage = async (mid, uid) => await doDeleteRestore(mid, 1, uid); @@ -18,6 +19,7 @@ module.exports = function (Messaging) { await Messaging.setMessageField(mid, 'deleted', state); msgData.deleted = state; + const ioRoom = sockets.in(`chat_room_${msgData.roomId}`); if (state === 1 && ioRoom) { ioRoom.emit('event:chats.delete', mid); @@ -27,5 +29,7 @@ module.exports = function (Messaging) { ioRoom.emit('event:chats.restore', messages[0]); plugins.hooks.fire('action:messaging.restore', { message: msgData }); } + + api.activitypub.update.privateNote({ uid }, { messageObj: msgData }); } };