mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	fix: #12990, local references via remote posts are not linkified properly, + tests for helper
This commit is contained in:
		| @@ -366,19 +366,29 @@ Helpers.remoteAnchorToLocalProfile = async (content) => { | |||||||
| 		return content; | 		return content; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Filter out urls that don't backreference to a remote id | 	const urlMap = new Map(); | ||||||
| 	const urlsArray = Array.from(urls); | 	const urlsArray = Array.from(urls); | ||||||
|  |  | ||||||
|  | 	// Local references | ||||||
|  | 	const localUrls = urlsArray.filter(url => url.startsWith(nconf.get('url'))); | ||||||
|  | 	await Promise.all(localUrls.map(async (url) => { | ||||||
|  | 		const { type, id } = await Helpers.resolveLocalId(url); | ||||||
|  | 		if (type === 'user') { | ||||||
|  | 			urlMap.set(url, id); | ||||||
|  | 		} // else if (type === 'category') { | ||||||
|  | 	})); | ||||||
|  |  | ||||||
|  | 	// Remote references | ||||||
| 	const [backrefs, urlAsIdExists] = await Promise.all([ | 	const [backrefs, urlAsIdExists] = await Promise.all([ | ||||||
| 		db.getObjectFields('remoteUrl:uid', urlsArray), | 		db.getObjectFields('remoteUrl:uid', urlsArray), | ||||||
| 		db.isSortedSetMembers('usersRemote:lastCrawled', urlsArray), | 		db.isSortedSetMembers('usersRemote:lastCrawled', urlsArray), | ||||||
| 	]); | 	]); | ||||||
|  |  | ||||||
| 	const urlMap = new Map(); |  | ||||||
| 	urlsArray.forEach((url, index) => { | 	urlsArray.forEach((url, index) => { | ||||||
| 		if (backrefs[url] || urlAsIdExists[index]) { | 		if (backrefs[url] || urlAsIdExists[index]) { | ||||||
| 			urlMap.set(url, backrefs[url] || url); | 			urlMap.set(url, backrefs[url] || url); | ||||||
| 		} | 		} | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	let slugs = await user.getUsersFields(Array.from(urlMap.values()), ['userslug']); | 	let slugs = await user.getUsersFields(Array.from(urlMap.values()), ['userslug']); | ||||||
| 	slugs = slugs.map(({ userslug }) => userslug); | 	slugs = slugs.map(({ userslug }) => userslug); | ||||||
| 	Array.from(urlMap.keys()).forEach((url, idx) => { | 	Array.from(urlMap.keys()).forEach((url, idx) => { | ||||||
|   | |||||||
| @@ -158,6 +158,58 @@ describe('ActivityPub integration', () => { | |||||||
| 				meta.config.maximumTitleLength = value; | 				meta.config.maximumTitleLength = value; | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  | 		describe.only('.remoteAnchorToLocalProfile', () => { | ||||||
|  | 			const uuid1 = utils.generateUUID(); | ||||||
|  | 			const id1 = `https://example.org/uuid/${uuid1}`; | ||||||
|  | 			const url1 = `https://example.org/test`; | ||||||
|  | 			const uuid2 = utils.generateUUID(); | ||||||
|  | 			const id2 = `https://example.org/uuid/${uuid2}`; | ||||||
|  | 			const localUsername = utils.generateUUID(); | ||||||
|  | 			const localSlug = slugify(localUsername); | ||||||
|  | 			let localUid; | ||||||
|  | 			before(async () => { | ||||||
|  | 				// Mock up a fake remote user | ||||||
|  | 				[,,,, localUid] = await Promise.all([ | ||||||
|  | 					db.setObjectField('remoteUrl:uid', url1, id1), | ||||||
|  | 					db.sortedSetAdd('usersRemote:lastCrawled', Date.now(), id2), | ||||||
|  | 					db.setObject(`userRemote:${id1}`, { uid: id1, userslug: uuid1 }), | ||||||
|  | 					db.setObject(`userRemote:${id2}`, { uid: id2, userslug: id2 }), | ||||||
|  | 					user.create({ username: localUsername }), | ||||||
|  | 				]); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			it('should convert an anchor pointing to a remote user URL', async () => { | ||||||
|  | 				const content = `adsf <a href="${url1}">@${uuid1}</a> asdf`; | ||||||
|  | 				const converted = await activitypub.helpers.remoteAnchorToLocalProfile(content); | ||||||
|  | 				assert.strictEqual(converted, `adsf <a href="/user/${uuid1}">@${uuid1}</a> asdf`); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			it('should convert an anchor pointing to a remote user id', async () => { | ||||||
|  | 				const content = `adsf <a href="${id2}">@${uuid2}</a> asdf`; | ||||||
|  | 				const converted = await activitypub.helpers.remoteAnchorToLocalProfile(content); | ||||||
|  | 				assert.strictEqual(converted, `adsf <a href="/user/${encodeURIComponent(id2)}">@${uuid2}</a> asdf`); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			it('should convert an anchor pointing to a local user URL', async () => { | ||||||
|  | 				const content = `adsf <a href="${nconf.get('url')}/user/${localSlug}">@${localSlug}</a> asdf`; | ||||||
|  | 				const converted = await activitypub.helpers.remoteAnchorToLocalProfile(content); | ||||||
|  | 				assert.strictEqual(converted, `adsf <a href="/user/${localSlug}">@${localSlug}</a> asdf`); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			it('should convert an anchor pointing to a local user URL', async () => { | ||||||
|  | 				const content = `adsf <a href="${nconf.get('url')}/uid/${localUid}">@${localSlug}</a> asdf`; | ||||||
|  | 				const converted = await activitypub.helpers.remoteAnchorToLocalProfile(content); | ||||||
|  | 				assert.strictEqual(converted, `adsf <a href="/user/${localSlug}">@${localSlug}</a> asdf`); | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			after(async () => { | ||||||
|  | 				await Promise.all([ | ||||||
|  | 					db.deleteObjectField('remoteUrl:uid', url1), | ||||||
|  | 					db.sortedSetRemove('usersRemote:lastCrawled', id2), | ||||||
|  | 				]); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	describe('ActivityPub screener middleware', () => { | 	describe('ActivityPub screener middleware', () => { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user