From d61eb13a8c12b272901ec1695dd7ba517e3c716b Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Sun, 29 Sep 2024 13:29:10 +0700 Subject: [PATCH] Wired up authentication to tests refs https://linear.app/tryghost/issue/AP-288 This makes sure that all of our tests use authentication. We have to stop communicating with the `activitypub-testing` service directly, because we need to replicate how this runs in production. How this generally runs is that there will be a host `example.com` and everything on `/.ghost/activitypub` will hit our service, and everything else will hit a Ghost instance - specifically for us we need the `/ghost/.well-known/jwks.json` endpoint to be reachable for auth to work. We have two wiremock instances, `fake-external-activitypub` is used to mock external services, so we can test things like follow requests and sending to external inboxes. `fake-ghost-activitypub` is the actual service under test, it proxies everything to our underlying `activitypub-testing` container, but allows us to add mocks for the jwks.json file. This essentially behaves as the `nginx` container in dev, or fastly in production. Listening on port 80 gives nicer urls Hardcoded keypair saves generating the keys, and allows us to cache them in the db. --- docker-compose.yml | 17 +-- features/fixtures/private.key | 28 +++++ features/fixtures/public.key | 9 ++ features/step_definitions/stepdefs.js | 153 ++++++++++++++++-------- wiremock/fake-ghost/mappings/proxy.json | 14 +++ 5 files changed, 163 insertions(+), 58 deletions(-) create mode 100644 features/fixtures/private.key create mode 100644 features/fixtures/public.key create mode 100644 wiremock/fake-ghost/mappings/proxy.json diff --git a/docker-compose.yml b/docker-compose.yml index 499703b4..824d9e29 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -84,7 +84,9 @@ services: - NODE_ENV=testing command: yarn run cucumber-js depends_on: - wiremock: + fake-ghost-activitypub: + condition: service_started + fake-external-activitypub: condition: service_started activitypub-testing: condition: service_healthy @@ -102,14 +104,15 @@ services: interval: 1s retries: 120 - wiremock: + fake-ghost-activitypub: image: wiremock/wiremock:latest - ports: - - "8082:8080" + entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose", "--port=80"] volumes: - - ./wiremock/mappings:/home/wiremock/mappings - - ./wiremock/__files:/home/wiremock/__files - entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose"] + - ./wiremock/fake-ghost/mappings:/home/wiremock/mappings + + fake-external-activitypub: + image: wiremock/wiremock:latest + entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose", "--port=80"] fake-mastodon: image: wiremock/wiremock:latest diff --git a/features/fixtures/private.key b/features/fixtures/private.key new file mode 100644 index 00000000..3f2f0545 --- /dev/null +++ b/features/fixtures/private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDF/DHjumSXbqze +fmOULYZNlddNWpqw6q3T1U/zrwY8XM/sZhRKzUBcEUVDucQTbSPpuo46FoNOhJT7 +ws57ltNlwLxJkzwTmkY2QUX2lmvRzXYwfjb4Q0y0ynYgDop213stJLORnpA4CjWP +gfvOtqpbEDI5L6luXEOR8G69Mfu3FzJ7C83WfpzuU5ErPSEBZZ0TT2ZXn8g6YXWu +EyDUz4GPNaDpRnaYU/5jNpURwzaB92Hmbb99zeUjPHMsrcRrAILDT46T66ISSi6J +Jpv1OcYkedCxjdRWSGz8jPXyO46q3CrcH2khiwRkk2I5dn+8gJkgOKHbCc3PUD0O +I1nKhfEFAgMBAAECggEAGke36pndDOHWxgDiYHKri2RqrBytAHNiSAZeYsMWkZAj +VGaXZnd4xc/QESWZMpfv5rBJ/UlsPBGqwgFxjaOvY2gSRjTqSlLV45FGA22jmbmL +aPP0AX/TcIMYa3hqpkxDkDI5OMjirWGjiu1O2rlSAxzzAbbDJ4BNQtO2q1v1ZO/O +SjIV7VnzF5JVJ6MmT5X0x8sXsUi6amhJHeUFhVuINxDhVi/bDgVcwaDvICD8Zd6M +IvpNLYtXEsUKDdu6Elk5EUL3bOGguQYUlHKefvzqxQOJiXZPUCrIn01MudBwssVh +9KbtEPWJRuKkT+sVDGBgArGh6rjmUAgYUvQF5TXwcQKBgQDoUtyiWNwQi/4V9qdh +oLLIQzcEnXySwuGt4W4MAKCuvrOs6olnHuShiX4gTy9AhuBbc8YyVmfyeyMYYchg +AJAbhNlE2pDodOhLc5j5zW2iqagf9VtlKz1qqHquEQu/DuHvQpRMYHH9bAam4dGD +pWQhDZCorZ89rILJeZtx26QxcQKBgQDaKXfQ81evhxWJCZE1uN8FZ9Qu5OfmB52x +cZONXmdhsspCmEXEhJkTaeHAJRs9YmP8cvNaVip2ox9XTvH1wfD/fUKSCF3VgCMM +WTlakbIs+OakOJIj4LK3lEch4Kq5KDD6AvFQ6yHkjM1ZeJPK4X0VevOVuvgw1gGJ +HrTU/y6u1QKBgHkQDOcQlQSOXsZFNO3b1q4i0H24L10u7nk0mqrofNLyjyCRSy6Q +W6WNx0rA2KewYSNmziYW/q3N2vjuo4LbaDze2nVVy+NGYHJI97NciEAWVoToz0qF +4Mg+qUchnNRfxf5u3GZ8b4oWi9TUoeAPBIFw1yv+5Zc22SRyGT2YrhQRAoGBANg1 +PK9yWzZ0E92qA6VQQIak7d5DsaeBaMEQpID4TFDA1j7Flm86UlKxHrBElghx2FG6 +wn6G4rKM22S1sooy2Nr7ktwTOpt60EFOs86UkhaL3lhmUD8KU1QouY5TkB7MPC2q +eOoO/Zn6CRFgtGferQ56ualskMglb4QrUF+/Ps65AoGAK89IUXy0AZe6Mu/Cel8c +vqy/162x6s3WjBVNB9Yv2SyyRDNi08/5j1IDBAsSAbFXI4GMY/SnqF7E5YhSvCwa +A9thv/Im0kF/72POO6UpEfe2QWqjOpUI8FCMWUOVDP4tVQ9b8eTqNTMkB3W4MgTo +2EOtiOrc9Wd+E7gpDsVMCNA= +-----END PRIVATE KEY----- diff --git a/features/fixtures/public.key b/features/fixtures/public.key new file mode 100644 index 00000000..3f99ccb3 --- /dev/null +++ b/features/fixtures/public.key @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfwx47pkl26s3n5jlC2G +TZXXTVqasOqt09VP868GPFzP7GYUSs1AXBFFQ7nEE20j6bqOOhaDToSU+8LOe5bT +ZcC8SZM8E5pGNkFF9pZr0c12MH42+ENMtMp2IA6Kdtd7LSSzkZ6QOAo1j4H7zraq +WxAyOS+pblxDkfBuvTH7txcyewvN1n6c7lORKz0hAWWdE09mV5/IOmF1rhMg1M+B +jzWg6UZ2mFP+YzaVEcM2gfdh5m2/fc3lIzxzLK3EawCCw0+Ok+uiEkouiSab9TnG +JHnQsY3UVkhs/Iz18juOqtwq3B9pIYsEZJNiOXZ/vICZIDih2wnNz1A9DiNZyoXx +BQIDAQAB +-----END PUBLIC KEY----- diff --git a/features/step_definitions/stepdefs.js b/features/step_definitions/stepdefs.js index 15755798..ea1c6d7b 100644 --- a/features/step_definitions/stepdefs.js +++ b/features/step_definitions/stepdefs.js @@ -3,6 +3,16 @@ import Knex from 'knex'; import { BeforeAll, AfterAll, Before, After, Given, When, Then } from '@cucumber/cucumber'; import { v4 as uuidv4 } from 'uuid'; import { WireMock } from 'wiremock-captain'; +import jose from 'node-jose'; +import jwt from 'jsonwebtoken'; +import fs from 'node:fs'; +import { fileURLToPath } from 'url'; +import { dirname, resolve } from 'path'; +import http from 'http'; + +// Get the current file's URL and convert it to a path +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); async function createActivity(activityType, object, actor, remote = true) { if (activityType === 'Follow') { @@ -12,7 +22,7 @@ async function createActivity(activityType, object, actor, remote = true) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Follow', - 'id': `http://wiremock:8080/follow/${uuidv4()}`, + 'id': `http://fake-external-activitypub/follow/${uuidv4()}`, 'to': 'as:Public', 'object': object, actor: actor, @@ -26,7 +36,7 @@ async function createActivity(activityType, object, actor, remote = true) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Accept', - 'id': `http://wiremock:8080/accept/${uuidv4()}`, + 'id': `http://fake-external-activitypub/accept/${uuidv4()}`, 'to': 'as:Public', 'object': object, actor: actor, @@ -40,7 +50,7 @@ async function createActivity(activityType, object, actor, remote = true) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Create', - 'id': `http://wiremock:8080/create/${uuidv4()}`, + 'id': `http://fake-external-activitypub/create/${uuidv4()}`, 'to': 'as:Public', 'object': object, actor: actor, @@ -54,7 +64,7 @@ async function createActivity(activityType, object, actor, remote = true) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Announce', - 'id': `http://wiremock:8080/announce/${uuidv4()}`, + 'id': `http://fake-external-activitypub/announce/${uuidv4()}`, 'to': 'as:Public', 'object': object, actor: actor, @@ -68,7 +78,7 @@ async function createActivity(activityType, object, actor, remote = true) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Like', - 'id': `http://wiremock:8080/like/${uuidv4()}`, + 'id': `http://fake-external-activitypub/like/${uuidv4()}`, 'to': 'as:Public', 'object': object, actor: actor, @@ -83,24 +93,24 @@ async function createActor(name = 'Test', remote = true) { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/data-integrity/v1', ], - 'id': 'http://activitypub-testing:8083/.ghost/activitypub/users/index', - 'url': 'http://activitypub-testing:8083/.ghost/activitypub/users/index', + 'id': 'http://fake-ghost-activitypub/.ghost/activitypub/users/index', + 'url': 'http://fake-ghost-activitypub/.ghost/activitypub/users/index', 'type': 'Person', 'preferredUsername': 'index', 'name': 'Test Actor', 'summary': 'A test actor for testing', - 'inbox': 'http://activitypub-testing:8083/.ghost/activitypub/inbox/index', - 'outbox': 'http://activitypub-testing:8083/.ghost/activitypub/outbox/index', - 'followers': 'http://activitypub-testing:8083/.ghost/activitypub/followers/index', - 'following': 'http://activitypub-testing:8083/.ghost/activitypub/following/index', + 'inbox': 'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', + 'outbox': 'http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', + 'followers': 'http://fake-ghost-activitypub/.ghost/activitypub/followers/index', + 'following': 'http://fake-ghost-activitypub/.ghost/activitypub/following/index', 'https://w3id.org/security#publicKey': { - 'id': 'http://activitypub-testing:8083/.ghost/activitypub/users/index#main-key', + 'id': 'http://fake-ghost-activitypub/.ghost/activitypub/users/index#main-key', 'type': 'https://w3id.org/security#Key', 'https://w3id.org/security#owner': { - 'id': 'http://activitypub-testing:8083/.ghost/activitypub/users/index' + 'id': 'http://fake-ghost-activitypub/.ghost/activitypub/users/index' }, 'https://w3id.org/security#publicKeyPem': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSc3IqGjRaO3vcFdQ15D\nF90WVJC6tb2QwYBh9kQYVlQ1VhBiF6E4GK2okvyvukIL5PHLCgfQrfJmSiopk9Xo\n46Qri6rJbcPoWoZz/jWN0pfmU20hNuTQx6ebSoSkg6rHv1MKuy5LmDGLFC2ze3kU\nsY8u7X6TOBrifs/N+goLaH3+SkT2hZDKWJrmDyHzj043KLvXs/eiyu50M+ERoSlg\n70uO7QAXQFuLMILdy0UNJFM4xjlK6q4Jfbm4MC8QRG+i31AkmNvpY9JqCLqu0mGD\nBrdfJeN8PN+7DHW/Pzspf5RlJtlvBx1dS8Bxo2xteUyLGIaTZ9HZFhHc3IrmmKeW\naQIDAQAB\n-----END PUBLIC KEY-----\n' } @@ -109,7 +119,7 @@ async function createActor(name = 'Test', remote = true) { // Register endpoints with wiremock - for now just inbox - captain.register({ + externalActivityPubCaptain.register({ method: 'POST', endpoint: `/inbox/${name}` }, { @@ -121,24 +131,24 @@ async function createActor(name = 'Test', remote = true) { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/data-integrity/v1', ], - 'id': `http://wiremock:8080/user/${name}`, - 'url': `http://wiremock:8080/user/${name}`, + 'id': `http://fake-external-activitypub/user/${name}`, + 'url': `http://fake-external-activitypub/user/${name}`, 'type': 'Person', 'preferredUsername': name, 'name': name, 'summary': 'A test actor for testing', - 'inbox': `http://wiremock:8080/inbox/${name}`, - 'outbox': `http://wiremock:8080/inbox/${name}`, - 'followers': `http://wiremock:8080/followers/${name}`, - 'following': `http://wiremock:8080/following/${name}`, + 'inbox': `http://fake-external-activitypub/inbox/${name}`, + 'outbox': `http://fake-external-activitypub/inbox/${name}`, + 'followers': `http://fake-external-activitypub/followers/${name}`, + 'following': `http://fake-external-activitypub/following/${name}`, 'https://w3id.org/security#publicKey': { - 'id': 'http://wiremock:8080/user#main-key', + 'id': 'http://fake-external-activitypub/user#main-key', 'type': 'https://w3id.org/security#Key', 'https://w3id.org/security#owner': { - 'id': 'http://wiremock:8080/user' + 'id': 'http://fake-external-activitypub/user' }, 'https://w3id.org/security#publicKeyPem': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSc3IqGjRaO3vcFdQ15D\nF90WVJC6tb2QwYBh9kQYVlQ1VhBiF6E4GK2okvyvukIL5PHLCgfQrfJmSiopk9Xo\n46Qri6rJbcPoWoZz/jWN0pfmU20hNuTQx6ebSoSkg6rHv1MKuy5LmDGLFC2ze3kU\nsY8u7X6TOBrifs/N+goLaH3+SkT2hZDKWJrmDyHzj043KLvXs/eiyu50M+ERoSlg\n70uO7QAXQFuLMILdy0UNJFM4xjlK6q4Jfbm4MC8QRG+i31AkmNvpY9JqCLqu0mGD\nBrdfJeN8PN+7DHW/Pzspf5RlJtlvBx1dS8Bxo2xteUyLGIaTZ9HZFhHc3IrmmKeW\naQIDAQAB\n-----END PUBLIC KEY-----\n' } @@ -154,13 +164,13 @@ function generateObject(type) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Article', - 'id': `http://wiremock:8080/article/${uuid}`, - 'url': `http://wiremock:8080/article/${uuid}`, + 'id': `http://fake-external-activitypub/article/${uuid}`, + 'url': `http://fake-external-activitypub/article/${uuid}`, 'to': 'as:Public', - 'cc': 'http://wiremock:8080/followers', + 'cc': 'http://fake-external-activitypub/followers', 'content': '

This is a test article

', 'published': '2020-04-20T04:20:00Z', - 'attributedTo': 'http://wiremock:8080/user' + 'attributedTo': 'http://fake-external-activitypub/user' }; } @@ -172,13 +182,13 @@ function generateObject(type) { 'https://w3id.org/security/data-integrity/v1', ], 'type': 'Note', - 'id': `http://wiremock:8080/note/${uuid}`, - 'url': `http://wiremock:8080/note/${uuid}`, + 'id': `http://fake-external-activitypub/note/${uuid}`, + 'url': `http://fake-external-activitypub/note/${uuid}`, 'to': 'as:Public', - 'cc': 'http://wiremock:8080/followers', + 'cc': 'http://fake-external-activitypub/followers', 'content': '

This is a test note

', 'published': '2020-04-20T04:20:00Z', - 'attributedTo': 'http://wiremock:8080/user' + 'attributedTo': 'http://fake-external-activitypub/user' }; } } @@ -188,7 +198,7 @@ async function createObject(type) { const url = new URL(object.id); - captain.register({ + externalActivityPubCaptain.register({ method: 'GET', endpoint: url.pathname }, { @@ -224,7 +234,8 @@ function parseActivityString(string) { } let /* @type Knex */ client; -let /* @type WireMock */ captain; +let /* @type WireMock */ externalActivityPubCaptain; +let /* @type WireMock */ ghostActivityPubCaptain; BeforeAll(async function () { client = Knex({ @@ -242,7 +253,28 @@ BeforeAll(async function () { }); BeforeAll(async function () { - captain = new WireMock('http://wiremock:8080'); + externalActivityPubCaptain = new WireMock('http://fake-external-activitypub'); + ghostActivityPubCaptain = new WireMock('http://fake-ghost-activitypub'); + + const publicKey = fs.readFileSync(resolve(__dirname, '../fixtures/private.key'), 'utf8'); + + const key = await jose.JWK.asKey(publicKey, 'pem', { + kid: 'test-key-id' + }) + const jwk = key.toJSON(); + + ghostActivityPubCaptain.register({ + method: 'GET', + endpoint: '/ghost/.well-known/jwks.json' + }, { + status: 200, + body: { + keys: [jwk] + }, + headers: { + 'Content-Type': 'application/activity+json' + } + }); }); AfterAll(async function () { @@ -250,7 +282,7 @@ AfterAll(async function () { }); Before(async function () { - await captain.clearAllRequests(); + await externalActivityPubCaptain.clearAllRequests(); }); Before(async function () { @@ -265,7 +297,26 @@ Before(async function () { Us: await createActor('Test', false) }; } -}) +}); + +async function fetchActivityPub(url, options) { + if (!options.headers) { + options.headers = {}; + } + + const privateKey = fs.readFileSync(resolve(__dirname, '../fixtures/private.key')); + const token = jwt.sign({ + sub: 'test@user.com', + role: 'Owner' + }, privateKey, { + algorithm: 'RS256', + keyid: 'test-key-id', + expiresIn: '5m' + }); + + options.headers['Authorization'] = `Bearer ${token}`; + return fetch(url, options); +} Given('an Actor {string}', async function (name) { this.actors[name] = await createActor(name); @@ -273,20 +324,20 @@ Given('an Actor {string}', async function (name) { When('we like the object {string}', async function (name) { const id = this.objects[name].id; - this.response = await fetch(`http://activitypub-testing:8083/.ghost/activitypub/actions/like/${encodeURIComponent(id)}`, { + this.response = await fetchActivityPub(`http://fake-ghost-activitypub/.ghost/activitypub/actions/like/${encodeURIComponent(id)}`, { method: 'POST' }); }); When('we unlike the object {string}', async function (name) { const id = this.objects[name].id; - this.response = await fetch(`http://activitypub-testing:8083/.ghost/activitypub/actions/unlike/${encodeURIComponent(id)}`, { + this.response = await fetchActivityPub(`http://fake-ghost-activitypub/.ghost/activitypub/actions/unlike/${encodeURIComponent(id)}`, { method: 'POST' }); }); Then('the object {string} should be liked', async function (name) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/inbox/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json' } @@ -300,7 +351,7 @@ Then('the object {string} should be liked', async function (name) { }); Then('the object {string} should not be liked', async function (name) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/inbox/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json' } @@ -314,7 +365,7 @@ Then('the object {string} should not be liked', async function (name) { }); Then('the object {string} should be in the liked collection', async function (name) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/liked/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/liked/index', { headers: { Accept: 'application/ld+json' } @@ -329,7 +380,7 @@ Then('the object {string} should be in the liked collection', async function (na }); Then('the object {string} should not be in the liked collection', async function (name) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/liked/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/liked/index', { headers: { Accept: 'application/ld+json' } @@ -383,7 +434,7 @@ When('{string} sends {string} to the Inbox', async function (actorName, activity const activity = this.activities[activityName]; - this.response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/inbox/index', { + this.response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', { method: 'POST', headers: { 'Content-Type': 'application/ld+json' @@ -395,7 +446,7 @@ When('{string} sends {string} to the Inbox', async function (actorName, activity Then('Activity {string} is sent to {string}', async function (activityName, actorName) { const actor = this.actors[actorName]; const inbox = new URL(actor.inbox); - const calls = await captain.getRequestsForAPI('POST', inbox.pathname); + const calls = await externalActivityPubCaptain.getRequestsForAPI('POST', inbox.pathname); const activity = this.activities[activityName]; const found = calls.find((call) => { @@ -416,7 +467,7 @@ const webhooks = { "feature_image": null, "visibility": "paid", "published_at": "1970-01-01T00:00:00.000Z", - "url": "http://wiremock:8080/post/", + "url": "http://fake-external-activitypub/post/", "excerpt": "This is some content.", } } @@ -424,7 +475,7 @@ const webhooks = { }; const endpoints = { - 'post.published': 'http://activitypub-testing:8083/.ghost/activitypub/webhooks/post/published' + 'post.published': 'http://fake-ghost-activitypub/.ghost/activitypub/webhooks/post/published' }; Given('a valid {string} webhook', function (string) { @@ -434,7 +485,7 @@ Given('a valid {string} webhook', function (string) { When('it is sent to the webhook endpoint', async function () { const endpoint = endpoints[this.payloadType]; const payload = webhooks[this.payloadType]; - this.response = await fetch(endpoint, { + this.response = await fetchActivityPub(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/ld+json' @@ -461,7 +512,7 @@ Then('a {string} activity is in the Outbox', async function (string) { if (!match) { throw new Error(`Could not match ${string} to an activity`); } - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/outbox/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/outbox/index', { headers: { Accept: 'application/ld+json' } @@ -488,7 +539,7 @@ Then('the found {string} has property {string}', function (name, prop) { }); Then('{string} is in our Inbox', async function (activityName) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/inbox/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/inbox/index', { headers: { Accept: 'application/ld+json' } @@ -502,7 +553,7 @@ Then('{string} is in our Inbox', async function (activityName) { }); Then('{string} is in our Followers', async function (actorName) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/followers/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/followers/index', { headers: { Accept: 'application/ld+json' } @@ -516,7 +567,7 @@ Then('{string} is in our Followers', async function (actorName) { }); Then('{string} is in our Followers once only', async function (actorName) { - const response = await fetch('http://activitypub-testing:8083/.ghost/activitypub/followers/index', { + const response = await fetchActivityPub('http://fake-ghost-activitypub/.ghost/activitypub/followers/index', { headers: { Accept: 'application/ld+json' } @@ -542,7 +593,7 @@ Then('a {string} activity is sent to {string}', async function (activityString, const inboxUrl = new URL(actor.inbox); - const requests = await captain.getRequestsForAPI('POST', inboxUrl.pathname); + const requests = await externalActivityPubCaptain.getRequestsForAPI('POST', inboxUrl.pathname); const found = requests.find(request => { const body = JSON.parse(request.request.body); diff --git a/wiremock/fake-ghost/mappings/proxy.json b/wiremock/fake-ghost/mappings/proxy.json new file mode 100644 index 00000000..33ec96e9 --- /dev/null +++ b/wiremock/fake-ghost/mappings/proxy.json @@ -0,0 +1,14 @@ +{ + "request": { + "method": "ANY", + "urlPattern": ".*" + }, + "response": { + "proxyBaseUrl": "http://activitypub-testing:8083", + "additionalProxyRequestHeaders": { + "X-Forwarded-For": "{{request.clientIp}}", + "X-Forwarded-Host": "{{request.headers.Host}}", + "X-Forwarded-Proto": "{{request.protocol}}" + } + } +}