mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
@@ -264,7 +264,7 @@ Helpers.resolveObjects = async (ids) => {
|
||||
if (!post) {
|
||||
throw new Error('[[error:activitypub.invalid-id]]');
|
||||
}
|
||||
return activitypub.mocks.note(post);
|
||||
return activitypub.mocks.notes.public(post);
|
||||
}
|
||||
case 'category': {
|
||||
if (!await categories.exists(resolvedId)) {
|
||||
|
||||
@@ -10,6 +10,7 @@ const user = require('../user');
|
||||
const categories = require('../categories');
|
||||
const posts = require('../posts');
|
||||
const topics = require('../topics');
|
||||
const messaging = require('../messaging');
|
||||
const plugins = require('../plugins');
|
||||
const slugify = require('../slugify');
|
||||
const translator = require('../translator');
|
||||
@@ -271,7 +272,9 @@ Mocks.actors.category = async (cid) => {
|
||||
};
|
||||
};
|
||||
|
||||
Mocks.note = async (post) => {
|
||||
Mocks.notes = {};
|
||||
|
||||
Mocks.notes.public = async (post) => {
|
||||
const id = `${nconf.get('url')}/post/${post.pid}`;
|
||||
|
||||
// Return a tombstone for a deleted post
|
||||
@@ -434,7 +437,6 @@ Mocks.note = async (post) => {
|
||||
attributedTo: `${nconf.get('url')}/uid/${post.user.uid}`,
|
||||
context: `${nconf.get('url')}/topic/${post.topic.tid}`,
|
||||
audience: `${nconf.get('url')}/category/${post.category.cid}`,
|
||||
sensitive: false, // todo
|
||||
summary: null,
|
||||
name,
|
||||
content: post.content,
|
||||
@@ -447,6 +449,66 @@ Mocks.note = async (post) => {
|
||||
return object;
|
||||
};
|
||||
|
||||
Mocks.notes.private = async ({ messageObj }) => {
|
||||
// todo: deleted messages
|
||||
let uids = await messaging.getUidsInRoom(messageObj.roomId, 0, -1);
|
||||
const remoteUids = uids.filter(uid => !utils.isNumber(uid));
|
||||
uids = uids.map(uid => (utils.isNumber(uid) ? `${nconf.get('url')}/uid/${uid}` : uid));
|
||||
const id = `${nconf.get('url')}/message/${messageObj.mid}`;
|
||||
const to = new Set(uids);
|
||||
const published = messageObj.timestampISO;
|
||||
const updated = messageObj.edited ? messageObj.editedISO : undefined;
|
||||
const content = await messaging.parse(messageObj.content, messageObj.fromuid, 0, messageObj.roomId, false);
|
||||
|
||||
let source;
|
||||
const markdownEnabled = await plugins.isActive('nodebb-plugin-markdown');
|
||||
if (markdownEnabled) {
|
||||
source = {
|
||||
content: messageObj.content,
|
||||
mediaType: 'text/markdown',
|
||||
};
|
||||
}
|
||||
|
||||
const mentions = await user.getUsersFields(remoteUids, ['uid', 'userslug']);
|
||||
const tag = [];
|
||||
tag.push(...mentions.map(({ uid, userslug }) => ({
|
||||
type: 'Mention',
|
||||
href: uid,
|
||||
name: userslug,
|
||||
})));
|
||||
|
||||
let inReplyTo;
|
||||
if (messageObj.toMid) {
|
||||
inReplyTo = utils.isNumber(messageObj.toMid) ?
|
||||
`${nconf.get('url')}/api/v3/chats/${messageObj.roomId}/messages/${messageObj.toMid}` :
|
||||
messageObj.toMid;
|
||||
}
|
||||
|
||||
const object = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id,
|
||||
type: 'Note',
|
||||
to: Array.from(to),
|
||||
cc: [],
|
||||
inReplyTo,
|
||||
published,
|
||||
updated,
|
||||
url: id,
|
||||
attributedTo: `${nconf.get('url')}/uid/${messageObj.fromuid}`,
|
||||
// context: `${nconf.get('url')}/topic/${post.topic.tid}`,
|
||||
// audience: `${nconf.get('url')}/category/${post.category.cid}`,
|
||||
summary: null,
|
||||
// name,
|
||||
content: content,
|
||||
source,
|
||||
tag,
|
||||
// attachment: [], // todo
|
||||
// replies: `${id}/replies`, // todo
|
||||
};
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
Mocks.tombstone = async properties => ({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
type: 'Tombstone',
|
||||
|
||||
@@ -18,6 +18,7 @@ const privileges = require('../privileges');
|
||||
const activitypub = require('../activitypub');
|
||||
const posts = require('../posts');
|
||||
const topics = require('../topics');
|
||||
const messaging = require('../messaging');
|
||||
const utils = require('../utils');
|
||||
|
||||
const activitypubApi = module.exports;
|
||||
@@ -180,7 +181,7 @@ activitypubApi.create.note = enabledCheck(async (caller, { pid, post }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const object = await activitypub.mocks.note(post);
|
||||
const object = await activitypub.mocks.notes.public(post);
|
||||
const { to, cc, targets } = await buildRecipients(object, { pid, uid: post.user.uid });
|
||||
const { cid } = post.category;
|
||||
const followers = await activitypub.notes.getCategoryFollowers(cid);
|
||||
@@ -211,6 +212,21 @@ activitypubApi.create.note = enabledCheck(async (caller, { pid, post }) => {
|
||||
}
|
||||
});
|
||||
|
||||
activitypubApi.create.privateNote = enabledCheck(async (caller, { mid, messageObj }) => {
|
||||
if (!messageObj) {
|
||||
messageObj = await messaging.getMessageFields(mid, []);
|
||||
if (!messageObj) {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
}
|
||||
}
|
||||
const { roomId } = messageObj;
|
||||
let targets = await messaging.getUidsInRoom(roomId, 0, -1);
|
||||
targets = targets.filter(uid => !utils.isNumber(uid)); // remote uids only
|
||||
|
||||
const payload = await activitypub.mocks.notes.private({ messageObj });
|
||||
await activitypub.send('uid', messageObj.fromuid, targets, payload);
|
||||
});
|
||||
|
||||
activitypubApi.update = {};
|
||||
|
||||
activitypubApi.update.profile = enabledCheck(async (caller, { uid }) => {
|
||||
@@ -249,7 +265,7 @@ activitypubApi.update.note = enabledCheck(async (caller, { post }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const object = await activitypub.mocks.note(post);
|
||||
const object = await activitypub.mocks.notes.public(post);
|
||||
const { to, cc, targets } = await buildRecipients(object, { pid: post.pid, uid: post.user.uid });
|
||||
|
||||
const allowed = await privileges.posts.can('topics:read', post.pid, activitypub._constants.uid);
|
||||
@@ -281,7 +297,7 @@ activitypubApi.delete.note = enabledCheck(async (caller, { pid }) => {
|
||||
|
||||
const id = `${nconf.get('url')}/post/${pid}`;
|
||||
const post = (await posts.getPostSummaryByPids([pid], caller.uid, { stripTags: false })).pop();
|
||||
const object = await activitypub.mocks.note(post);
|
||||
const object = await activitypub.mocks.notes.public(post);
|
||||
const { to, cc, targets } = await buildRecipients(object, { pid, uid: post.user.uid });
|
||||
|
||||
const allowed = await privileges.posts.can('topics:read', pid, activitypub._constants.uid);
|
||||
|
||||
@@ -9,6 +9,7 @@ const privileges = require('../../privileges');
|
||||
const posts = require('../../posts');
|
||||
const topics = require('../../topics');
|
||||
const categories = require('../../categories');
|
||||
const messaging = require('../../messaging');
|
||||
const activitypub = require('../../activitypub');
|
||||
const utils = require('../../utils');
|
||||
|
||||
@@ -75,7 +76,7 @@ Actors.note = async function (req, res) {
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
|
||||
const payload = await activitypub.mocks.note(post);
|
||||
const payload = await activitypub.mocks.notes.public(post);
|
||||
res.status(200).json(payload);
|
||||
};
|
||||
|
||||
@@ -184,3 +185,14 @@ Actors.category = async function (req, res, next) {
|
||||
const payload = await activitypub.mocks.actors.category(req.params.cid);
|
||||
res.status(200).json(payload);
|
||||
};
|
||||
|
||||
Actors.message = async function (req, res, next) {
|
||||
// Handle requests for remote content
|
||||
if (!utils.isNumber(req.params.mid)) {
|
||||
return res.set('Location', req.params.mid).sendStatus(308);
|
||||
}
|
||||
|
||||
const messageObj = await messaging.getMessageFields(req.params.mid, []);
|
||||
const payload = await activitypub.mocks.notes.private({ messageObj });
|
||||
res.status(200).json(payload);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ const db = require('../database');
|
||||
const notifications = require('../notifications');
|
||||
const user = require('../user');
|
||||
const io = require('../socket.io');
|
||||
const api = require('../api');
|
||||
const plugins = require('../plugins');
|
||||
const utils = require('../utils');
|
||||
|
||||
@@ -79,8 +80,10 @@ module.exports = function (Messaging) {
|
||||
}
|
||||
|
||||
try {
|
||||
await sendNotification(fromUid, roomId, messageObj);
|
||||
// await federate(fromUid, roomId, messageObj);
|
||||
await Promise.all([
|
||||
sendNotification(fromUid, roomId, messageObj),
|
||||
!isPublic ? api.activitypub.create.privateNote({ uid: fromUid }, { messageObj }) : null,
|
||||
]);
|
||||
} catch (err) {
|
||||
winston.error(`[messaging/notifications] Unabled to send notification\n${err.stack}`);
|
||||
}
|
||||
@@ -142,7 +145,4 @@ module.exports = function (Messaging) {
|
||||
await notifications.push(notification, uidsToNotify);
|
||||
}
|
||||
}
|
||||
|
||||
// async function federate(fromUid, roomId, messageObj) {
|
||||
// }
|
||||
};
|
||||
|
||||
@@ -45,4 +45,6 @@ module.exports = function (app, middleware, controllers) {
|
||||
app.post('/category/:cid/inbox', [...inboxMiddlewares, middleware.assert.category, ...inboxMiddlewares], controllers.activitypub.postInbox);
|
||||
app.get('/category/:cid/outbox', [...middlewares, middleware.assert.category], controllers.activitypub.getCategoryOutbox);
|
||||
app.post('/category/:cid/outbox', [...middlewares, middleware.assert.category], controllers.activitypub.postOutbox);
|
||||
|
||||
app.get('/message/:mid', [...middlewares, middleware.assert.message], controllers.activitypub.actors.message);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user