mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 09:06:15 +01:00
refactor: resolveId method, add hostname verification
This commit is contained in:
@@ -93,10 +93,12 @@ inbox.announce = async (req) => {
|
|||||||
tid = await posts.getPostField(id, 'tid');
|
tid = await posts.getPostField(id, 'tid');
|
||||||
} else {
|
} else {
|
||||||
pid = object;
|
pid = object;
|
||||||
([pid, tid] = await Promise.all([
|
pid = await activitypub.resolveId(0, pid); // in case wrong id is passed-in; unlikely, but still.
|
||||||
activitypub.notes.resolveId(0, pid),
|
if (!pid) {
|
||||||
activitypub.notes.assertTopic(0, pid),
|
return;
|
||||||
]));
|
}
|
||||||
|
|
||||||
|
tid = await activitypub.notes.assertTopic(0, pid);
|
||||||
if (!tid) {
|
if (!tid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,23 @@ ActivityPub.mocks = require('./mocks');
|
|||||||
ActivityPub.notes = require('./notes');
|
ActivityPub.notes = require('./notes');
|
||||||
ActivityPub.actors = require('./actors');
|
ActivityPub.actors = require('./actors');
|
||||||
|
|
||||||
|
ActivityPub.resolveId = async (uid, id) => {
|
||||||
|
try {
|
||||||
|
const query = new URL(id);
|
||||||
|
({ id } = await ActivityPub.get('uid', uid, id));
|
||||||
|
const response = new URL(id);
|
||||||
|
|
||||||
|
if (query.host !== response.host) {
|
||||||
|
winston.warn(`[activitypub/resolveId] id resolution domain mismatch: ${query.href} != ${response.href}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ActivityPub.resolveInboxes = async (ids) => {
|
ActivityPub.resolveInboxes = async (ids) => {
|
||||||
const inboxes = new Set();
|
const inboxes = new Set();
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,6 @@ const slugify = require('../slugify');
|
|||||||
const activitypub = module.parent.exports;
|
const activitypub = module.parent.exports;
|
||||||
const Notes = module.exports;
|
const Notes = module.exports;
|
||||||
|
|
||||||
Notes.resolveId = async (uid, id) => {
|
|
||||||
({ id } = await activitypub.get('uid', uid, id));
|
|
||||||
return id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo: when asserted, notes aren't added to a global sorted set
|
// todo: when asserted, notes aren't added to a global sorted set
|
||||||
// also, db.exists call is probably expensive
|
// also, db.exists call is probably expensive
|
||||||
Notes.assert = async (uid, input, options = {}) => {
|
Notes.assert = async (uid, input, options = {}) => {
|
||||||
@@ -28,8 +23,13 @@ Notes.assert = async (uid, input, options = {}) => {
|
|||||||
await Promise.all(input.map(async (item) => {
|
await Promise.all(input.map(async (item) => {
|
||||||
let id = activitypub.helpers.isUri(item) ? item : item.pid;
|
let id = activitypub.helpers.isUri(item) ? item : item.pid;
|
||||||
if (activitypub.helpers.isUri(id)) {
|
if (activitypub.helpers.isUri(id)) {
|
||||||
id = await Notes.resolveId(uid, id);
|
id = await activitypub.resolveId(uid, id);
|
||||||
|
if (!id) {
|
||||||
|
winston.warn(`[activitypub/notes.assert] Not asserting ${id}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = `post:${id}`;
|
const key = `post:${id}`;
|
||||||
const exists = await db.exists(key);
|
const exists = await db.exists(key);
|
||||||
winston.verbose(`[activitypub/notes.assert] Asserting note id ${id}`);
|
winston.verbose(`[activitypub/notes.assert] Asserting note id ${id}`);
|
||||||
|
|||||||
@@ -88,6 +88,40 @@ describe('ActivityPub integration', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe.only('.resolveId()', () => {
|
||||||
|
let url;
|
||||||
|
let resolved;
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
url = 'https://example.org/topic/foobar';
|
||||||
|
resolved = 'https://example.org/tid/1234';
|
||||||
|
activitypub._cache.set(`0;${url}`, {
|
||||||
|
id: resolved,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the resolved id when queried', async () => {
|
||||||
|
const id = await activitypub.resolveId(0, url);
|
||||||
|
assert.strictEqual(id, resolved);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when the query fails', async () => {
|
||||||
|
const id = await activitypub.resolveId(0, 'https://example.org/sdlknsdfnsd');
|
||||||
|
assert.strictEqual(id, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when the resolved host does not match the queried host', async () => {
|
||||||
|
const url = 'https://example.com/topic/foobar'; // .com attempting to overwrite .org data
|
||||||
|
const resolved = 'https://example.org/tid/1234'; // .org
|
||||||
|
activitypub._cache.set(`0;${url}`, {
|
||||||
|
id: resolved,
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = await activitypub.resolveId(0, url);
|
||||||
|
assert.strictEqual(id, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('.resolveLocalId()', () => {
|
describe('.resolveLocalId()', () => {
|
||||||
let uid;
|
let uid;
|
||||||
let slug;
|
let slug;
|
||||||
|
|||||||
Reference in New Issue
Block a user