From ecc7d1eee75cb1fdcac5850a8286a6a7c93b0b9c Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Mon, 25 Nov 2024 13:09:28 +0100 Subject: [PATCH] feat(federation): :sparkles: Add UI to view BullMQ metadata --- app.ts | 2 + build.ts | 4 + bun.lockb | Bin 379084 -> 380888 bytes package.json | 5 + patches/@bull-board%2Fapi@6.5.3.patch | 13 ++ plugins/openid/index.ts | 224 ++++++++++++++++++-------- utils/bull-board.ts | 38 +++++ 7 files changed, 215 insertions(+), 71 deletions(-) create mode 100644 patches/@bull-board%2Fapi@6.5.3.patch create mode 100644 utils/bull-board.ts diff --git a/app.ts b/app.ts index 242726de..bec323c6 100644 --- a/app.ts +++ b/app.ts @@ -1,5 +1,6 @@ import { join } from "node:path"; import { handleZodError } from "@/api"; +import { applyToHono } from "@/bull-board.ts"; import { configureLoggers } from "@/loggers"; import { sentry } from "@/sentry"; import { cors } from "@hono/hono/cors"; @@ -160,6 +161,7 @@ export const appFactory = async (): Promise> => { }, }); app.get("/docs", swaggerUI({ url: "/openapi.json" })); + applyToHono(app); app.options("*", (context) => { return context.text("", 204); diff --git a/build.ts b/build.ts index 59dd4c24..2fa0ed8f 100644 --- a/build.ts +++ b/build.ts @@ -35,6 +35,10 @@ await Bun.build({ buildSpinner.text = "Transforming"; +// Fix Bun incorrectly transforming aliased imports +await $`sed -i 's/var serveStatic = (options) => {/var serveStaticBase = (options) => {/g' dist/index.js`; +await $`sed -i 's/ return serveStatic({/ return serveStaticBase({/g' dist/index.js`; + // Copy Drizzle migrations to dist await $`cp -r drizzle dist/drizzle`; diff --git a/bun.lockb b/bun.lockb index 33e178496a23b52301d4188412235cb76e1e081a..36980e772e5b439ee4941093f1207fb5a9a5f4d9 100755 GIT binary patch delta 68887 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 delta 66987 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

Pa?}UAt9v{ z`ZCe2AIS*TcB7F8Uj-V-vQtt7k zX^G4MTi7WQ$0P9N6YQiGf%d>7MvUX$j@U&W7416mG>k3cXRAiN6MfSBmSRK94 zRahBrcDwY@7nR&2oidy%j2iV+$ZO0IZnSeGY|t9J*{#!qd)&jFBXmeomq;+rjq>*i zx3Ehjbhxs6q)SGypPSS*61>Nac8!F8V^}tIk44g*#tc+-YS2BNo*J4|)g9X^Bm5*{ zOE=-f@8M}FT~eLj@zgsc5J`3VGybpeJdLFX@EZAHty06g z@p`$*WLo?DKp=vCj=Q!^YIqV}bN5(!y0aQfgT+fL^y&F-{T>-kO)k30h>7mnE~&xU zZefo|_+_-F?wa=Lp`U8F^?PPGmvTkcnISi&XR5Ol&mSZ5zQk)xSP7LdT$M{)JNH<( zbZ0PDdoMT28eS&P&CW=7KErD6>6$TB-K5?Tr~ie%#(eCZ>deRM<>!XCAFlx(1?-XP z46VgZ8?TgClC^k>>5Wz=$n`&hSK3|MGBw-=ucMpXCEd9ROZ{5Xn=-H9ojK=RF6}CP zSmWL4i09|bTnOKd=are^8NDjvRO9O0%8RSkABm^>apthJL>y&N!cDosb5z4pUVhE$ z#N$!l@N~R3?wU5~!HsTGKh~5w?$~}A!Asr3ev$C-O9Fu*ZgS6b=XtCvz4Vk-xw?M0 zJ6@${gUK)KCR#DN(`tX2=a~#c{*(%jZVpG=9 zPc=Q&xef1fys)YeejBfa(g`NINrNK6S#FfSJKRG4UgjR=?=UxMa3nb2jSh~4zP!|3 zJvc+78Hs=)5ogI|ek*&^fK|3|NF*3^4-;}VV^0+&WI(F(1YSElZ#fJ9j+gEpqX%0u z05nf%US`20Jhi;Pb#aJ0}gV zGoDvvrvR_5?=4A7#8HNhyS9C5FycmsM}pJb!r>8TQxm_N0&Yr=)X+~&-1;LjoVsMB z8YFs4z$`rV8YSwJmWX4!l`cGvr*@$LbXqg6pZ<)Sj^(#rE`#DJy#8+X@N~_+tccT% zp=uk5`MAt2%!-6QZ|)w+$_UnTlSb+46Xow(w{TR%`7SlSU>)zDmPk2hEvl$>UL zu^AaoYX%p&>6+gqHGB(RM{nNm$5KLmvNbVvYJ!&1a4ueBU8TYgc$U_QJy^7pEmV1y z01X`f>~46fxWA0f#w#j@v(bhTvvq3do6Ft$c^Sc4ZZt0v9OoA1MV#dfOh3A6yZ4Mo z-?IzKk2rZ9{9bXq_P8JKN(?Dp;Ew-RO)+_|{%rjOB;-V72i= zD!EBBBjJs`X)ZT;X1WukCDoXvG~k0%+`}^?&gTfD(7b(QxN9E@r^|NmCb#g~Ncau> z0h)o~+E)bvz1`$V>CQb^YJScbmKyr(DtGm)45vlkfTj~7vpzfpueqB%Bt85nRtv8J z2jf=oBlqxikzh|ZDHaK@9OM-)mL5KaHNs6E;Z=~3hXyO;SS&sC^s2>;W5hXyrol*8Pfuml zI(#E-m>CERcaPne&ftj7iG(K&XN0-O3etmrcMs2rIPFIGqtQR-NjG{^BwTJ}AaIS& zarDioEH6cEX7=EXaoK1L{puWcp4FYd8)dH=S9N(qw#zmy|Qs^|IFwAjv2-D|A zJe}vYv$G9PF-enUKa}k+t^S5If~PRNA*s%EJawzTKySiphF8WbO9?tj>m)f)vUYfW znz;-eu5b$?&W~1OVzx_l8s+%;_)E?NJoP;Dh*e<&p329v98F7PT~Shgb42j$%0DdC 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 { - try { - return await crypto.subtle.importKey( - "spki", - Buffer.from(v, "base64"), - "Ed25519", - true, - ["verify"], - ); - } catch { - throw new Error( - "Public key at oidc.keys.public is invalid", - ); - } - }), - private: z - .string() - .min(1) - .transform(async (v) => { - try { - return await crypto.subtle.importKey( - "pkcs8", - Buffer.from(v, "base64"), - "Ed25519", - true, - ["sign"], - ); - } catch { - throw new Error( - "Private key at oidc.keys.private is invalid", - ); - } - }), - }) - .optional() - .transform(async (v, ctx) => { - if (!(v?.private && v?.public)) { - const { public_key, private_key } = - await User.generateKeys(); - - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `Keys are missing, please add the following to your config:\n\nkeys.public: ${chalk.gray(public_key)}\nkeys.private: ${chalk.gray(private_key)} - `, - }); - } - - return v as Exclude; +const configSchema = z.object({ + forced: z.boolean().default(false), + allow_registration: z.boolean().default(true), + providers: z + .array( + z.object({ + name: z.string().min(1), + id: z.string().min(1), + url: z.string().min(1), + client_id: z.string().min(1), + client_secret: z.string().min(1), + icon: z.string().min(1).optional(), }), - }), -); + ) + .default([]), + keys: z + .object({ + public: z + .string() + .min(1) + .transform(async (v) => { + try { + return await crypto.subtle.importKey( + "spki", + Buffer.from(v, "base64"), + "Ed25519", + true, + ["verify"], + ); + } catch { + throw new Error( + "Public key at oidc.keys.public is invalid", + ); + } + }), + private: z + .string() + .min(1) + .transform(async (v) => { + try { + return await crypto.subtle.importKey( + "pkcs8", + Buffer.from(v, "base64"), + "Ed25519", + true, + ["sign"], + ); + } catch { + throw new Error( + "Private key at oidc.keys.private is invalid", + ); + } + }), + }) + .optional() + .transform(async (v, ctx) => { + if (!(v?.private && v?.public)) { + const { public_key, private_key } = await User.generateKeys(); + + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Keys are missing, please add the following to your config:\n\nkeys.public: ${chalk.gray(public_key)}\nkeys.private: ${chalk.gray(private_key)} + `, + }); + } + + return v as Exclude; + }), +}); + +const plugin = new Plugin(configSchema); // Test hook for screenshots plugin.registerHandler(Hooks.Response, (req) => { @@ -99,5 +102,84 @@ jwksRoute(plugin); ssoLoginRoute(plugin); ssoLoginCallbackRoute(plugin); +plugin.registerRoute("/admin/*", (app) => { + // Check for JWT when accessing the admin panel + app.use("/admin/*", async (context, next) => { + const jwtCookie = getCookie(context, "jwt"); + + if (!jwtCookie) { + return context.json( + { + error: "Unauthorized", + message: "No JWT cookie provided", + }, + 401, + ); + } + + const { keys } = context.get("pluginConfig"); + + const result = await jwtVerify(jwtCookie, keys.public, { + algorithms: ["EdDSA"], + issuer: new URL(context.get("config").http.base_url).origin, + }).catch((error) => { + if (error instanceof JOSEError) { + return error; + } + + throw error; + }); + + if (result instanceof JOSEError) { + if (result instanceof JWTExpired) { + return context.json( + { + error: "Unauthorized", + message: "JWT has expired. Please log in again.", + }, + 401, + ); + } + + return context.json( + { + error: "Unauthorized", + message: "Invalid JWT", + }, + 401, + ); + } + + const { + payload: { sub }, + } = result; + + if (!sub) { + return context.json( + { + error: "Unauthorized", + message: "Invalid JWT (no sub)", + }, + 401, + ); + } + + const user = await User.fromId(sub); + + if (!user?.hasPermission(RolePermissions.ManageInstanceFederation)) { + return context.json( + { + error: "Unauthorized", + message: + "You do not have permission to access this resource", + }, + 403, + ); + } + + await next(); + }); +}); + export type PluginType = typeof plugin; export default plugin; diff --git a/utils/bull-board.ts b/utils/bull-board.ts new file mode 100644 index 00000000..38c33395 --- /dev/null +++ b/utils/bull-board.ts @@ -0,0 +1,38 @@ +import { createBullBoard } from "@bull-board/api"; +import { BullMQAdapter } from "@bull-board/api/bullMQAdapter"; +import { HonoAdapter } from "@bull-board/hono"; +import { serveStatic } from "@hono/hono/bun"; +import type { OpenAPIHono } from "@hono/zod-openapi"; +import { config } from "~/packages/config-manager"; +import type { HonoEnv } from "~/types/api"; +import { deliveryQueue, inboxQueue } from "~/worker"; + +export const applyToHono = (app: OpenAPIHono): void => { + const serverAdapter = new HonoAdapter(serveStatic); + + createBullBoard({ + queues: [ + new BullMQAdapter(inboxQueue), + new BullMQAdapter(deliveryQueue), + ], + serverAdapter, + options: { + uiConfig: { + boardTitle: "Server Queues", + favIcon: { + default: "/favicon.png", + alternative: "/favicon.ico", + }, + boardLogo: { + path: + config.instance.logo ?? + "https://cdn.versia.pub/branding/icon.svg", + height: 40, + }, + }, + }, + }); + + serverAdapter.setBasePath("/admin/queues"); + app.route("/admin/queues", serverAdapter.registerPlugin()); +};