From 7cea876ed8946bad06037db8525ad346a4f4fa8a Mon Sep 17 00:00:00 2001 From: Sven Sauleau Date: Tue, 7 Feb 2023 16:03:46 +0000 Subject: [PATCH] clarify UA used for federation --- backend/src/activitypub/activities/handle.ts | 2 +- backend/src/activitypub/deliver.ts | 12 +++++++++--- config/ua.ts | 5 +++++ consumer/src/deliver.ts | 2 +- consumer/test/consumer.spec.ts | 2 ++ functions/api/v1/accounts/[id]/follow.ts | 4 ++-- functions/api/v1/accounts/[id]/unfollow.ts | 4 ++-- functions/api/v1/statuses.ts | 2 +- functions/api/v1/statuses/[id]/favourite.ts | 2 +- functions/api/v1/statuses/[id]/reblog.ts | 2 +- 10 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 config/ua.ts diff --git a/backend/src/activitypub/activities/handle.ts b/backend/src/activitypub/activities/handle.ts index 5fb2ae3..8462492 100644 --- a/backend/src/activitypub/activities/handle.ts +++ b/backend/src/activitypub/activities/handle.ts @@ -248,7 +248,7 @@ export async function handle( await acceptFollowing(db, originalActor, receiver) const reply = accept.create(receiver, activity) const signingKey = await getSigningKey(userKEK, db, receiver) - await deliverToActor(signingKey, receiver, originalActor, reply) + await deliverToActor(signingKey, receiver, originalActor, reply, domain) // Notify the user const notifId = await insertFollowNotification(db, receiver, originalActor) diff --git a/backend/src/activitypub/deliver.ts b/backend/src/activitypub/deliver.ts index bca0e7c..45f273c 100644 --- a/backend/src/activitypub/deliver.ts +++ b/backend/src/activitypub/deliver.ts @@ -7,14 +7,20 @@ import type { Actor } from './actors' import { generateDigestHeader } from 'wildebeest/backend/src/utils/http-signing-cavage' import { signRequest } from 'wildebeest/backend/src/utils/http-signing' import { getFollowers } from 'wildebeest/backend/src/mastodon/follow' -import { WILDEBEEST_VERSION, MASTODON_API_VERSION } from 'wildebeest/config/versions' +import { getFederationUA } from 'wildebeest/config/ua' const MAX_BATCH_SIZE = 100 -export async function deliverToActor(signingKey: CryptoKey, from: Actor, to: Actor, activity: Activity) { +export async function deliverToActor( + signingKey: CryptoKey, + from: Actor, + to: Actor, + activity: Activity, + domain: string +) { const headers = { Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', - 'User-Agent': `Wildebeest/${WILDEBEEST_VERSION} Mastodon/${MASTODON_API_VERSION}`, + 'User-Agent': getFederationUA(domain), } const body = JSON.stringify(activity) diff --git a/config/ua.ts b/config/ua.ts new file mode 100644 index 0000000..b1201b1 --- /dev/null +++ b/config/ua.ts @@ -0,0 +1,5 @@ +import { WILDEBEEST_VERSION, MASTODON_API_VERSION } from 'wildebeest/config/versions' + +export function getFederationUA(domain: string): string { + return `Wildebeest/${WILDEBEEST_VERSION} (Mastodon/${MASTODON_API_VERSION}; +${domain})` +} diff --git a/consumer/src/deliver.ts b/consumer/src/deliver.ts index d1a7a78..6e825cb 100644 --- a/consumer/src/deliver.ts +++ b/consumer/src/deliver.ts @@ -20,5 +20,5 @@ export async function handleDeliverMessage(env: Env, actor: Actor, message: Deli } const signingKey = await getSigningKey(message.userKEK, env.DATABASE, actor) - await deliverToActor(signingKey, actor, targetActor, message.activity) + await deliverToActor(signingKey, actor, targetActor, message.activity, env.DOMAIN) } diff --git a/consumer/test/consumer.spec.ts b/consumer/test/consumer.spec.ts index 7ab8e2e..999d4cc 100644 --- a/consumer/test/consumer.spec.ts +++ b/consumer/test/consumer.spec.ts @@ -31,6 +31,7 @@ describe('Consumer', () => { if (input.url.toString() === 'https://example.com/inbox') { assert(input.headers.get('accept').includes('json')) assert(input.headers.get('user-agent').includes('Wildebeest')) + assert(input.headers.get('user-agent').includes(domain)) assert.equal(input.method, 'POST') receivedActivity = await input.json() return new Response('') @@ -60,6 +61,7 @@ describe('Consumer', () => { const env = { DATABASE: db, + DOMAIN: domain, } as any await handleDeliverMessage(env, actor, message) diff --git a/functions/api/v1/accounts/[id]/follow.ts b/functions/api/v1/accounts/[id]/follow.ts index da769eb..6491923 100644 --- a/functions/api/v1/accounts/[id]/follow.ts +++ b/functions/api/v1/accounts/[id]/follow.ts @@ -25,7 +25,7 @@ export async function handleRequest( if (request.method !== 'POST') { return new Response('', { status: 400 }) } - + const domain = new URL(request.url).hostname const handle = parseHandle(id) // Only allow to follow remote users @@ -44,7 +44,7 @@ export async function handleRequest( const activity = follow.create(connectedActor, targetActor) const signingKey = await getSigningKey(userKEK, db, connectedActor) - await deliverToActor(signingKey, connectedActor, targetActor, activity) + await deliverToActor(signingKey, connectedActor, targetActor, activity, domain) const res: Relationship = { id: await addFollowing(db, connectedActor, targetActor, acct), diff --git a/functions/api/v1/accounts/[id]/unfollow.ts b/functions/api/v1/accounts/[id]/unfollow.ts index 2eac35c..680cfa2 100644 --- a/functions/api/v1/accounts/[id]/unfollow.ts +++ b/functions/api/v1/accounts/[id]/unfollow.ts @@ -24,7 +24,7 @@ export async function handleRequest( if (request.method !== 'POST') { return new Response('', { status: 400 }) } - + const domain = new URL(request.url).hostname const handle = parseHandle(id) // Only allow to unfollow remote users @@ -41,7 +41,7 @@ export async function handleRequest( const activity = unfollow.create(connectedActor, targetActor) const signingKey = await getSigningKey(userKEK, db, connectedActor) - await deliverToActor(signingKey, connectedActor, targetActor, activity) + await deliverToActor(signingKey, connectedActor, targetActor, activity, domain) await removeFollowing(db, connectedActor, targetActor) const res: Relationship = { diff --git a/functions/api/v1/statuses.ts b/functions/api/v1/statuses.ts index 2527ee3..8253d7a 100644 --- a/functions/api/v1/statuses.ts +++ b/functions/api/v1/statuses.ts @@ -127,7 +127,7 @@ export async function handleRequest( note.cc.push(targetActor.id.toString()) const activity = activities.create(domain, connectedActor, note) const signingKey = await getSigningKey(userKEK, db, connectedActor) - await deliverToActor(signingKey, connectedActor, targetActor, activity) + await deliverToActor(signingKey, connectedActor, targetActor, activity, domain) } } diff --git a/functions/api/v1/statuses/[id]/favourite.ts b/functions/api/v1/statuses/[id]/favourite.ts index a22c1fc..047f376 100644 --- a/functions/api/v1/statuses/[id]/favourite.ts +++ b/functions/api/v1/statuses/[id]/favourite.ts @@ -45,7 +45,7 @@ export async function handleRequest( const activity = like.create(connectedActor, new URL(obj[originalObjectIdSymbol])) const signingKey = await getSigningKey(userKEK, db, connectedActor) - await deliverToActor(signingKey, connectedActor, targetActor, activity) + await deliverToActor(signingKey, connectedActor, targetActor, activity, domain) } await insertLike(db, connectedActor, obj) diff --git a/functions/api/v1/statuses/[id]/reblog.ts b/functions/api/v1/statuses/[id]/reblog.ts index 2238186..ffef22a 100644 --- a/functions/api/v1/statuses/[id]/reblog.ts +++ b/functions/api/v1/statuses/[id]/reblog.ts @@ -50,7 +50,7 @@ export async function handleRequest( await Promise.all([ // Delivers the announce activity to the post author. - deliverToActor(signingKey, connectedActor, targetActor, activity), + deliverToActor(signingKey, connectedActor, targetActor, activity, domain), // Share reblogged by delivering the announce activity to followers deliverFollowers(db, userKEK, connectedActor, activity, queue), ])