mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-17 11:11:04 +01:00
refactor: split activitypub tests to subfolder files
This commit is contained in:
143
test/activitypub/signatures.js
Normal file
143
test/activitypub/signatures.js
Normal file
@@ -0,0 +1,143 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const nconf = require('nconf');
|
||||
const { createHash } = require('crypto');
|
||||
|
||||
const user = require('../../src/user');
|
||||
const utils = require('../../src/utils');
|
||||
const db = require('../../src/database');
|
||||
const activitypub = require('../../src/activitypub');
|
||||
|
||||
describe('http signature signing and verification', () => {
|
||||
describe('.sign()', () => {
|
||||
let uid;
|
||||
|
||||
before(async () => {
|
||||
uid = await user.create({ username: utils.generateUUID().slice(0, 10) });
|
||||
});
|
||||
|
||||
it('should create a key-pair for a user if the user does not have one already', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
await activitypub.sign(keyData, endpoint);
|
||||
const { publicKey, privateKey } = await db.getObject(`uid:${uid}:keys`);
|
||||
|
||||
assert(publicKey);
|
||||
assert(privateKey);
|
||||
});
|
||||
|
||||
it('should return an object with date, a null digest, and signature, if no payload is passed in', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
const { date, digest, signature } = await activitypub.sign(keyData, endpoint);
|
||||
const dateObj = new Date(date);
|
||||
|
||||
assert(signature);
|
||||
assert(dateObj);
|
||||
assert.strictEqual(digest, null);
|
||||
});
|
||||
|
||||
it('should also return a digest hash if payload is passed in', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const payload = { foo: 'bar' };
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
const { digest } = await activitypub.sign(keyData, endpoint, payload);
|
||||
const hash = createHash('sha256');
|
||||
hash.update(JSON.stringify(payload));
|
||||
const checksum = hash.digest('base64');
|
||||
|
||||
assert(digest);
|
||||
assert.strictEqual(digest, `SHA-256=${checksum}`);
|
||||
});
|
||||
|
||||
it('should create a key for NodeBB itself if a uid of 0 is passed in', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', 0);
|
||||
await activitypub.sign(keyData, endpoint);
|
||||
const { publicKey, privateKey } = await db.getObject(`uid:0:keys`);
|
||||
|
||||
assert(publicKey);
|
||||
assert(privateKey);
|
||||
});
|
||||
|
||||
it('should return headers with an appropriate key id uri', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
const { signature } = await activitypub.sign(keyData, endpoint);
|
||||
const [keyId] = signature.split(',');
|
||||
|
||||
assert(signature);
|
||||
assert.strictEqual(keyId, `keyId="${nconf.get('url')}/uid/${uid}#key"`);
|
||||
});
|
||||
|
||||
it('should return the instance key id when uid is 0', async () => {
|
||||
const endpoint = `${nconf.get('url')}/uid/${uid}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', 0);
|
||||
const { signature } = await activitypub.sign(keyData, endpoint);
|
||||
const [keyId] = signature.split(',');
|
||||
|
||||
assert(signature);
|
||||
assert.strictEqual(keyId, `keyId="${nconf.get('url')}/actor#key"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.verify()', () => {
|
||||
let uid;
|
||||
let username;
|
||||
const baseUrl = nconf.get('relative_path');
|
||||
const mockReqBase = {
|
||||
method: 'GET',
|
||||
// path: ...
|
||||
baseUrl,
|
||||
headers: {
|
||||
// host: ...
|
||||
// date: ...
|
||||
// signature: ...
|
||||
// digest: ...
|
||||
},
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
username = utils.generateUUID().slice(0, 10);
|
||||
uid = await user.create({ username });
|
||||
});
|
||||
|
||||
it('should return true when the proper signature and relevant headers are passed in', async () => {
|
||||
const endpoint = `${nconf.get('url')}/user/${username}/inbox`;
|
||||
const path = `/user/${username}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
const signature = await activitypub.sign(keyData, endpoint);
|
||||
const { host } = nconf.get('url_parsed');
|
||||
const req = {
|
||||
...mockReqBase,
|
||||
...{
|
||||
path,
|
||||
headers: { ...signature, host },
|
||||
},
|
||||
};
|
||||
|
||||
const verified = await activitypub.verify(req);
|
||||
assert.strictEqual(verified, true);
|
||||
});
|
||||
|
||||
it('should return true when a digest is also passed in', async () => {
|
||||
const endpoint = `${nconf.get('url')}/user/${username}/inbox`;
|
||||
const path = `/user/${username}/inbox`;
|
||||
const keyData = await activitypub.getPrivateKey('uid', uid);
|
||||
const signature = await activitypub.sign(keyData, endpoint, { foo: 'bar' });
|
||||
const { host } = nconf.get('url_parsed');
|
||||
const req = {
|
||||
...mockReqBase,
|
||||
...{
|
||||
method: 'POST',
|
||||
path,
|
||||
headers: { ...signature, host },
|
||||
},
|
||||
};
|
||||
|
||||
const verified = await activitypub.verify(req);
|
||||
assert.strictEqual(verified, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user