Skip to content

Commit b311e04

Browse files
committed
add basic auth to queues management
1 parent ad50094 commit b311e04

File tree

5 files changed

+93
-34
lines changed

5 files changed

+93
-34
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@
2727
"dependencies": {
2828
"@aws-sdk/client-kms": "^3.398.0",
2929
"@bull-board/fastify": "^5.21.1",
30+
"@fastify/basic-auth": "^5.1.1",
3031
"@fastify/cookie": "^8.3.0",
3132
"@fastify/express": "^2.3.0",
3233
"@fastify/swagger": "^8.9.0",
3334
"@fastify/type-provider-typebox": "^3.2.0",
3435
"@fastify/websocket": "^8.2.0",
3536
"@google-cloud/kms": "^4.4.0",
36-
"@prisma/client": "^5.16.1",
37+
"@prisma/client": "5.17.0",
3738
"@sinclair/typebox": "^0.31.28",
3839
"@t3-oss/env-core": "^0.6.0",
3940
"@thirdweb-dev/auth": "^4.1.87",
@@ -43,7 +44,7 @@
4344
"@types/base-64": "^1.0.2",
4445
"base-64": "^1.0.0",
4546
"body-parser": "^1.20.2",
46-
"bullmq": "^5.10.3",
47+
"bullmq": "^5.11.0",
4748
"cookie": "^0.5.0",
4849
"cookie-parser": "^1.4.6",
4950
"cron-parser": "^4.9.0",

src/server/middleware/adminRoutes.ts

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { createBullBoard } from "@bull-board/api";
22
import { BullMQAdapter } from "@bull-board/api/bullMQAdapter";
33
import { FastifyAdapter } from "@bull-board/fastify";
4+
import fastifyBasicAuth from "@fastify/basic-auth";
45
import { Queue } from "bullmq";
6+
import { timingSafeEqual } from "crypto";
57
import { FastifyInstance } from "fastify";
8+
import { StatusCodes } from "http-status-codes";
9+
import { env } from "../../utils/env";
610
import { CancelRecycledNoncesQueue } from "../../worker/queues/cancelRecycledNoncesQueue";
711
import { MineTransactionQueue } from "../../worker/queues/mineTransactionQueue";
812
import { ProcessEventsLogQueue } from "../../worker/queues/processEventLogsQueue";
@@ -11,29 +15,71 @@ import { PruneTransactionsQueue } from "../../worker/queues/pruneTransactionsQue
1115
import { SendTransactionQueue } from "../../worker/queues/sendTransactionQueue";
1216
import { SendWebhookQueue } from "../../worker/queues/sendWebhookQueue";
1317

14-
export const withAdminRoutes = async (server: FastifyInstance) => {
15-
const serverAdapter = new FastifyAdapter();
18+
export const ADMIN_QUEUES_BASEPATH = "/admin/queues";
19+
const ADMIN_ROUTES_PASSWORD = env.THIRDWEB_API_SECRET_KEY;
20+
// Add queues to monitor here.
21+
const QUEUES: Queue[] = [
22+
SendWebhookQueue.q,
23+
ProcessEventsLogQueue.q,
24+
ProcessTransactionReceiptsQueue.q,
25+
SendTransactionQueue.q,
26+
MineTransactionQueue.q,
27+
CancelRecycledNoncesQueue.q,
28+
PruneTransactionsQueue.q,
29+
];
1630

17-
const queues: Queue[] = [
18-
SendWebhookQueue.q,
19-
ProcessEventsLogQueue.q,
20-
ProcessTransactionReceiptsQueue.q,
21-
SendTransactionQueue.q,
22-
MineTransactionQueue.q,
23-
CancelRecycledNoncesQueue.q,
24-
PruneTransactionsQueue.q,
25-
];
26-
27-
createBullBoard({
28-
queues: queues.map((q) => new BullMQAdapter(q)),
29-
serverAdapter,
31+
export const withAdminRoutes = async (fastify: FastifyInstance) => {
32+
// Configure basic auth.
33+
await fastify.register(fastifyBasicAuth, {
34+
validate: (username, password, req, reply, done) => {
35+
if (assertAdminBasicAuth(username, password)) {
36+
done();
37+
return;
38+
}
39+
done(new Error("Unauthorized"));
40+
},
41+
authenticate: true,
3042
});
3143

32-
const bullboardPath = "/admin/queues";
44+
// Set up routes after Fastify is set up.
45+
fastify.after(async () => {
46+
// Register bullboard UI.
47+
const serverAdapter = new FastifyAdapter();
48+
serverAdapter.setBasePath(ADMIN_QUEUES_BASEPATH);
49+
50+
createBullBoard({
51+
queues: QUEUES.map((q) => new BullMQAdapter(q)),
52+
serverAdapter,
53+
});
54+
await fastify.register(serverAdapter.registerPlugin(), {
55+
basePath: ADMIN_QUEUES_BASEPATH,
56+
prefix: ADMIN_QUEUES_BASEPATH,
57+
});
3358

34-
serverAdapter.setBasePath(bullboardPath);
35-
await server.register(serverAdapter.registerPlugin(), {
36-
basePath: bullboardPath,
37-
prefix: bullboardPath,
59+
// Apply basic auth only to admin routes.
60+
fastify.addHook("onRequest", (req, reply, done) => {
61+
if (req.url.startsWith(ADMIN_QUEUES_BASEPATH)) {
62+
fastify.basicAuth(req, reply, (error) => {
63+
if (error) {
64+
reply
65+
.status(StatusCodes.UNAUTHORIZED)
66+
.send({ error: "Unauthorized" });
67+
return done(error);
68+
}
69+
});
70+
}
71+
done();
72+
});
3873
});
3974
};
75+
76+
const assertAdminBasicAuth = (username: string, password: string) => {
77+
if (username === "admin") {
78+
try {
79+
const buf1 = Buffer.from(password.padEnd(100));
80+
const buf2 = Buffer.from(ADMIN_ROUTES_PASSWORD.padEnd(100));
81+
return timingSafeEqual(buf1, buf2);
82+
} catch (e) {}
83+
}
84+
return false;
85+
};

src/server/middleware/auth.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { env } from "../../utils/env";
2424
import { logger } from "../../utils/logger";
2525
import { sendWebhookRequest } from "../../utils/webhook";
2626
import { Permission } from "../schemas/auth";
27+
import { ADMIN_QUEUES_BASEPATH } from "./adminRoutes";
2728

2829
export type TAuthData = never;
2930
export type TAuthSession = { permissions: string };
@@ -229,6 +230,11 @@ const handlePublicEndpoints = (req: FastifyRequest): AuthResponse => {
229230
}
230231
}
231232

233+
// Admin routes enforce their own auth.
234+
if (req.url.startsWith(ADMIN_QUEUES_BASEPATH)) {
235+
return { isAuthed: true };
236+
}
237+
232238
return { isAuthed: false };
233239
};
234240

src/utils/tracer.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import tracer from "dd-trace";
2-
import {env} from "./env";
2+
import { env } from "./env";
33

44
if (env.DD_TRACER_ACTIVATED) {
55
tracer.init(); // initialized in a different file to avoid hoisting.
6-
} else {
7-
console.info("DD_TRACER_ACTIVATED is not activated");
86
}
97

108
export default tracer;

yarn.lock

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,14 @@
17821782
ajv-formats "^2.1.1"
17831783
fast-uri "^2.0.0"
17841784

1785+
"@fastify/basic-auth@^5.1.1":
1786+
version "5.1.1"
1787+
resolved "https://registry.yarnpkg.com/@fastify/basic-auth/-/basic-auth-5.1.1.tgz#ff93d787bbbbd93b126550b797e1c416628c0a49"
1788+
integrity sha512-L4b7EK5LKZnV6fdH1+rQbjhkKGXjCfiKJ0JkdGHZQPBMHMiXDZF8xbZsCakWGf9c7jDXJicP3FPcIXUPBkuSeQ==
1789+
dependencies:
1790+
"@fastify/error" "^3.0.0"
1791+
fastify-plugin "^4.0.0"
1792+
17851793
"@fastify/cookie@^8.3.0":
17861794
version "8.3.0"
17871795
resolved "https://registry.yarnpkg.com/@fastify/cookie/-/cookie-8.3.0.tgz#7d3304fcf0d11ea64ae8e02d65ae217b01fe1cf4"
@@ -1798,7 +1806,7 @@
17981806
cookie-signature "^1.1.0"
17991807
fastify-plugin "^4.0.0"
18001808

1801-
"@fastify/error@^3.3.0", "@fastify/error@^3.4.0":
1809+
"@fastify/error@^3.0.0", "@fastify/error@^3.3.0", "@fastify/error@^3.4.0":
18021810
version "3.4.1"
18031811
resolved "https://registry.yarnpkg.com/@fastify/error/-/error-3.4.1.tgz#b14bb4cac3dd4ec614becbc643d1511331a6425c"
18041812
integrity sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==
@@ -2530,10 +2538,10 @@
25302538
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
25312539
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
25322540

2533-
"@prisma/client@^5.16.1":
2534-
version "5.16.1"
2535-
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.16.1.tgz#65c5649b4701c097e7fa943c91a3140ce8bf053d"
2536-
integrity sha512-wM9SKQjF0qLxdnOZIVAIMKiz6Hu7vDt4FFAih85K1dk/Rr2mdahy6d3QP41K62N9O0DJJA//gUDA3Mp49xsKIg==
2541+
"@prisma/client@5.17.0":
2542+
version "5.17.0"
2543+
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.17.0.tgz#9079947bd749689c2dabfb9ecc70a24ebefb1f43"
2544+
integrity sha512-N2tnyKayT0Zf7mHjwEyE8iG7FwTmXDHFZ1GnNhQp0pJUObsuel4ZZ1XwfuAYkq5mRIiC/Kot0kt0tGCfLJ70Jw==
25372545

25382546
"@prisma/debug@5.17.0":
25392547
version "5.17.0"
@@ -5349,10 +5357,10 @@ builtin-status-codes@^3.0.0:
53495357
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
53505358
integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==
53515359

5352-
bullmq@^5.10.3:
5353-
version "5.10.3"
5354-
resolved "https://registry.yarnpkg.com/bullmq/-/bullmq-5.10.3.tgz#655d5bc8621ad5fc78f94559206024e3b7639088"
5355-
integrity sha512-kJZTTPs5WNcNdkqyECXEckgXy7RZgf75emzbiJ+2Q4fKHDvLbeEnbveGwYxncNaJQMcsu6gjr6eHIgMMzD3gSw==
5360+
bullmq@^5.11.0:
5361+
version "5.11.0"
5362+
resolved "https://registry.yarnpkg.com/bullmq/-/bullmq-5.11.0.tgz#15c526d4a45453843b36cc34bdcaa5249772d22e"
5363+
integrity sha512-qVzyWGZqie3VHaYEgRXhId/j8ebfmj6MExEJyUByMsUJA5pVciVle3hKLer5fyMwtQ8lTMP7GwhXV/NZ+HzlRA==
53565364
dependencies:
53575365
cron-parser "^4.6.0"
53585366
ioredis "^5.4.1"

0 commit comments

Comments
 (0)