From 0326978dfaef5c1dd69ed3312c0a6de609b4d54e Mon Sep 17 00:00:00 2001 From: Fabien 'egg' O'Carroll Date: Mon, 29 Jul 2024 17:38:51 +0700 Subject: [PATCH 1/2] Updated @fedify/fedify to 0.13.0-dev.316 This includes the new inbox queue, which means that inbox handlers receive a Context instead of RequestContext --- package.json | 2 +- src/app.ts | 39 ++++++++++++++++++++++++++-------- src/dispatchers.ts | 11 +++++----- src/user.ts | 7 ++++--- yarn.lock | 52 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index ff2ffa0b..c012dac8 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "typescript": "5.4.5" }, "dependencies": { - "@fedify/fedify": "0.11.0-dev.223", + "@fedify/fedify": "0.13.0-dev.316", "@hono/node-server": "1.11.1", "@sentry/node": "8.13.0", "hono": "4.4.6", diff --git a/src/app.ts b/src/app.ts index dca93a9b..58df4354 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,7 +3,7 @@ import { Article, Accept, Object as ActivityPubObject, - Federation, + createFederation, Follow, KvKey, KvStore, @@ -15,9 +15,10 @@ import { Organization, Service, Update, + Context, } from '@fedify/fedify'; import { federation } from '@fedify/fedify/x/hono'; -import { Hono, Context } from 'hono'; +import { Hono, Context as HonoContext } from 'hono'; import { cors } from 'hono/cors'; import { behindProxy } from 'x-forwarded-fetch'; import { configure, getConsoleSink } from '@logtape/logtape'; @@ -65,18 +66,38 @@ export type ContextData = { const fedifyKv = await KnexKvStore.create(client, 'key_value'); -export const fedify = new Federation({ +export const fedify = createFederation({ kv: fedifyKv, - treatHttps: true, }); export const db = await KnexKvStore.create(client, 'key_value'); /** Fedify */ +/** + * Fedify does not pass the correct context object when running outside of the request context + * for example in the context of the Inbox Queue - so we need to wrap handlers with this. + */ +function ensureCorrectContext(fn: (ctx: Context, b: B) => Promise) { + return async function (ctx: Context, b: B) { + const host = ctx.host; + if (!ctx.data) { + (ctx as any).data = {}; + } + if (!ctx.data.globaldb) { + ctx.data.globaldb = db; + } + if (!ctx.data.db) { + ctx.data.db = scopeKvStore(db, ['sites', host]); + } + return fn(ctx, b); + } +} + fedify + // actorDispatcher uses RequestContext so doesn't need the ensureCorrectContext wrapper .setActorDispatcher('/.ghost/activitypub/users/{handle}', actorDispatcher) - .setKeyPairsDispatcher(keypairDispatcher); + .setKeyPairsDispatcher(ensureCorrectContext(keypairDispatcher)); const inboxListener = fedify.setInboxListeners( '/.ghost/activitypub/inbox/{handle}', @@ -84,11 +105,11 @@ const inboxListener = fedify.setInboxListeners( ); inboxListener - .on(Follow, handleFollow) + .on(Follow, ensureCorrectContext(handleFollow)) .onError(inboxErrorHandler) - .on(Accept, handleAccept) + .on(Accept, ensureCorrectContext(handleAccept)) .onError(inboxErrorHandler) - .on(Create, handleCreate) + .on(Create, ensureCorrectContext(handleCreate)) .onError(inboxErrorHandler); fedify @@ -227,7 +248,7 @@ app.post('/.ghost/activitypub/actions/follow/:handle', followAction); app.use( federation( fedify, - (ctx: Context<{ Variables: HonoContextVariables }>): ContextData => { + (ctx: HonoContext<{ Variables: HonoContextVariables }>): ContextData => { return { db: ctx.get('db'), globaldb: ctx.get('globaldb'), diff --git a/src/dispatchers.ts b/src/dispatchers.ts index 229299f8..4b1ee1ae 100644 --- a/src/dispatchers.ts +++ b/src/dispatchers.ts @@ -9,6 +9,7 @@ import { Note, Activity, Update, + Context, } from '@fedify/fedify'; import { v4 as uuidv4 } from 'uuid'; import { addToList } from './kv-helpers'; @@ -28,7 +29,7 @@ export async function actorDispatcher( return person; } -export async function keypairDispatcher(ctx: ContextData, handle: string) { +export async function keypairDispatcher(ctx: Context, handle: string) { if (handle !== 'index') return []; const data = await getUserKeypair(ctx, handle); @@ -39,7 +40,7 @@ export async function keypairDispatcher(ctx: ContextData, handle: string) { } export async function handleFollow( - ctx: RequestContext, + ctx: Context, follow: Follow, ) { console.log('Handling Follow'); @@ -76,7 +77,7 @@ export async function handleFollow( } export async function handleAccept( - ctx: RequestContext, + ctx: Context, accept: Accept, ) { console.log('Handling Accept'); @@ -108,7 +109,7 @@ export async function handleAccept( } export async function handleCreate( - ctx: RequestContext, + ctx: Context, create: Create, ) { console.log('Handling Create'); @@ -136,7 +137,7 @@ export async function handleCreate( } export async function inboxErrorHandler( - ctx: RequestContext, + ctx: Context, error: unknown, ) { console.error('Error handling incoming activity'); diff --git a/src/user.ts b/src/user.ts index ce074854..01aeba4e 100644 --- a/src/user.ts +++ b/src/user.ts @@ -4,6 +4,7 @@ import { generateCryptoKeyPair, exportJwk, importJwk, + Context, } from '@fedify/fedify'; import { ContextData } from './app'; @@ -78,8 +79,8 @@ export async function getUserData(ctx: RequestContext, handle: stri return data; } -export async function getUserKeypair(ctx: ContextData, handle: string) { - const existing = await ctx.db.get<{ publicKey: any; privateKey: any }>([ +export async function getUserKeypair(ctx: Context, handle: string) { + const existing = await ctx.data.db.get<{ publicKey: any; privateKey: any }>([ 'keypair', handle, ]); @@ -98,7 +99,7 @@ export async function getUserKeypair(ctx: ContextData, handle: string) { privateKey: keys.privateKey, }; - await ctx.db.set(['keypair', handle], { + await ctx.data.db.set(['keypair', handle], { publicKey: await exportJwk(data.publicKey), privateKey: await exportJwk(data.privateKey), }); diff --git a/yarn.lock b/yarn.lock index 823bc287..77a6dad6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -154,13 +154,14 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== -"@fedify/fedify@0.11.0-dev.223": - version "0.11.0-dev.223" - resolved "https://registry.yarnpkg.com/@fedify/fedify/-/fedify-0.11.0-dev.223.tgz#a9796a2ecd1e1517af67c32d87252672eb0b31de" - integrity sha512-p9WqdgPvKmzX1rsmQhNUZv+Z9BNs5T9DZbCJ55XfS0N0T6xOUTHeMty6B8hWOYNdtatFIaWAaTIcwOIFBlqm1Q== +"@fedify/fedify@0.13.0-dev.316": + version "0.13.0-dev.316" + resolved "https://registry.yarnpkg.com/@fedify/fedify/-/fedify-0.13.0-dev.316.tgz#c05928b26f520cbcf568ab4ade9715ac903cf958" + integrity sha512-/GQdF5jcyWOJrJmlaFZAH1sfPMmU7UAjCvXDERKMCts2LEv9kuj/d2NwqOLKbjggFPvaehzXoeiCDkI60v6MFA== dependencies: "@deno/shim-crypto" "~0.3.1" "@deno/shim-deno" "~0.18.0" + "@hugoalh/http-header-link" "^1.0.2" "@js-temporal/polyfill" "^0.4.4" "@logtape/logtape" "^0.4.0" "@phensley/language-tag" "^1.8.1" @@ -179,6 +180,18 @@ resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.11.1.tgz#f4c7bea7f3d52760b1950d6b8aeb900cc59142d3" integrity sha512-GW1Iomhmm1o4Z+X57xGby8A35Cu9UZLL7pSMdqDBkD99U5cywff8F+8hLk5aBTzNubnsFAvWQ/fZjNwPsEn9lA== +"@hugoalh/http-header-link@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@hugoalh/http-header-link/-/http-header-link-1.0.2.tgz#d3d35e960b2c2c024f903b2c8718c6b4d119b85c" + integrity sha512-q28PYAwW2OtuNqJnYKqFPod9QWpqSkvPQXsY7Qo+IC+6mk4vZyb0m9UqH1zL/PD7knP/YJ9qr4amJAxe1lmfkg== + dependencies: + "@hugoalh/is-string-singleline" "1.0.2" + +"@hugoalh/is-string-singleline@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@hugoalh/is-string-singleline/-/is-string-singleline-1.0.2.tgz#b123d9c06940cb08ce372ad3512ea3c893c6b78d" + integrity sha512-58tr/0q1D+2sB37ghYKPGR82XpNp/Lo2lbxumCX9KXQ6u0aZm1p4KIl3XW5R23m11znflKbsuZZyWv7cOqkm9Q== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -1912,7 +1925,16 @@ sqlstring@^2.3.2: resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1930,7 +1952,14 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -2091,7 +2120,16 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 4e01db4c7c162f91d25793a0d1e99d93ab15ad81 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Wed, 31 Jul 2024 17:27:37 +0700 Subject: [PATCH 2/2] fixup! Updated @fedify/fedify to 0.13.0-dev.316 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c012dac8..3bd753bc 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "typescript": "5.4.5" }, "dependencies": { - "@fedify/fedify": "0.13.0-dev.316", + "@fedify/fedify": "0.13.0-dev.318", "@hono/node-server": "1.11.1", "@sentry/node": "8.13.0", "hono": "4.4.6", diff --git a/yarn.lock b/yarn.lock index 77a6dad6..c8b0a40f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -154,10 +154,10 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== -"@fedify/fedify@0.13.0-dev.316": - version "0.13.0-dev.316" - resolved "https://registry.yarnpkg.com/@fedify/fedify/-/fedify-0.13.0-dev.316.tgz#c05928b26f520cbcf568ab4ade9715ac903cf958" - integrity sha512-/GQdF5jcyWOJrJmlaFZAH1sfPMmU7UAjCvXDERKMCts2LEv9kuj/d2NwqOLKbjggFPvaehzXoeiCDkI60v6MFA== +"@fedify/fedify@0.13.0-dev.318": + version "0.13.0-dev.318" + resolved "https://registry.yarnpkg.com/@fedify/fedify/-/fedify-0.13.0-dev.318.tgz#96146859d01888cb163908049bdb4d928ade0938" + integrity sha512-xzT3iz5IA9/9Wj30X+o0t0INDeLzn/7dq75nw5u966myzT0Ejq5L//fKNmVB04rFE6vx0+DWmZtpdxOL26YoNw== dependencies: "@deno/shim-crypto" "~0.3.1" "@deno/shim-deno" "~0.18.0"