refactor: resolveId method, add hostname verification

This commit is contained in:
Julian Lam
2024-02-21 10:58:20 -05:00
parent 42a0924137
commit ed4ccbfccc
4 changed files with 63 additions and 10 deletions

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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}`);

View File

@@ -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;