@lokalise/fastify-bullboard-plugin 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/basicAuth.d.ts +17 -1
- package/dist/basicAuth.js +50 -5
- package/dist/basicAuth.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,27 @@ await app.register(bullBoard, {
|
|
|
44
44
|
})
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
Each `enableList` entry protects that path and every route under it, so `'/bull'` covers the dashboard page,
|
|
48
|
+
its API (`/bull/api/queues/...`, including the job retry/clean/obliterate endpoints) and its static assets. It does
|
|
49
|
+
not cover routes that only share the string prefix, such as `/bullet`. A trailing slash makes no difference
|
|
50
|
+
(`'/bull/'` behaves like `'/bull'`), empty entries are ignored, and the root path `'/'` is matched exactly.
|
|
51
|
+
|
|
52
|
+
Entries are full route paths. If BullBoard is registered inside a plugin with its own prefix, list the full path,
|
|
53
|
+
e.g. `'/admin/bull'` for a `/bull` mount under `/admin`.
|
|
54
|
+
|
|
55
|
+
To protect everything by default instead, pass a `skipList` in place of `enableList`. Every route then requires
|
|
56
|
+
credentials, including the root redirect and unmatched URLs, except the listed route paths:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
await app.register(basicAuth, {
|
|
60
|
+
config: { isEnabled: true, username: 'username', password: 'pass' },
|
|
61
|
+
skipList: new Set(['/health', '/metrics']),
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`skipList` entries are matched exactly against the registered route path, so `'/health'` does not skip
|
|
66
|
+
`/health/deep`. Pass either `enableList` or `skipList`, not both.
|
|
67
|
+
|
|
47
68
|
## BullMQ Pro support
|
|
48
69
|
|
|
49
70
|
The plugin supports both standard BullMQ queues and BullMQ Pro queues, including mixing
|
package/dist/basicAuth.d.ts
CHANGED
|
@@ -5,7 +5,23 @@ export type AuthConfig = {
|
|
|
5
5
|
};
|
|
6
6
|
type BasicAuthOptions = {
|
|
7
7
|
config: AuthConfig;
|
|
8
|
+
} & ({
|
|
9
|
+
/**
|
|
10
|
+
* Paths that require basic auth. Each entry protects the path itself and every route under it,
|
|
11
|
+
* e.g. `/bull` (or `/bull/`) covers `/bull`, `/bull/api/queues` and `/bull/static/*`, but not `/bullet`.
|
|
12
|
+
* Entries are full route paths, so include any prefix the protected routes are registered under.
|
|
13
|
+
* The root path `/` is matched exactly, so it does not protect the whole app. Empty entries are ignored.
|
|
14
|
+
*/
|
|
8
15
|
enableList: Set<string>;
|
|
9
|
-
|
|
16
|
+
skipList?: never;
|
|
17
|
+
} | {
|
|
18
|
+
/**
|
|
19
|
+
* Route paths that do not require basic auth; every other route does, including unmatched ones.
|
|
20
|
+
* Entries are matched exactly against the registered route path, e.g. `/health` skips `/health` only,
|
|
21
|
+
* and `/users/:id` skips that parametric route.
|
|
22
|
+
*/
|
|
23
|
+
skipList: Set<string>;
|
|
24
|
+
enableList?: never;
|
|
25
|
+
});
|
|
10
26
|
export declare const basicAuth: import("fastify").FastifyPluginCallback<BasicAuthOptions, import("fastify").RawServerDefault, import("fastify").FastifyTypeProviderDefault, import("fastify").FastifyBaseLogger>;
|
|
11
27
|
export {};
|
package/dist/basicAuth.js
CHANGED
|
@@ -12,21 +12,66 @@ function validate(config) {
|
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
+
function toProtectedPaths(enableList) {
|
|
16
|
+
const exact = new Set();
|
|
17
|
+
const prefixes = [];
|
|
18
|
+
for (const entry of enableList) {
|
|
19
|
+
if (entry === '')
|
|
20
|
+
continue;
|
|
21
|
+
const path = entry.replace(/\/+$/, '');
|
|
22
|
+
// The root is matched exactly: as a prefix it would put auth on every route, health checks included
|
|
23
|
+
if (path === '') {
|
|
24
|
+
exact.add('/');
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
exact.add(path);
|
|
28
|
+
prefixes.push(`${path}/`);
|
|
29
|
+
}
|
|
30
|
+
return { exact, prefixes };
|
|
31
|
+
}
|
|
32
|
+
function requiresAuth(url, protectedPaths) {
|
|
33
|
+
if (!url)
|
|
34
|
+
return false;
|
|
35
|
+
if (protectedPaths.exact.has(url))
|
|
36
|
+
return true;
|
|
37
|
+
return protectedPaths.prefixes.some((prefix) => url.startsWith(prefix));
|
|
38
|
+
}
|
|
15
39
|
function enableListAuthHandler(enableList) {
|
|
40
|
+
const protectedPaths = toProtectedPaths(enableList);
|
|
41
|
+
return (req, _res, done) => {
|
|
42
|
+
if (!requiresAuth(req.routeOptions.url, protectedPaths)) {
|
|
43
|
+
return done(); // success: skip the rest of the handlers
|
|
44
|
+
}
|
|
45
|
+
// Matching by prefix, not exact route, is what keeps BullBoard's API routes under /bull/ protected.
|
|
46
|
+
// Fail here to go to the next handler (basicAuth). String for performance, it also works
|
|
47
|
+
return done('Needs auth');
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function skipListAuthHandler(skipList) {
|
|
16
51
|
return (req, _res, done) => {
|
|
17
|
-
|
|
18
|
-
if (!req.routeOptions.url || !enableList.has(req.routeOptions.url)) {
|
|
52
|
+
if (req.routeOptions.url && skipList.has(req.routeOptions.url)) {
|
|
19
53
|
return done(); // success: skip the rest of the handlers
|
|
20
54
|
}
|
|
21
|
-
//
|
|
22
|
-
// String for performance, it also works
|
|
55
|
+
// Fail here to go to the next handler (basicAuth). String for performance, it also works
|
|
23
56
|
return done('Needs auth');
|
|
24
57
|
};
|
|
25
58
|
}
|
|
59
|
+
function resolveAccessHandler(pluginOptions) {
|
|
60
|
+
const { enableList, skipList } = pluginOptions;
|
|
61
|
+
if (enableList && skipList) {
|
|
62
|
+
throw new Error('basic-auth: enableList and skipList are mutually exclusive, pass only one');
|
|
63
|
+
}
|
|
64
|
+
if (skipList)
|
|
65
|
+
return skipListAuthHandler(skipList);
|
|
66
|
+
if (enableList)
|
|
67
|
+
return enableListAuthHandler(enableList);
|
|
68
|
+
throw new Error('basic-auth: either enableList or skipList is required');
|
|
69
|
+
}
|
|
26
70
|
async function plugin(fastify, pluginOptions) {
|
|
27
71
|
if (!pluginOptions.config.isEnabled) {
|
|
28
72
|
return;
|
|
29
73
|
}
|
|
74
|
+
const accessHandler = resolveAccessHandler(pluginOptions);
|
|
30
75
|
if (!fastify.auth) {
|
|
31
76
|
await fastify.register(fastifyAuth);
|
|
32
77
|
}
|
|
@@ -35,7 +80,7 @@ async function plugin(fastify, pluginOptions) {
|
|
|
35
80
|
authenticate: true,
|
|
36
81
|
});
|
|
37
82
|
fastify.after(() => {
|
|
38
|
-
fastify.addHook('onRequest', fastify.auth([
|
|
83
|
+
fastify.addHook('onRequest', fastify.auth([accessHandler, fastify.basicAuth]));
|
|
39
84
|
});
|
|
40
85
|
}
|
|
41
86
|
export const basicAuth = fp(plugin, {
|
package/dist/basicAuth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basicAuth.js","sourceRoot":"","sources":["../src/basicAuth.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,gBAAgB,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"basicAuth.js","sourceRoot":"","sources":["../src/basicAuth.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,gBAAgB,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAgC/B,SAAS,QAAQ,CAAC,MAAkB;IAClC,OAAO,CACL,QAAgB,EAChB,QAAgB,EAChB,IAAoB,EACpB,MAAoB,EACpB,IAA2B,EAC3B,EAAE;QACF,IAAI,QAAQ,KAAK,MAAM,CAAC,QAAQ,IAAI,QAAQ,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjE,IAAI,EAAE,CAAA;QACR,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,eAAe,EAAE,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAOD,SAAS,gBAAgB,CAAC,UAAuB;IAC/C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAA;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAA;IAE7B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,KAAK,KAAK,EAAE;YAAE,SAAQ;QAE1B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACtC,oGAAoG;QACpG,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACd,SAAQ;QACV,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACf,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,GAAuB,EAAE,cAA8B;IAC3E,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAA;IACtB,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9C,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;AACzE,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAuB;IACpD,MAAM,cAAc,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;IAEnD,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACzB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC;YACxD,OAAO,IAAI,EAAE,CAAA,CAAC,yCAAyC;QACzD,CAAC;QACD,oGAAoG;QACpG,yFAAyF;QACzF,OAAO,IAAI,CAAC,YAAgC,CAAC,CAAA;IAC/C,CAAC,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAqB;IAChD,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QACzB,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,EAAE,CAAA,CAAC,yCAAyC;QACzD,CAAC;QACD,yFAAyF;QACzF,OAAO,IAAI,CAAC,YAAgC,CAAC,CAAA;IAC/C,CAAC,CAAA;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,aAA+B;IAC3D,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAA;IAC9C,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;IAC9F,CAAC;IACD,IAAI,QAAQ;QAAE,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAA;IAClD,IAAI,UAAU;QAAE,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAA;IACxD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;AAC1E,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,OAAwB,EAAE,aAA+B;IAC7E,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACpC,OAAM;IACR,CAAC;IAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAA;IAEzD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IACrC,CAAC;IACD,MAAM,OAAO,CAAC,QAAQ,CAAC,gBAAgB,EAAE;QACvC,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IAEF,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;QACjB,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAChF,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAmB,MAAM,EAAE;IACpD,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,YAAY;CACnB,CAAC,CAAA"}
|