mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-27 17:16:14 +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