mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	feat: update activitypub helper resolveLocalUid to accept both webfinger name and full URL as input
This commit is contained in:
		| @@ -4,6 +4,7 @@ const request = require('request-promise-native'); | ||||
| const { generateKeyPairSync } = require('crypto'); | ||||
| const winston = require('winston'); | ||||
| const nconf = require('nconf'); | ||||
| const validator = require('validator'); | ||||
|  | ||||
| const db = require('../database'); | ||||
| const ttl = require('../cache/ttl'); | ||||
| @@ -68,10 +69,26 @@ Helpers.generateKeys = async (uid) => { | ||||
| 	return { publicKey, privateKey }; | ||||
| }; | ||||
|  | ||||
| Helpers.resolveLocalUid = async (id) => { | ||||
| 	const [slug, host] = id.split('@'); | ||||
| Helpers.resolveLocalUid = async (input) => { | ||||
| 	let slug; | ||||
|  | ||||
| 	if (id.indexOf('@') === -1 || host !== nconf.get('url_parsed').host) { | ||||
| 	if (validator.isURL(input, { | ||||
| 		require_protocol: true, | ||||
| 		require_host: true, | ||||
| 		require_tld: false, | ||||
| 		protocols: ['https'], | ||||
| 		require_valid_protocol: true, | ||||
| 	})) { | ||||
| 		const { host, pathname } = new URL(input); | ||||
|  | ||||
| 		if (host === nconf.get('url_parsed').host) { | ||||
| 			slug = pathname.split('/').filter(Boolean)[1]; | ||||
| 		} else { | ||||
| 			throw new Error('[[activitypub:invalid-id]]'); | ||||
| 		} | ||||
| 	} else if (input.indexOf('@') !== -1) { // Webfinger | ||||
| 		([slug] = input.replace(/^acct:/, '').split('@')); | ||||
| 	} else { | ||||
| 		throw new Error('[[activitypub:invalid-id]]'); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -100,6 +100,53 @@ describe('ActivityPub integration', () => { | ||||
| 		}); | ||||
| 	}); | ||||
|  | ||||
| 	describe.only('Helpers', () => { | ||||
| 		describe('.query()', () => { | ||||
|  | ||||
| 		}); | ||||
|  | ||||
| 		describe('.generateKeys()', () => { | ||||
|  | ||||
| 		}); | ||||
|  | ||||
| 		describe('.resolveLocalUid()', () => { | ||||
| 			let uid; | ||||
| 			let slug; | ||||
|  | ||||
| 			beforeEach(async () => { | ||||
| 				slug = slugify(utils.generateUUID().slice(0, 8)); | ||||
| 				uid = await user.create({ username: slug }); | ||||
| 			}); | ||||
|  | ||||
| 			it('should throw when an invalid input is passed in', async () => { | ||||
| 				await assert.rejects( | ||||
| 					activitypub.helpers.resolveLocalUid('ncl28h3qwhoiclwnevoinw3u'), | ||||
| 					{ message: '[[activitypub:invalid-id]]' } | ||||
| 				); | ||||
| 			}); | ||||
|  | ||||
| 			it('should return null when valid input is passed but does not resolve', async () => { | ||||
| 				const uid = await activitypub.helpers.resolveLocalUid(`acct:foobar@${nconf.get('url_parsed').host}`); | ||||
| 				assert.strictEqual(uid, null); | ||||
| 			}); | ||||
|  | ||||
| 			it('should resolve to a local uid when given a webfinger-style string', async () => { | ||||
| 				const found = await activitypub.helpers.resolveLocalUid(`acct:${slug}@${nconf.get('url_parsed').host}`); | ||||
| 				assert.strictEqual(found, uid); | ||||
| 			}); | ||||
|  | ||||
| 			it('should resolve even without the "acct:" prefix', async () => { | ||||
| 				const found = await activitypub.helpers.resolveLocalUid(`${slug}@${nconf.get('url_parsed').host}`); | ||||
| 				assert.strictEqual(found, uid); | ||||
| 			}); | ||||
|  | ||||
| 			it('should resolve when passed a full URL', async () => { | ||||
| 				const found = await activitypub.helpers.resolveLocalUid(`${nconf.get('url')}/user/${slug}`); | ||||
| 				assert.strictEqual(found, uid); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
|  | ||||
| 	describe('ActivityPub screener middleware', () => { | ||||
| 		let uid; | ||||
| 		let slug; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user