mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-31 19:15:58 +01:00
refactor: update ActivityPub.get and all methods calling it to take a uid so that requests can be signed
This commit is contained in:
@@ -10,16 +10,16 @@ const inbox = module.exports;
|
||||
|
||||
inbox.follow = async (req) => {
|
||||
// Sanity checks
|
||||
const from = await activitypub.getActor(req.body.actor);
|
||||
if (!from) {
|
||||
throw new Error('[[error:invalid-uid]]'); // should probably be AP specific
|
||||
}
|
||||
|
||||
const localUid = await helpers.resolveLocalUid(req.body.object);
|
||||
if (!localUid) {
|
||||
throw new Error('[[error:invalid-uid]]');
|
||||
}
|
||||
|
||||
const from = await activitypub.getActor(localUid, req.body.actor);
|
||||
if (!from) {
|
||||
throw new Error('[[error:invalid-uid]]'); // should probably be AP specific
|
||||
}
|
||||
|
||||
const isFollowed = await inbox.isFollowed(from.id, localUid);
|
||||
if (isFollowed) {
|
||||
// No additional parsing required
|
||||
@@ -51,15 +51,14 @@ inbox.accept = async (req) => {
|
||||
let { actor, object } = req.body;
|
||||
const { type } = object;
|
||||
|
||||
actor = await activitypub.getActor(actor);
|
||||
|
||||
if (type === 'Follow') {
|
||||
// todo: should check that actor and object.actor are the same person?
|
||||
const uid = await helpers.resolveLocalUid(object.actor);
|
||||
if (!uid) {
|
||||
throw new Error('[[error:invalid-uid]]');
|
||||
}
|
||||
|
||||
actor = await activitypub.getActor(uid, actor);
|
||||
|
||||
if (type === 'Follow') {
|
||||
const now = Date.now();
|
||||
await Promise.all([
|
||||
db.sortedSetAdd(`followingRemote:${uid}`, now, actor.id),
|
||||
@@ -72,15 +71,14 @@ inbox.undo = async (req) => {
|
||||
let { actor, object } = req.body;
|
||||
const { type } = object;
|
||||
|
||||
actor = await activitypub.getActor(actor);
|
||||
|
||||
if (type === 'Follow') {
|
||||
// todo: should check that actor and object.actor are the same person?
|
||||
const uid = await helpers.resolveLocalUid(object.object);
|
||||
if (!uid) {
|
||||
throw new Error('[[error:invalid-uid]]');
|
||||
}
|
||||
|
||||
actor = await activitypub.getActor(uid, actor);
|
||||
|
||||
if (type === 'Follow') {
|
||||
await Promise.all([
|
||||
db.sortedSetRemove(`followingRemote:${uid}`, actor.id),
|
||||
db.decrObjectField(`user:${uid}`, 'followingRemoteCount'),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const nconf = require('nconf');
|
||||
const winston = require('winston');
|
||||
const { createHash, createSign, createVerify } = require('crypto');
|
||||
|
||||
const request = require('../request');
|
||||
@@ -14,7 +15,7 @@ const ActivityPub = module.exports;
|
||||
ActivityPub.helpers = require('./helpers');
|
||||
ActivityPub.inbox = require('./inbox');
|
||||
|
||||
ActivityPub.getActor = async (input) => {
|
||||
ActivityPub.getActor = async (uid, input) => {
|
||||
// Can be a webfinger id, uri, or object, handle as appropriate
|
||||
let uri;
|
||||
if (ActivityPub.helpers.isUri(input)) {
|
||||
@@ -33,7 +34,7 @@ ActivityPub.getActor = async (input) => {
|
||||
return actorCache.get(uri);
|
||||
}
|
||||
|
||||
const actor = await ActivityPub.get(uri);
|
||||
const actor = await ActivityPub.get(uid, uri);
|
||||
|
||||
// todo: remove this after ActivityPub.get is updated to handle errors more effectively
|
||||
if (typeof actor === 'string' || actor.hasOwnProperty('error')) {
|
||||
@@ -41,8 +42,8 @@ ActivityPub.getActor = async (input) => {
|
||||
}
|
||||
|
||||
const [followers, following] = await Promise.all([
|
||||
actor.followers ? ActivityPub.get(actor.followers) : { totalItems: 0 },
|
||||
actor.following ? ActivityPub.get(actor.following) : { totalItems: 0 },
|
||||
actor.followers ? ActivityPub.get(uid, actor.followers) : { totalItems: 0 },
|
||||
actor.following ? ActivityPub.get(uid, actor.following) : { totalItems: 0 },
|
||||
]);
|
||||
|
||||
actor.hostname = new URL(uri).hostname;
|
||||
@@ -64,7 +65,7 @@ ActivityPub.mockProfile = async (actors, callerUid = 0) => {
|
||||
const profiles = (await Promise.all(actors.map(async (actor) => {
|
||||
// convert uri to actor object
|
||||
if (typeof actor === 'string' && ActivityPub.helpers.isUri(actor)) {
|
||||
actor = await ActivityPub.getActor(actor);
|
||||
actor = await ActivityPub.getActor(callerUid, actor);
|
||||
}
|
||||
|
||||
if (!actor) {
|
||||
@@ -111,8 +112,8 @@ ActivityPub.mockProfile = async (actors, callerUid = 0) => {
|
||||
return single ? profiles.pop() : profiles;
|
||||
};
|
||||
|
||||
ActivityPub.resolveInboxes = async ids => await Promise.all(ids.map(async (id) => {
|
||||
const actor = await ActivityPub.getActor(id);
|
||||
ActivityPub.resolveInboxes = async (uid, ids) => await Promise.all(ids.map(async (id) => {
|
||||
const actor = await ActivityPub.getActor(uid, id);
|
||||
return actor.inbox;
|
||||
}));
|
||||
|
||||
@@ -222,13 +223,22 @@ ActivityPub.verify = async (req) => {
|
||||
}
|
||||
};
|
||||
|
||||
ActivityPub.get = async (uri) => {
|
||||
const { body } = await request.get(uri, {
|
||||
ActivityPub.get = async (uid, uri) => {
|
||||
const headers = uid > 0 ? await ActivityPub.sign(uid, uri) : {};
|
||||
const { response, body } = await request.get(uri, {
|
||||
headers: {
|
||||
...headers,
|
||||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
},
|
||||
});
|
||||
|
||||
if (!String(response.statusCode).startsWith('2')) {
|
||||
winston.error(`[activitypub/get] Received ${response.statusCode} when querying ${uri}`);
|
||||
if (body.hasOwnProperty('error')) {
|
||||
winston.error(`[activitypub/get] Error received: ${body.error}`);
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
@@ -238,7 +248,7 @@ ActivityPub.send = async (uid, targets, payload) => {
|
||||
}
|
||||
|
||||
const userslug = await user.getUserField(uid, 'userslug');
|
||||
const inboxes = await ActivityPub.resolveInboxes(targets);
|
||||
const inboxes = await ActivityPub.resolveInboxes(uid, targets);
|
||||
|
||||
payload = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
|
||||
@@ -17,7 +17,7 @@ const user = require('../user');
|
||||
const activitypubApi = module.exports;
|
||||
|
||||
activitypubApi.follow = async (caller, { actorId } = {}) => {
|
||||
const object = await activitypub.getActor(actorId);
|
||||
const object = await activitypub.getActor(caller.uid, actorId);
|
||||
if (!object) {
|
||||
throw new Error('[[error:invalid-uid]]'); // should be activitypub-specific
|
||||
}
|
||||
@@ -29,7 +29,7 @@ activitypubApi.follow = async (caller, { actorId } = {}) => {
|
||||
};
|
||||
|
||||
activitypubApi.unfollow = async (caller, { actorId }) => {
|
||||
const object = await activitypub.getActor(actorId);
|
||||
const object = await activitypub.getActor(caller.uid, actorId);
|
||||
const userslug = await user.getUserField(caller.uid, 'userslug');
|
||||
if (!object) {
|
||||
throw new Error('[[error:invalid-uid]]'); // should be activitypub-specific
|
||||
|
||||
Reference in New Issue
Block a user