@darthcav/ts-http-server 0.5.1 → 0.6.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 +58 -8
- package/dist/__tests__/defaultPlugins.test.js +47 -2
- package/dist/__tests__/defaultPlugins.test.js.map +1 -1
- package/dist/__tests__/defaultRoutes.test.js +226 -1
- package/dist/__tests__/defaultRoutes.test.js.map +1 -1
- package/dist/__tests__/keycloak.test.d.ts +2 -0
- package/dist/__tests__/keycloak.test.d.ts.map +1 -0
- package/dist/__tests__/keycloak.test.js +105 -0
- package/dist/__tests__/keycloak.test.js.map +1 -0
- package/dist/__tests__/launcher.test.js +34 -0
- package/dist/__tests__/launcher.test.js.map +1 -1
- package/dist/auth/keycloak.d.ts +17 -0
- package/dist/auth/keycloak.d.ts.map +1 -0
- package/dist/auth/keycloak.js +35 -0
- package/dist/auth/keycloak.js.map +1 -0
- package/dist/defaults/defaultPlugins.d.ts +12 -7
- package/dist/defaults/defaultPlugins.d.ts.map +1 -1
- package/dist/defaults/defaultPlugins.js +109 -2
- package/dist/defaults/defaultPlugins.js.map +1 -1
- package/dist/defaults/defaultRoutes.d.ts +5 -0
- package/dist/defaults/defaultRoutes.d.ts.map +1 -1
- package/dist/defaults/defaultRoutes.js +30 -0
- package/dist/defaults/defaultRoutes.js.map +1 -1
- package/dist/hooks/authPreHandler.d.ts +19 -0
- package/dist/hooks/authPreHandler.d.ts.map +1 -0
- package/dist/hooks/authPreHandler.js +32 -0
- package/dist/hooks/authPreHandler.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/launcher.d.ts +2 -2
- package/dist/launcher.d.ts.map +1 -1
- package/dist/launcher.js +7 -2
- package/dist/launcher.js.map +1 -1
- package/dist/start.js +34 -5
- package/dist/start.js.map +1 -1
- package/dist/types.d.ts +64 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -3
- package/src/auth/keycloak.ts +43 -0
- package/src/defaults/defaultPlugins.ts +141 -7
- package/src/defaults/defaultRoutes.ts +30 -1
- package/src/hooks/authPreHandler.ts +41 -0
- package/src/index.ts +7 -0
- package/src/launcher.ts +11 -1
- package/src/openapi/api.yaml +150 -0
- package/src/openapi/schemas/Error.yaml +14 -0
- package/src/start.ts +44 -5
- package/src/types.ts +71 -2
- package/src/views/index.ejs +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.test.js","sourceRoot":"","sources":["../../src/__tests__/launcher.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAGrC,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E,MAAM,IAAI,GAAG,GAAS,EAAE,GAAE,CAAC,CAAA;AAC3B,MAAM,UAAU,GAAG;IACf,QAAQ,EAAE,CAAC,MAAM,CAAC;IAClB,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU;CACR,CAAA;AAEtB,8EAA8E;AAC9E,sDAAsD;AACtD,8EAA8E;AAE9E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAoB;IACvC,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;CACnD,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAuB;IACzC;QACI,SAAS;QACT;YACI,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,GAAG;YACR,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;SAC/D;KACJ;IACD;QACI,UAAU;QACV;YACI,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;YAC1C,GAAG,EAAE,GAAG;YACR,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;gBAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;gBAClC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAA;YACtD,CAAC;SACJ;KACJ;IACD;QACI,aAAa;QACb;YACI,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,QAAQ;YACb,OAAO,EAAE,KAAK,IAAI,EAAE;gBAChB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;YACxC,CAAC;SACJ;KACJ;CACJ,CAAC,CAAA;AAEF,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,KAAK,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAA;IAClB,MAAM,IAAI,GAAG,oBAAoB,IAAI,EAAE,CAAA;IACvC,IAAI,MAAyC,CAAA;IAE7C,MAAM,CAAC,KAAK,IAAI,EAAE;QACd,MAAM,GAAG,QAAQ,CAAC;YACd,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,EAAE,IAAI,EAAE;YAChB,OAAO;YACP,MAAM;YACN,IAAI,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE;SACxC,CAAC,CAAA;QACF,MAAM,UAAU,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,KAAK,IAAI,EAAE;QACb,MAAM,UAAU,CAAC,GAAG,CAAC,CAAA;QACrB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;QACnC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoB,CAAA;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IACxB,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;QAC5B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QACvD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,UAAU,EAAE;YACvC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SAC1C,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtB,KAAK,CACD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAC/B,iCAAiC,CACpC,CAAA;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAA;QACzD,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACnB,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,UAAU,EAAE;YACvC,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;SACpC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE;YACrC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SAC1C,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE;YACrC,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;SACpC,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"launcher.test.js","sourceRoot":"","sources":["../../src/__tests__/launcher.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { KeycloakAuthConfig, TokenVerifier } from "../types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a JWT token verifier backed by a Keycloak realm's JWKS endpoint.
|
|
4
|
+
*
|
|
5
|
+
* The JWKS keys are fetched lazily on the first verification request and
|
|
6
|
+
* cached; key rotation is handled automatically by `jose`.
|
|
7
|
+
*
|
|
8
|
+
* The verifier extracts the bearer token from the `Authorization` header,
|
|
9
|
+
* verifies the JWT signature against the realm's public keys, and validates
|
|
10
|
+
* the issuer claim. Any verification failure returns `false` without throwing.
|
|
11
|
+
*
|
|
12
|
+
* @param config - Keycloak realm and client configuration.
|
|
13
|
+
* @returns An async {@link TokenVerifier} that returns `true` if the bearer
|
|
14
|
+
* JWT is valid, `false` otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createKeycloakVerifier(config: KeycloakAuthConfig): TokenVerifier;
|
|
17
|
+
//# sourceMappingURL=keycloak.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycloak.d.ts","sourceRoot":"","sources":["../../src/auth/keycloak.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEpE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,kBAAkB,GAC3B,aAAa,CAuBf"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a JWT token verifier backed by a Keycloak realm's JWKS endpoint.
|
|
4
|
+
*
|
|
5
|
+
* The JWKS keys are fetched lazily on the first verification request and
|
|
6
|
+
* cached; key rotation is handled automatically by `jose`.
|
|
7
|
+
*
|
|
8
|
+
* The verifier extracts the bearer token from the `Authorization` header,
|
|
9
|
+
* verifies the JWT signature against the realm's public keys, and validates
|
|
10
|
+
* the issuer claim. Any verification failure returns `false` without throwing.
|
|
11
|
+
*
|
|
12
|
+
* @param config - Keycloak realm and client configuration.
|
|
13
|
+
* @returns An async {@link TokenVerifier} that returns `true` if the bearer
|
|
14
|
+
* JWT is valid, `false` otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export function createKeycloakVerifier(config) {
|
|
17
|
+
const baseUrl = config.url.replace(/\/$/, "");
|
|
18
|
+
const jwksUri = new URL(`/realms/${config.realm}/protocol/openid-connect/certs`, baseUrl);
|
|
19
|
+
const JWKS = createRemoteJWKSet(jwksUri);
|
|
20
|
+
const issuer = `${baseUrl}/realms/${config.realm}`;
|
|
21
|
+
return async function verifyToken(authorizationHeader) {
|
|
22
|
+
if (!authorizationHeader?.startsWith("Bearer ")) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const token = authorizationHeader.slice(7);
|
|
26
|
+
try {
|
|
27
|
+
await jwtVerify(token, JWKS, { issuer });
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=keycloak.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycloak.js","sourceRoot":"","sources":["../../src/auth/keycloak.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAGpD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAClC,MAA0B;IAE1B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,CACnB,WAAW,MAAM,CAAC,KAAK,gCAAgC,EACvD,OAAO,CACV,CAAA;IACD,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,GAAG,OAAO,WAAW,MAAM,CAAC,KAAK,EAAE,CAAA;IAElD,OAAO,KAAK,UAAU,WAAW,CAC7B,mBAAuC;QAEvC,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAA;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1C,IAAI,CAAC;YACD,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YACxC,OAAO,IAAI,CAAA;QACf,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAA;QAChB,CAAC;IACL,CAAC,CAAA;AACL,CAAC"}
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DefaultPluginsOptions, FSTPlugin } from "../types.ts";
|
|
2
2
|
/**
|
|
3
3
|
* Builds the default plugin map for use with `launcher`.
|
|
4
4
|
*
|
|
5
5
|
* Registers: `@fastify/accepts`, `@fastify/compress`,
|
|
6
6
|
* `@fastify/cors`, `@fastify/etag`, `@fastify/helmet`,
|
|
7
|
-
* `@fastify/view` (EJS),
|
|
7
|
+
* `@fastify/view` (EJS), `@fastify/static`, `@fastify/swagger`,
|
|
8
|
+
* and `@fastify/swagger-ui`.
|
|
9
|
+
*
|
|
10
|
+
* Synchronously reads and resolves all `$ref` schema files from
|
|
11
|
+
* `src/openapi/schemas/` before building the plugin map, so `@fastify/swagger`
|
|
12
|
+
* receives a fully inlined document.
|
|
8
13
|
*
|
|
9
14
|
* @param opts.locals - Application locals; `locals.pkg` is exposed as the
|
|
10
15
|
* default context for every EJS view.
|
|
11
|
-
* @param opts.baseDir - Optional base directory for resolving the `src/`
|
|
16
|
+
* @param opts.baseDir - Optional base directory for resolving the `src/`
|
|
17
|
+
* folder; defaults to the parent of `import.meta.dirname`.
|
|
18
|
+
* @param opts.keycloakAuth - Optional Keycloak configuration used to mark the
|
|
19
|
+
* generated `/api/` OpenAPI operations as OpenID Connect–protected.
|
|
12
20
|
* @returns A `Map` of plugin names to plugin entries, suitable for passing as
|
|
13
21
|
* the `plugins` field of `LauncherOptions`.
|
|
14
22
|
*/
|
|
15
|
-
export default function defaultPlugins(opts:
|
|
16
|
-
locals: LauncherLocals;
|
|
17
|
-
baseDir?: string | null;
|
|
18
|
-
}): Map<string, FSTPlugin>;
|
|
23
|
+
export default function defaultPlugins(opts: DefaultPluginsOptions): Map<string, FSTPlugin>;
|
|
19
24
|
//# sourceMappingURL=defaultPlugins.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultPlugins.d.ts","sourceRoot":"","sources":["../../src/defaults/defaultPlugins.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"defaultPlugins.d.ts","sourceRoot":"","sources":["../../src/defaults/defaultPlugins.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACR,qBAAqB,EACrB,SAAS,EAEZ,MAAM,aAAa,CAAA;AAwEpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAClC,IAAI,EAAE,qBAAqB,GAC5B,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CA8GxB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import FastifyAccepts from "@fastify/accepts";
|
|
3
4
|
import FastifyCompress from "@fastify/compress";
|
|
@@ -5,18 +6,84 @@ import FastifyCors from "@fastify/cors";
|
|
|
5
6
|
import FastifyEtag from "@fastify/etag";
|
|
6
7
|
import FastifyHelmet from "@fastify/helmet";
|
|
7
8
|
import FastifyStatic from "@fastify/static";
|
|
9
|
+
import FastifySwagger from "@fastify/swagger";
|
|
10
|
+
import FastifySwaggerUi from "@fastify/swagger-ui";
|
|
8
11
|
import FastifyView from "@fastify/view";
|
|
9
12
|
import Ejs from "ejs";
|
|
13
|
+
import { parse } from "yaml";
|
|
14
|
+
function configureApiDocumentAuth(apiDoc, keycloakAuth) {
|
|
15
|
+
if (!apiDoc.paths) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const apiPath = apiDoc.paths["/api/"];
|
|
19
|
+
if (!apiPath) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (keycloakAuth) {
|
|
23
|
+
const baseUrl = keycloakAuth.url.replace(/\/$/, "");
|
|
24
|
+
const openIdConnectUrl = `${baseUrl}/realms/${keycloakAuth.realm}/.well-known/openid-configuration`;
|
|
25
|
+
apiDoc.components ??= {};
|
|
26
|
+
apiDoc.components.securitySchemes = {
|
|
27
|
+
openIdConnect: {
|
|
28
|
+
type: "openIdConnect",
|
|
29
|
+
openIdConnectUrl,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
apiDoc.security = [{ openIdConnect: [] }];
|
|
33
|
+
for (const operation of Object.values(apiPath)) {
|
|
34
|
+
if (!operation ||
|
|
35
|
+
typeof operation !== "object" ||
|
|
36
|
+
!("responses" in operation)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
operation.security = [{ openIdConnect: [] }];
|
|
40
|
+
operation.responses ??= {};
|
|
41
|
+
operation.responses["401"] = {
|
|
42
|
+
description: "Unauthorized",
|
|
43
|
+
content: {
|
|
44
|
+
"application/json": {
|
|
45
|
+
schema: { $ref: "#/components/schemas/Error" },
|
|
46
|
+
examples: {
|
|
47
|
+
"401": { $ref: "#/components/examples/http_401" },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
delete apiDoc.security;
|
|
56
|
+
if (apiDoc.components?.securitySchemes) {
|
|
57
|
+
delete apiDoc.components.securitySchemes["openIdConnect"];
|
|
58
|
+
}
|
|
59
|
+
for (const operation of Object.values(apiPath)) {
|
|
60
|
+
if (!operation ||
|
|
61
|
+
typeof operation !== "object" ||
|
|
62
|
+
!("responses" in operation)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
delete operation.security;
|
|
66
|
+
delete operation.responses?.["401"];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
10
69
|
/**
|
|
11
70
|
* Builds the default plugin map for use with `launcher`.
|
|
12
71
|
*
|
|
13
72
|
* Registers: `@fastify/accepts`, `@fastify/compress`,
|
|
14
73
|
* `@fastify/cors`, `@fastify/etag`, `@fastify/helmet`,
|
|
15
|
-
* `@fastify/view` (EJS),
|
|
74
|
+
* `@fastify/view` (EJS), `@fastify/static`, `@fastify/swagger`,
|
|
75
|
+
* and `@fastify/swagger-ui`.
|
|
76
|
+
*
|
|
77
|
+
* Synchronously reads and resolves all `$ref` schema files from
|
|
78
|
+
* `src/openapi/schemas/` before building the plugin map, so `@fastify/swagger`
|
|
79
|
+
* receives a fully inlined document.
|
|
16
80
|
*
|
|
17
81
|
* @param opts.locals - Application locals; `locals.pkg` is exposed as the
|
|
18
82
|
* default context for every EJS view.
|
|
19
|
-
* @param opts.baseDir - Optional base directory for resolving the `src/`
|
|
83
|
+
* @param opts.baseDir - Optional base directory for resolving the `src/`
|
|
84
|
+
* folder; defaults to the parent of `import.meta.dirname`.
|
|
85
|
+
* @param opts.keycloakAuth - Optional Keycloak configuration used to mark the
|
|
86
|
+
* generated `/api/` OpenAPI operations as OpenID Connect–protected.
|
|
20
87
|
* @returns A `Map` of plugin names to plugin entries, suitable for passing as
|
|
21
88
|
* the `plugins` field of `LauncherOptions`.
|
|
22
89
|
*/
|
|
@@ -26,6 +93,18 @@ export default function defaultPlugins(opts) {
|
|
|
26
93
|
const srcDir = baseDir
|
|
27
94
|
? join(baseDir, "src")
|
|
28
95
|
: join(import.meta.dirname, "..");
|
|
96
|
+
const apiDoc = parse(readFileSync(join(srcDir, "openapi", "api.yaml"), "utf8"));
|
|
97
|
+
const schemas = apiDoc.components?.schemas;
|
|
98
|
+
if (schemas) {
|
|
99
|
+
for (const key of Object.keys(schemas)) {
|
|
100
|
+
const schema = schemas[key];
|
|
101
|
+
if (schema && "$ref" in schema) {
|
|
102
|
+
const refPath = join(srcDir, "openapi", schema.$ref);
|
|
103
|
+
schemas[key] = parse(readFileSync(refPath, "utf8"));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
configureApiDocumentAuth(apiDoc, opts.keycloakAuth);
|
|
29
108
|
plugins.set("@fastify/accepts", {
|
|
30
109
|
plugin: FastifyAccepts,
|
|
31
110
|
});
|
|
@@ -46,6 +125,7 @@ export default function defaultPlugins(opts) {
|
|
|
46
125
|
global: true,
|
|
47
126
|
contentSecurityPolicy: {
|
|
48
127
|
directives: {
|
|
128
|
+
connectSrc: ["'self'", "https://cdn.jsdelivr.net/"],
|
|
49
129
|
fontSrc: [
|
|
50
130
|
"'self'",
|
|
51
131
|
"https://fonts.googleapis.com/",
|
|
@@ -79,6 +159,33 @@ export default function defaultPlugins(opts) {
|
|
|
79
159
|
prefix: "/",
|
|
80
160
|
},
|
|
81
161
|
});
|
|
162
|
+
plugins.set("@fastify/swagger", {
|
|
163
|
+
plugin: FastifySwagger,
|
|
164
|
+
opts: {
|
|
165
|
+
mode: "static",
|
|
166
|
+
specification: { document: apiDoc },
|
|
167
|
+
exposeRoute: true,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
plugins.set("@fastify/swagger-ui", {
|
|
171
|
+
plugin: FastifySwaggerUi,
|
|
172
|
+
opts: {
|
|
173
|
+
routePrefix: "/docs",
|
|
174
|
+
uiConfig: {
|
|
175
|
+
deepLinking: true,
|
|
176
|
+
docExpansion: "list",
|
|
177
|
+
dom_id: "#swagger-ui",
|
|
178
|
+
jsonEditor: true,
|
|
179
|
+
showRequestHeaders: true,
|
|
180
|
+
tryItOutEnabled: false,
|
|
181
|
+
onComplete: () => {
|
|
182
|
+
// @ts-expect-error — runs in browser context, not Node
|
|
183
|
+
const topbar = document.querySelector("div.topbar");
|
|
184
|
+
topbar?.remove();
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
});
|
|
82
189
|
return plugins;
|
|
83
190
|
}
|
|
84
191
|
//# sourceMappingURL=defaultPlugins.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultPlugins.js","sourceRoot":"","sources":["../../src/defaults/defaultPlugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAC7C,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAC/C,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAC3C,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAC3C,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,GAAG,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"defaultPlugins.js","sourceRoot":"","sources":["../../src/defaults/defaultPlugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,11 @@ import type { RouteOptions } from "fastify";
|
|
|
5
5
|
* Registers:
|
|
6
6
|
* - `GET /` — renders `index.ejs` for `text/html`, throws 406 otherwise.
|
|
7
7
|
* - `DELETE|PATCH|POST|PUT|OPTIONS /` — responds with 405 Method Not Allowed.
|
|
8
|
+
* - `GET /api/` — returns a JSON welcome message.
|
|
9
|
+
* - `DELETE|PATCH|POST|PUT /api/` — responds with 405 Method Not Allowed.
|
|
10
|
+
*
|
|
11
|
+
* Authentication is handled globally by the `preHandler` hook registered in
|
|
12
|
+
* {@link launcher} when `locals.authPaths` is set.
|
|
8
13
|
*/
|
|
9
14
|
export default function defaultRoutes(): Map<string, RouteOptions>;
|
|
10
15
|
//# sourceMappingURL=defaultRoutes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultRoutes.d.ts","sourceRoot":"","sources":["../../src/defaults/defaultRoutes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C
|
|
1
|
+
{"version":3,"file":"defaultRoutes.d.ts","sourceRoot":"","sources":["../../src/defaults/defaultRoutes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAuDjE"}
|
|
@@ -5,6 +5,11 @@ import { methodNotAllowed, notAcceptable } from "@hapi/boom";
|
|
|
5
5
|
* Registers:
|
|
6
6
|
* - `GET /` — renders `index.ejs` for `text/html`, throws 406 otherwise.
|
|
7
7
|
* - `DELETE|PATCH|POST|PUT|OPTIONS /` — responds with 405 Method Not Allowed.
|
|
8
|
+
* - `GET /api/` — returns a JSON welcome message.
|
|
9
|
+
* - `DELETE|PATCH|POST|PUT /api/` — responds with 405 Method Not Allowed.
|
|
10
|
+
*
|
|
11
|
+
* Authentication is handled globally by the `preHandler` hook registered in
|
|
12
|
+
* {@link launcher} when `locals.authPaths` is set.
|
|
8
13
|
*/
|
|
9
14
|
export default function defaultRoutes() {
|
|
10
15
|
const routes = new Map();
|
|
@@ -33,6 +38,31 @@ export default function defaultRoutes() {
|
|
|
33
38
|
throw methodNotAllowed();
|
|
34
39
|
},
|
|
35
40
|
});
|
|
41
|
+
routes.set("API_INDEX", {
|
|
42
|
+
method: "GET",
|
|
43
|
+
url: "/api/",
|
|
44
|
+
exposeHeadRoute: true,
|
|
45
|
+
handler: async (request, reply) => {
|
|
46
|
+
const { locals } = request.server;
|
|
47
|
+
const accept = request.accepts();
|
|
48
|
+
switch (accept.type(["json"])) {
|
|
49
|
+
case "json":
|
|
50
|
+
return reply.type("application/json").send({
|
|
51
|
+
message: `Welcome to the index page of the server API :: ${locals.pkg?.["name"]}`,
|
|
52
|
+
});
|
|
53
|
+
default:
|
|
54
|
+
throw notAcceptable();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
routes.set("API_INDEX_405", {
|
|
59
|
+
method: ["DELETE", "PATCH", "POST", "PUT"],
|
|
60
|
+
url: "/api/",
|
|
61
|
+
handler: async (_request, reply) => {
|
|
62
|
+
reply.header("allow", "GET, HEAD");
|
|
63
|
+
throw methodNotAllowed();
|
|
64
|
+
},
|
|
65
|
+
});
|
|
36
66
|
return routes;
|
|
37
67
|
}
|
|
38
68
|
//# sourceMappingURL=defaultRoutes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultRoutes.js","sourceRoot":"","sources":["../../src/defaults/defaultRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG5D
|
|
1
|
+
{"version":3,"file":"defaultRoutes.js","sourceRoot":"","sources":["../../src/defaults/defaultRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG5D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAA;IAE9C,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE;QAChB,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,GAAG;QACR,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;YAChC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC5B,KAAK,MAAM;oBACP,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;wBAC7C,SAAS,EAAE,OAAO;wBAClB,MAAM,EAAE,cAAc;qBACzB,CAAC,CAAA;gBACN;oBACI,MAAM,aAAa,EAAE,CAAA;YAC7B,CAAC;QACL,CAAC;KACJ,CAAC,CAAA;IACF,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE;QACpB,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;QACrD,GAAG,EAAE,GAAG;QACR,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YAClC,MAAM,gBAAgB,EAAE,CAAA;QAC5B,CAAC;KACJ,CAAC,CAAA;IACF,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE;QACpB,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,OAAO;QACZ,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;YACjC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;YAChC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC5B,KAAK,MAAM;oBACP,OAAO,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;wBACvC,OAAO,EAAE,kDAAkD,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE;qBACpF,CAAC,CAAA;gBACN;oBACI,MAAM,aAAa,EAAE,CAAA;YAC7B,CAAC;QACL,CAAC;KACJ,CAAC,CAAA;IACF,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE;QACxB,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;QAC1C,GAAG,EAAE,OAAO;QACZ,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YAClC,MAAM,gBAAgB,EAAE,CAAA;QAC5B,CAAC;KACJ,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
2
|
+
/**
|
|
3
|
+
* Factory that creates a Fastify `preHandler` hook enforcing bearer-token
|
|
4
|
+
* authentication on any route whose URL matches one of the given glob patterns.
|
|
5
|
+
*
|
|
6
|
+
* The returned hook is intended to be registered globally via
|
|
7
|
+
* `fastify.addHook("preHandler", createAuthPreHandler(authPaths))`.
|
|
8
|
+
* For every request, `request.routeOptions.url` is tested against the compiled
|
|
9
|
+
* picomatch matcher; non-matching routes pass through unconditionally.
|
|
10
|
+
*
|
|
11
|
+
* When a route is protected, token verification is delegated to the
|
|
12
|
+
* `verifyToken` decorator registered on the Fastify instance.
|
|
13
|
+
*
|
|
14
|
+
* @param authPaths - Array of picomatch glob patterns (e.g. `["/api/**"]`).
|
|
15
|
+
* @param realm - Protection-space label used in the `WWW-Authenticate` challenge
|
|
16
|
+
* (RFC 6750). Typically the Keycloak realm name. Defaults to `"api"`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAuthPreHandler(authPaths: string[], realm?: string): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
19
|
+
//# sourceMappingURL=authPreHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authPreHandler.d.ts","sourceRoot":"","sources":["../../src/hooks/authPreHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG3D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAChC,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,SAAQ,GACd,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAiBjE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { unauthorized } from "@hapi/boom";
|
|
2
|
+
import picomatch from "picomatch";
|
|
3
|
+
/**
|
|
4
|
+
* Factory that creates a Fastify `preHandler` hook enforcing bearer-token
|
|
5
|
+
* authentication on any route whose URL matches one of the given glob patterns.
|
|
6
|
+
*
|
|
7
|
+
* The returned hook is intended to be registered globally via
|
|
8
|
+
* `fastify.addHook("preHandler", createAuthPreHandler(authPaths))`.
|
|
9
|
+
* For every request, `request.routeOptions.url` is tested against the compiled
|
|
10
|
+
* picomatch matcher; non-matching routes pass through unconditionally.
|
|
11
|
+
*
|
|
12
|
+
* When a route is protected, token verification is delegated to the
|
|
13
|
+
* `verifyToken` decorator registered on the Fastify instance.
|
|
14
|
+
*
|
|
15
|
+
* @param authPaths - Array of picomatch glob patterns (e.g. `["/api/**"]`).
|
|
16
|
+
* @param realm - Protection-space label used in the `WWW-Authenticate` challenge
|
|
17
|
+
* (RFC 6750). Typically the Keycloak realm name. Defaults to `"api"`.
|
|
18
|
+
*/
|
|
19
|
+
export function createAuthPreHandler(authPaths, realm = "api") {
|
|
20
|
+
const isProtected = picomatch(authPaths);
|
|
21
|
+
return async function authPreHandler(request, reply) {
|
|
22
|
+
if (!isProtected(request.routeOptions.url ?? "")) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const isAuthorized = await request.server.verifyToken(request.headers.authorization);
|
|
26
|
+
if (!isAuthorized) {
|
|
27
|
+
reply.header("www-authenticate", `Bearer realm="${realm}"`);
|
|
28
|
+
throw unauthorized("Missing or invalid bearer token");
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=authPreHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authPreHandler.js","sourceRoot":"","sources":["../../src/hooks/authPreHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAChC,SAAmB,EACnB,KAAK,GAAG,KAAK;IAEb,MAAM,WAAW,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IACxC,OAAO,KAAK,UAAU,cAAc,CAChC,OAAuB,EACvB,KAAmB;QAEnB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/C,OAAM;QACV,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,CACjD,OAAO,CAAC,OAAO,CAAC,aAAa,CAChC,CAAA;QACD,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,iBAAiB,KAAK,GAAG,CAAC,CAAA;YAC3D,MAAM,YAAY,CAAC,iCAAiC,CAAC,CAAA;QACzD,CAAC;IACL,CAAC,CAAA;AACL,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,9 +7,11 @@ import defaultErrorHandler from "./defaults/defaultErrorHandler.ts";
|
|
|
7
7
|
import defaultFastifyOptions from "./defaults/defaultFastifyOptions.ts";
|
|
8
8
|
import defaultPlugins from "./defaults/defaultPlugins.ts";
|
|
9
9
|
import defaultRoutes from "./defaults/defaultRoutes.ts";
|
|
10
|
+
import { createAuthPreHandler } from "./hooks/authPreHandler.ts";
|
|
10
11
|
import onResponse from "./hooks/onResponse.ts";
|
|
11
12
|
import preHandler from "./hooks/preHandler.ts";
|
|
12
13
|
import launcher from "./launcher.ts";
|
|
13
|
-
export
|
|
14
|
-
export {
|
|
14
|
+
export { createKeycloakVerifier } from "./auth/keycloak.ts";
|
|
15
|
+
export type { DefaultPluginsOptions, FSTPlugin, KeycloakAuthConfig, LauncherLocals, LauncherOptions, TokenVerifier, } from "./types.ts";
|
|
16
|
+
export { createAuthPreHandler, defaultErrorHandler, defaultFastifyOptions, defaultPlugins, defaultRoutes, launcher, onResponse, preHandler, };
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,aAAa,MAAM,6BAA6B,CAAA;AACvD,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,QAAQ,MAAM,eAAe,CAAA;AAEpC,YAAY,EACR,SAAS,EACT,cAAc,EACd,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,aAAa,MAAM,6BAA6B,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,QAAQ,MAAM,eAAe,CAAA;AAEpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,YAAY,EACR,qBAAqB,EACrB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,aAAa,GAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,GACb,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,10 @@ import defaultErrorHandler from "./defaults/defaultErrorHandler.js";
|
|
|
7
7
|
import defaultFastifyOptions from "./defaults/defaultFastifyOptions.js";
|
|
8
8
|
import defaultPlugins from "./defaults/defaultPlugins.js";
|
|
9
9
|
import defaultRoutes from "./defaults/defaultRoutes.js";
|
|
10
|
+
import { createAuthPreHandler } from "./hooks/authPreHandler.js";
|
|
10
11
|
import onResponse from "./hooks/onResponse.js";
|
|
11
12
|
import preHandler from "./hooks/preHandler.js";
|
|
12
13
|
import launcher from "./launcher.js";
|
|
13
|
-
export {
|
|
14
|
+
export { createKeycloakVerifier } from "./auth/keycloak.js";
|
|
15
|
+
export { createAuthPreHandler, defaultErrorHandler, defaultFastifyOptions, defaultPlugins, defaultRoutes, launcher, onResponse, preHandler, };
|
|
14
16
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,aAAa,MAAM,6BAA6B,CAAA;AACvD,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,QAAQ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,OAAO,aAAa,MAAM,6BAA6B,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,UAAU,MAAM,uBAAuB,CAAA;AAC9C,OAAO,QAAQ,MAAM,eAAe,CAAA;AAEpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAU3D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,UAAU,EACV,UAAU,GACb,CAAA"}
|
package/dist/launcher.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { LauncherOptions } from "./types.ts";
|
|
|
5
5
|
*
|
|
6
6
|
* Steps performed:
|
|
7
7
|
* 1. Creates a `FastifyInstance` merging {@link defaultFastifyOptions} with `opts`.
|
|
8
|
-
* 2. Decorates the instance with `locals` and any extra `decorators`.
|
|
8
|
+
* 2. Decorates the instance with `locals`, `verifyToken`, and any extra `decorators`.
|
|
9
9
|
* 3. Registers all `plugins` and `routes`.
|
|
10
10
|
* 4. Sets a `notFound` handler (throws Boom 404) and {@link defaultErrorHandler}.
|
|
11
11
|
* 5. Registers {@link preHandler} and {@link onResponse} hooks.
|
|
@@ -13,5 +13,5 @@ import type { LauncherOptions } from "./types.ts";
|
|
|
13
13
|
*
|
|
14
14
|
* @returns The `FastifyInstance` (e.g. for use with `fastify.close()`).
|
|
15
15
|
*/
|
|
16
|
-
export default function launcher({ logger, locals, plugins, routes, decorators, opts, done, }: LauncherOptions): FastifyInstance;
|
|
16
|
+
export default function launcher({ logger, locals, plugins, routes, decorators, verifyToken, opts, done, }: LauncherOptions): FastifyInstance;
|
|
17
17
|
//# sourceMappingURL=launcher.d.ts.map
|
package/dist/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAEA,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAEA,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;AAKvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC7B,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACV,WAAW,EACX,IAAI,EACJ,IAAI,GACP,EAAE,eAAe,GAAG,eAAe,CAoDnC"}
|
package/dist/launcher.js
CHANGED
|
@@ -3,13 +3,14 @@ import { notFound } from "@hapi/boom";
|
|
|
3
3
|
import Fastify, {} from "fastify";
|
|
4
4
|
import defaultErrorHandler from "./defaults/defaultErrorHandler.js";
|
|
5
5
|
import defaultFastifyOptions from "./defaults/defaultFastifyOptions.js";
|
|
6
|
+
import { createAuthPreHandler } from "./hooks/authPreHandler.js";
|
|
6
7
|
import { onResponse, preHandler } from "./index.js";
|
|
7
8
|
/**
|
|
8
9
|
* Creates and starts a Fastify HTTP server with the given configuration.
|
|
9
10
|
*
|
|
10
11
|
* Steps performed:
|
|
11
12
|
* 1. Creates a `FastifyInstance` merging {@link defaultFastifyOptions} with `opts`.
|
|
12
|
-
* 2. Decorates the instance with `locals` and any extra `decorators`.
|
|
13
|
+
* 2. Decorates the instance with `locals`, `verifyToken`, and any extra `decorators`.
|
|
13
14
|
* 3. Registers all `plugins` and `routes`.
|
|
14
15
|
* 4. Sets a `notFound` handler (throws Boom 404) and {@link defaultErrorHandler}.
|
|
15
16
|
* 5. Registers {@link preHandler} and {@link onResponse} hooks.
|
|
@@ -17,7 +18,7 @@ import { onResponse, preHandler } from "./index.js";
|
|
|
17
18
|
*
|
|
18
19
|
* @returns The `FastifyInstance` (e.g. for use with `fastify.close()`).
|
|
19
20
|
*/
|
|
20
|
-
export default function launcher({ logger, locals, plugins, routes, decorators, opts, done, }) {
|
|
21
|
+
export default function launcher({ logger, locals, plugins, routes, decorators, verifyToken, opts, done, }) {
|
|
21
22
|
const host = locals?.host ?? "localhost";
|
|
22
23
|
const port = locals?.port ?? 8888;
|
|
23
24
|
const fastify = Fastify({
|
|
@@ -25,6 +26,7 @@ export default function launcher({ logger, locals, plugins, routes, decorators,
|
|
|
25
26
|
...opts,
|
|
26
27
|
});
|
|
27
28
|
fastify.decorate("locals", locals);
|
|
29
|
+
fastify.decorate("verifyToken", verifyToken ?? (async () => false));
|
|
28
30
|
if (decorators instanceof Map) {
|
|
29
31
|
for (const [key, value] of decorators) {
|
|
30
32
|
fastify.decorate(key, value);
|
|
@@ -40,6 +42,9 @@ export default function launcher({ logger, locals, plugins, routes, decorators,
|
|
|
40
42
|
throw notFound();
|
|
41
43
|
});
|
|
42
44
|
fastify.setErrorHandler(defaultErrorHandler);
|
|
45
|
+
if (locals.authPaths?.length) {
|
|
46
|
+
fastify.addHook("preHandler", createAuthPreHandler(locals.authPaths, locals.authRealm));
|
|
47
|
+
}
|
|
43
48
|
// TODO: Add hook for `onRequestAbort`
|
|
44
49
|
fastify.addHook("preHandler", preHandler);
|
|
45
50
|
fastify.addHook("onResponse", onResponse);
|
package/dist/launcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,OAAO,EAAE,EAAwB,MAAM,SAAS,CAAA;AACvD,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGnD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC7B,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACV,IAAI,EACJ,IAAI,GACU;IACd,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA;IAEjC,MAAM,OAAO,GAAG,OAAO,CAAC;QACpB,GAAG,qBAAqB,CAAC,MAAM,CAAC;QAChC,GAAG,IAAI;KACV,CAAC,CAAA;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,OAAO,EAAE,EAAwB,MAAM,SAAS,CAAA;AACvD,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE,OAAO,qBAAqB,MAAM,qCAAqC,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGnD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC7B,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,EACV,WAAW,EACX,IAAI,EACJ,IAAI,GACU;IACd,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA;IAEjC,MAAM,OAAO,GAAG,OAAO,CAAC;QACpB,GAAG,qBAAqB,CAAC,MAAM,CAAC;QAChC,GAAG,IAAI;KACV,CAAC,CAAA;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,WAAW,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEnE,IAAI,UAAU,YAAY,GAAG,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;YACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACnC,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IACzD,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAED,OAAO,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAClD,MAAM,QAAQ,EAAE,CAAA;IACpB,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAA;IAE5C,IAAI,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,OAAO,CACX,YAAY,EACZ,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAC3D,CAAA;IACL,CAAC;IAED,sCAAsC;IACtC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IACzC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAEzC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;QACrC,IAAI,KAAK,EAAE,CAAC;YACR,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACnB,CAAC;QACD,IAAI,EAAE,EAAE,CAAA;IACZ,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAClB,CAAC"}
|
package/dist/start.js
CHANGED
|
@@ -1,17 +1,46 @@
|
|
|
1
1
|
import process, { env } from "node:process";
|
|
2
2
|
import { getConsoleLogger, main } from "@darthcav/ts-utils";
|
|
3
3
|
import pkg from "../package.json" with { type: "json" };
|
|
4
|
-
import {
|
|
4
|
+
import { createKeycloakVerifier } from "./auth/keycloak.js";
|
|
5
|
+
import { defaultPlugins, defaultRoutes, launcher, } from "./index.js";
|
|
5
6
|
const logger = await getConsoleLogger(pkg.name, "info");
|
|
6
|
-
main(pkg.name, logger, () => {
|
|
7
|
+
main(pkg.name, logger, async () => {
|
|
8
|
+
const authPaths = env["API_AUTH_PATHS"]
|
|
9
|
+
?.split(",")
|
|
10
|
+
.map((p) => p.trim())
|
|
11
|
+
.filter((p) => p.length > 0);
|
|
12
|
+
const keycloakUrl = env["KEYCLOAK_URL"]?.trim();
|
|
13
|
+
const keycloakRealm = env["KEYCLOAK_REALM"]?.trim();
|
|
14
|
+
const keycloakClientId = env["KEYCLOAK_CLIENT_ID"]?.trim();
|
|
15
|
+
const keycloakClientSecret = env["KEYCLOAK_CLIENT_SECRET"]?.trim();
|
|
16
|
+
const keycloakAuth = keycloakUrl && keycloakRealm && keycloakClientId && keycloakClientSecret
|
|
17
|
+
? {
|
|
18
|
+
url: keycloakUrl,
|
|
19
|
+
realm: keycloakRealm,
|
|
20
|
+
clientId: keycloakClientId,
|
|
21
|
+
clientSecret: keycloakClientSecret,
|
|
22
|
+
}
|
|
23
|
+
: undefined;
|
|
7
24
|
const locals = {
|
|
8
25
|
pkg,
|
|
9
26
|
host: env["HOST"] ?? "localhost",
|
|
10
|
-
port: Number(env["CONTAINER_EXPOSE_PORT"])
|
|
27
|
+
port: Number(env["CONTAINER_EXPOSE_PORT"]) || 8888,
|
|
28
|
+
...(authPaths?.length ? { authPaths } : {}),
|
|
29
|
+
...(keycloakRealm ? { authRealm: keycloakRealm } : {}),
|
|
11
30
|
};
|
|
12
|
-
const plugins =
|
|
31
|
+
const plugins = keycloakAuth
|
|
32
|
+
? defaultPlugins({ locals, keycloakAuth })
|
|
33
|
+
: defaultPlugins({ locals });
|
|
13
34
|
const routes = defaultRoutes();
|
|
14
|
-
const fastify =
|
|
35
|
+
const fastify = keycloakAuth
|
|
36
|
+
? launcher({
|
|
37
|
+
logger,
|
|
38
|
+
locals,
|
|
39
|
+
plugins,
|
|
40
|
+
routes,
|
|
41
|
+
verifyToken: createKeycloakVerifier(keycloakAuth),
|
|
42
|
+
})
|
|
43
|
+
: launcher({ logger, locals, plugins, routes });
|
|
15
44
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
16
45
|
process.on(signal, async (signal) => fastify
|
|
17
46
|
.close()
|
package/dist/start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
|