mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
test: updated activitypub test suite
This commit is contained in:
@@ -21,7 +21,7 @@ ActivityPub.getPublicKey = async (uid) => {
|
||||
};
|
||||
|
||||
async function generateKeys(uid) {
|
||||
winston.info(`[activitypub] Generating RSA key-pair for uid ${uid}`);
|
||||
winston.verbose(`[activitypub] Generating RSA key-pair for uid ${uid}`);
|
||||
const {
|
||||
publicKey,
|
||||
privateKey,
|
||||
|
||||
@@ -1,27 +1,187 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const nconf = require('nconf');
|
||||
const request = require('request-promise-native');
|
||||
|
||||
const db = require('./mocks/databasemock');
|
||||
const slugify = require('../src/slugify');
|
||||
const utils = require('../src/utils');
|
||||
|
||||
const user = require('../src/user');
|
||||
const privileges = require('../src/privileges');
|
||||
|
||||
describe('ActivityPub integration', () => {
|
||||
describe('WebFinger endpoint', () => {
|
||||
let uid;
|
||||
let slug;
|
||||
const { hostname } = nconf.get('url_parsed');
|
||||
|
||||
beforeEach(async () => {
|
||||
slug = slugify(utils.generateUUID().slice(0, 8));
|
||||
uid = await user.create({ username: slug });
|
||||
});
|
||||
|
||||
it('should return a 404 Not Found if no user exists by that username', async () => {
|
||||
const response = await request(`${nconf.get('url')}/register/complete`, {
|
||||
method: 'post',
|
||||
jar,
|
||||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:foobar@${hostname}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: false,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 404);
|
||||
});
|
||||
|
||||
it('should return a 400 Bad Request if the request is malformed', async () => {
|
||||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:foobar`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 400);
|
||||
});
|
||||
|
||||
it('should return 403 Forbidden if the calling user is not allowed to view the user list/profiles', async () => {
|
||||
await privileges.global.rescind(['groups:view:users'], 'guests');
|
||||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:${slug}@${hostname}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 403);
|
||||
await privileges.global.give(['groups:view:users'], 'guests');
|
||||
});
|
||||
|
||||
it('should return a valid WebFinger response otherwise', async () => {
|
||||
const response = await request(`${nconf.get('url')}/.well-known/webfinger?resource=acct:${slug}@${hostname}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 200);
|
||||
|
||||
['subject', 'aliases', 'links'].forEach((prop) => {
|
||||
assert(response.body.hasOwnProperty(prop));
|
||||
assert(response.body[prop]);
|
||||
});
|
||||
|
||||
assert.strictEqual(response.body.subject, `acct:${slug}@${hostname}`);
|
||||
|
||||
assert(Array.isArray(response.body.aliases));
|
||||
assert([`${nconf.get('url')}/uid/${uid}`, `${nconf.get('url')}/user/${slug}`].every(url => response.body.aliases.includes(url)));
|
||||
|
||||
assert(Array.isArray(response.body.links));
|
||||
});
|
||||
});
|
||||
|
||||
describe('ActivityPub screener middleware', () => {
|
||||
let uid;
|
||||
let slug;
|
||||
|
||||
beforeEach(async () => {
|
||||
slug = slugify(utils.generateUUID().slice(0, 8));
|
||||
uid = await user.create({ username: slug });
|
||||
});
|
||||
|
||||
it('should return regular user profile html if Accept header is not ActivityPub-related', async () => {
|
||||
const response = await request(`${nconf.get('url')}/user/${slug}`, {
|
||||
method: 'get',
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
headers: {
|
||||
'x-csrf-token': token,
|
||||
},
|
||||
form: {
|
||||
email: '',
|
||||
Accept: 'text/html',
|
||||
},
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 200);
|
||||
assert(response.body.startsWith('<!DOCTYPE html>'));
|
||||
});
|
||||
|
||||
it('should return the ActivityPub Actor JSON-LD payload if the correct Accept header is provided', async () => {
|
||||
const response = await request(`${nconf.get('url')}/user/${slug}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
headers: {
|
||||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
},
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 200);
|
||||
assert(response.body.hasOwnProperty('@context'));
|
||||
assert(response.body['@context'].includes('https://www.w3.org/ns/activitystreams'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Actor endpoint', () => {
|
||||
let uid;
|
||||
let slug;
|
||||
|
||||
beforeEach(async () => {
|
||||
slug = slugify(utils.generateUUID().slice(0, 8));
|
||||
uid = await user.create({ username: slug });
|
||||
});
|
||||
|
||||
it('should return a valid ActivityPub Actor JSON-LD payload', async () => {
|
||||
const response = await request(`${nconf.get('url')}/user/${slug}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
headers: {
|
||||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
},
|
||||
});
|
||||
|
||||
assert(response);
|
||||
assert.strictEqual(response.statusCode, 200);
|
||||
assert(response.body.hasOwnProperty('@context'));
|
||||
assert(response.body['@context'].includes('https://www.w3.org/ns/activitystreams'));
|
||||
|
||||
['id', 'url', 'followers', 'following', 'inbox', 'outbox'].forEach((prop) => {
|
||||
assert(response.body.hasOwnProperty(prop));
|
||||
assert(response.body[prop]);
|
||||
});
|
||||
|
||||
assert.strictEqual(response.body.id, response.body.url);
|
||||
assert.strictEqual(response.body.type, 'Person');
|
||||
});
|
||||
|
||||
it('should contain a `publicKey` property with a public key', async () => {
|
||||
const response = await request(`${nconf.get('url')}/user/${slug}`, {
|
||||
method: 'get',
|
||||
json: true,
|
||||
followRedirect: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true,
|
||||
headers: {
|
||||
Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
},
|
||||
});
|
||||
|
||||
assert(response.body.hasOwnProperty('publicKey'));
|
||||
assert(['id', 'owner', 'publicKeyPem'].every(prop => response.body.publicKey.hasOwnProperty(prop)));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user