mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
fix: actor assertion logic to ignore loopback urls
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const winston = require('winston');
|
||||
const nconf = require('nconf');
|
||||
|
||||
const db = require('../database');
|
||||
const user = require('../user');
|
||||
@@ -23,17 +24,27 @@ Actors.assert = async (ids, options = {}) => {
|
||||
ids = ids.filter(id => !utils.isNumber(id) && !failedWebfingerCache.has(id));
|
||||
|
||||
// Translate webfinger handles to uris
|
||||
ids = await Promise.all(ids.map(async (id) => {
|
||||
ids = (await Promise.all(ids.map(async (id) => {
|
||||
const originalId = id;
|
||||
if (id.includes('@')) {
|
||||
const host = id.split('@')[1];
|
||||
if (host === nconf.get('url_parsed').host) { // do not assert loopback ids
|
||||
return null;
|
||||
}
|
||||
|
||||
({ actorUri: id } = await activitypub.helpers.query(id));
|
||||
}
|
||||
if (!id) {
|
||||
failedWebfingerCache.set(originalId, true);
|
||||
}
|
||||
return id;
|
||||
}));
|
||||
}))).filter(Boolean);
|
||||
|
||||
// Filter out loopback uris
|
||||
ids = ids.filter((uri) => {
|
||||
const { host } = new URL(uri);
|
||||
return host !== nconf.get('url_parsed').host;
|
||||
});
|
||||
|
||||
// Filter out existing
|
||||
if (!options.update) {
|
||||
|
||||
@@ -564,46 +564,77 @@ describe('ActivityPub integration', () => {
|
||||
});
|
||||
|
||||
describe('Actor asserton', () => {
|
||||
let uid;
|
||||
let actorUri;
|
||||
describe('happy path', () => {
|
||||
let uid;
|
||||
let actorUri;
|
||||
|
||||
before(async () => {
|
||||
uid = utils.generateUUID().slice(0, 8);
|
||||
actorUri = `https://example.org/user/${uid}`;
|
||||
activitypub._cache.set(`0;${actorUri}`, {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: actorUri,
|
||||
url: actorUri,
|
||||
before(async () => {
|
||||
uid = utils.generateUUID().slice(0, 8);
|
||||
actorUri = `https://example.org/user/${uid}`;
|
||||
activitypub._cache.set(`0;${actorUri}`, {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: actorUri,
|
||||
url: actorUri,
|
||||
|
||||
type: 'Person',
|
||||
name: 'example',
|
||||
preferredUsername: 'example',
|
||||
type: 'Person',
|
||||
name: 'example',
|
||||
preferredUsername: 'example',
|
||||
|
||||
publicKey: {
|
||||
id: `${actorUri}#key`,
|
||||
owner: actorUri,
|
||||
publicKeyPem: 'somekey',
|
||||
},
|
||||
publicKey: {
|
||||
id: `${actorUri}#key`,
|
||||
owner: actorUri,
|
||||
publicKeyPem: 'somekey',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return true if successfully asserted', async () => {
|
||||
const result = await activitypub.actors.assert([actorUri]);
|
||||
assert(result);
|
||||
});
|
||||
|
||||
it('should contain a representation of that remote user in the database', async () => {
|
||||
const exists = await db.exists(`userRemote:${actorUri}`);
|
||||
assert(exists);
|
||||
|
||||
const userData = await user.getUserData(actorUri);
|
||||
assert(userData);
|
||||
assert.strictEqual(userData.uid, actorUri);
|
||||
});
|
||||
|
||||
it('should save the actor\'s publicly accessible URL in the hash as well', async () => {
|
||||
const url = await user.getUserField(actorUri, 'url');
|
||||
assert.strictEqual(url, actorUri);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return true if successfully asserted', async () => {
|
||||
const result = await activitypub.actors.assert([actorUri]);
|
||||
assert(result);
|
||||
});
|
||||
describe('edge case: loopback handles and uris', () => {
|
||||
let uid;
|
||||
const userslug = utils.generateUUID().slice(0, 8);
|
||||
before(async () => {
|
||||
uid = await user.create({ username: userslug });
|
||||
});
|
||||
|
||||
it('should contain a representation of that remote user in the database', async () => {
|
||||
const exists = await db.exists(`userRemote:${actorUri}`);
|
||||
assert(exists);
|
||||
it('should return true but not actually assert the handle into the database', async () => {
|
||||
const handle = `${userslug}@${nconf.get('url_parsed').host}`;
|
||||
const result = await activitypub.actors.assert([handle]);
|
||||
assert(result);
|
||||
|
||||
const userData = await user.getUserData(actorUri);
|
||||
assert(userData);
|
||||
assert.strictEqual(userData.uid, actorUri);
|
||||
});
|
||||
const handleExists = await db.isObjectField('handle:uid', handle);
|
||||
assert.strictEqual(handleExists, false);
|
||||
|
||||
it('should save the actor\'s publicly accessible URL in the hash as well', async () => {
|
||||
const url = await user.getUserField(actorUri, 'url');
|
||||
assert.strictEqual(url, actorUri);
|
||||
const userRemoteHashExists = await db.exists(`userRemote:${nconf.get('url')}/uid/${uid}`);
|
||||
assert.strictEqual(userRemoteHashExists, false);
|
||||
});
|
||||
|
||||
it('should return true but not actually assert the uri into the database', async () => {
|
||||
const uri = `${nconf.get('url')}/uid/${uid}`;
|
||||
const result = await activitypub.actors.assert([uri]);
|
||||
assert(result);
|
||||
|
||||
const userRemoteHashExists = await db.exists(`userRemote:${uri}`);
|
||||
assert.strictEqual(userRemoteHashExists, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user