mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +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');
|
||||
} else {
|
||||
pid = object;
|
||||
([pid, tid] = await Promise.all([
|
||||
activitypub.notes.resolveId(0, pid),
|
||||
activitypub.notes.assertTopic(0, pid),
|
||||
]));
|
||||
pid = await activitypub.resolveId(0, pid); // in case wrong id is passed-in; unlikely, but still.
|
||||
if (!pid) {
|
||||
return;
|
||||
}
|
||||
|
||||
tid = await activitypub.notes.assertTopic(0, pid);
|
||||
if (!tid) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,23 @@ ActivityPub.mocks = require('./mocks');
|
||||
ActivityPub.notes = require('./notes');
|
||||
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) => {
|
||||
const inboxes = new Set();
|
||||
|
||||
|
||||
@@ -14,11 +14,6 @@ const slugify = require('../slugify');
|
||||
const activitypub = module.parent.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
|
||||
// also, db.exists call is probably expensive
|
||||
Notes.assert = async (uid, input, options = {}) => {
|
||||
@@ -28,8 +23,13 @@ Notes.assert = async (uid, input, options = {}) => {
|
||||
await Promise.all(input.map(async (item) => {
|
||||
let id = activitypub.helpers.isUri(item) ? item : item.pid;
|
||||
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 exists = await db.exists(key);
|
||||
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()', () => {
|
||||
let uid;
|
||||
let slug;
|
||||
|
||||
Reference in New Issue
Block a user