@darthcav/ts-http-server 0.5.0 → 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.
Files changed (51) hide show
  1. package/README.md +58 -8
  2. package/dist/__tests__/defaultPlugins.test.js +47 -2
  3. package/dist/__tests__/defaultPlugins.test.js.map +1 -1
  4. package/dist/__tests__/defaultRoutes.test.js +226 -1
  5. package/dist/__tests__/defaultRoutes.test.js.map +1 -1
  6. package/dist/__tests__/keycloak.test.d.ts +2 -0
  7. package/dist/__tests__/keycloak.test.d.ts.map +1 -0
  8. package/dist/__tests__/keycloak.test.js +105 -0
  9. package/dist/__tests__/keycloak.test.js.map +1 -0
  10. package/dist/__tests__/launcher.test.js +34 -0
  11. package/dist/__tests__/launcher.test.js.map +1 -1
  12. package/dist/auth/keycloak.d.ts +17 -0
  13. package/dist/auth/keycloak.d.ts.map +1 -0
  14. package/dist/auth/keycloak.js +35 -0
  15. package/dist/auth/keycloak.js.map +1 -0
  16. package/dist/defaults/defaultPlugins.d.ts +12 -7
  17. package/dist/defaults/defaultPlugins.d.ts.map +1 -1
  18. package/dist/defaults/defaultPlugins.js +109 -2
  19. package/dist/defaults/defaultPlugins.js.map +1 -1
  20. package/dist/defaults/defaultRoutes.d.ts +5 -0
  21. package/dist/defaults/defaultRoutes.d.ts.map +1 -1
  22. package/dist/defaults/defaultRoutes.js +30 -0
  23. package/dist/defaults/defaultRoutes.js.map +1 -1
  24. package/dist/hooks/authPreHandler.d.ts +19 -0
  25. package/dist/hooks/authPreHandler.d.ts.map +1 -0
  26. package/dist/hooks/authPreHandler.js +32 -0
  27. package/dist/hooks/authPreHandler.js.map +1 -0
  28. package/dist/index.d.ts +4 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/launcher.d.ts +2 -2
  33. package/dist/launcher.d.ts.map +1 -1
  34. package/dist/launcher.js +7 -2
  35. package/dist/launcher.js.map +1 -1
  36. package/dist/start.js +34 -5
  37. package/dist/start.js.map +1 -1
  38. package/dist/types.d.ts +64 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +10 -3
  41. package/src/auth/keycloak.ts +43 -0
  42. package/src/defaults/defaultPlugins.ts +141 -7
  43. package/src/defaults/defaultRoutes.ts +30 -1
  44. package/src/hooks/authPreHandler.ts +41 -0
  45. package/src/index.ts +7 -0
  46. package/src/launcher.ts +11 -1
  47. package/src/openapi/api.yaml +150 -0
  48. package/src/openapi/schemas/Error.yaml +14 -0
  49. package/src/start.ts +44 -5
  50. package/src/types.ts +71 -2
  51. package/src/views/index.ejs +4 -0
package/README.md CHANGED
@@ -12,7 +12,8 @@ A TypeScript wrapper HTTP server for Node.js >= 25 based upon [Fastify](https://
12
12
  - Strict TypeScript configuration with isolated declarations
13
13
  - Content negotiation for error responses (HTML / JSON / plain-text)
14
14
  - Access logging via `onResponse` hook — `info` for 2xx/3xx, `error` for 4xx/5xx
15
- - Default plugin set: CORS, compression, ETag, Helmet CSP, EJS views, and static files
15
+ - Default plugin set: accepts, CORS, compression, ETag, Helmet CSP, EJS views, static files, Swagger, and Swagger UI
16
+ - Optional Keycloak-backed JWT authentication for the default `/api/` routes
16
17
  - Returns a `FastifyInstance` for graceful shutdown via `SIGINT`/`SIGTERM`
17
18
  - Biome for linting and formatting
18
19
  - Built-in Node.js test runner
@@ -35,7 +36,7 @@ import pkg from "./package.json" with { type: "json" }
35
36
 
36
37
  const logger = await getConsoleLogger(pkg.name, "info")
37
38
 
38
- main(pkg.name, logger, false, () => {
39
+ main(pkg.name, logger, async () => {
39
40
  const locals = { pkg }
40
41
  const plugins = defaultPlugins({ locals })
41
42
  const routes = defaultRoutes()
@@ -63,7 +64,50 @@ The `defaultPlugins` function accepts an optional `baseDir` to resolve the `src/
63
64
  `import.meta.dirname`):
64
65
 
65
66
  ```ts
66
- const plugins = defaultPlugins({ locals, baseDir: import.meta.dirname });
67
+ const plugins = defaultPlugins({ locals, baseDir: import.meta.dirname })
68
+ ```
69
+
70
+ ### Keycloak authentication
71
+
72
+ To protect routes with Keycloak JWT authentication, set `API_AUTH_PATHS` to a comma-separated list of
73
+ [picomatch](https://github.com/micromatch/picomatch) glob patterns and provide the Keycloak connection variables. The
74
+ server verifies bearer tokens against the realm's JWKS endpoint; public keys are cached and rotated automatically.
75
+
76
+ ```ts
77
+ import { createKeycloakVerifier, type KeycloakAuthConfig } from "@darthcav/ts-http-server"
78
+
79
+ const keycloakAuth: KeycloakAuthConfig = {
80
+ url: process.env["KEYCLOAK_URL"] ?? "",
81
+ realm: process.env["KEYCLOAK_REALM"] ?? "",
82
+ clientId: process.env["KEYCLOAK_CLIENT_ID"] ?? "",
83
+ clientSecret: process.env["KEYCLOAK_CLIENT_SECRET"] ?? "",
84
+ }
85
+
86
+ const verifyToken = createKeycloakVerifier(keycloakAuth)
87
+ const locals = {
88
+ pkg,
89
+ authPaths: ["/api/**"],
90
+ authRealm: keycloakAuth.realm, // used in WWW-Authenticate challenge
91
+ }
92
+ const plugins = defaultPlugins({ locals, keycloakAuth }) // marks /api/ as protected in OpenAPI
93
+ const routes = defaultRoutes()
94
+
95
+ const fastify = launcher({ logger, locals, plugins, routes, verifyToken })
96
+ ```
97
+
98
+ When `locals.authPaths` is set, every request whose URL matches one of the glob patterns must carry
99
+ `Authorization: Bearer <token>`. Missing or invalid tokens receive `401 Unauthorized` with a
100
+ `WWW-Authenticate: Bearer realm="<authRealm>"` challenge (defaults to `"api"` when `authRealm` is not set). When
101
+ `authPaths` is `undefined` (the default), all routes are public regardless of any token in the request.
102
+
103
+ You can supply any custom `verifyToken` function instead of `createKeycloakVerifier` — it receives the raw
104
+ `Authorization` header value and should return `true` to allow the request or `false` to reject it with 401:
105
+
106
+ ```ts
107
+ const verifyToken = async (authorizationHeader: string | undefined): Promise<boolean> => {
108
+ return authorizationHeader === "Bearer my-static-token"
109
+ }
110
+ const fastify = launcher({ logger, locals, plugins, routes, verifyToken })
67
111
  ```
68
112
 
69
113
  ## Getting Started
@@ -100,6 +144,7 @@ src/
100
144
  start.ts # Application entry point
101
145
  launcher.ts # Application launcher (returns FastifyInstance)
102
146
  types.ts # Shared type definitions
147
+ auth/ # Authentication utilities
103
148
  defaults/ # Default Fastify options, plugins, routes, and error handler
104
149
  hooks/ # Fastify hooks (preHandler, onResponse)
105
150
  __tests__/ # Test files
@@ -134,10 +179,15 @@ docker build \
134
179
 
135
180
  Runtime environment variables:
136
181
 
137
- | Variable | Default | Description |
138
- | ----------------------- | ----------- | ------------------------------------------ |
139
- | `HOST` | `localhost` | Bind address (use `0.0.0.0` in containers) |
140
- | `CONTAINER_EXPOSE_PORT` | `8888` | Port the server listens on |
182
+ | Variable | Default | Description |
183
+ | ------------------------ | ----------- | --------------------------------------------------------------------- |
184
+ | `HOST` | `localhost` | Bind address (use `0.0.0.0` in containers) |
185
+ | `CONTAINER_EXPOSE_PORT` | `8888` | Port the server listens on |
186
+ | `API_AUTH_PATHS` | unset | Comma-separated picomatch globs for protected routes (e.g. `/api/**`) |
187
+ | `KEYCLOAK_URL` | unset | Keycloak server base URL |
188
+ | `KEYCLOAK_REALM` | unset | Keycloak realm name; also used as the `WWW-Authenticate` realm label |
189
+ | `KEYCLOAK_CLIENT_ID` | unset | Client ID registered in the realm |
190
+ | `KEYCLOAK_CLIENT_SECRET` | unset | Client secret for the registered client |
141
191
 
142
192
  ### Run
143
193
 
@@ -170,7 +220,7 @@ services:
170
220
 
171
221
  [node-version]: https://img.shields.io/badge/node-%3E%3D25-orange.svg?style=flat-square
172
222
  [node-url]: https://nodejs.org
173
- [version-image]: https://img.shields.io/badge/version-0.5.0-blue.svg?style=flat-square
223
+ [version-image]: https://img.shields.io/badge/version-0.6.0-blue.svg?style=flat-square
174
224
  [ci-badge]: https://github.com/darthcav/ts-http-server/actions/workflows/tests.yml/badge.svg
175
225
  [coverage-badge]: https://codecov.io/github/darthcav/ts-http-server/branch/dev/graph/badge.svg?token=K8Q4T4N9SG
176
226
  [coverage-url]: https://codecov.io/github/darthcav/ts-http-server
@@ -2,22 +2,67 @@ import { equal, ok } from "node:assert/strict";
2
2
  import { cwd } from "node:process";
3
3
  import { suite, test } from "node:test";
4
4
  import defaultPlugins from "../defaults/defaultPlugins.js";
5
+ function getSwaggerDocument(plugins) {
6
+ const swaggerPlugin = plugins.get("@fastify/swagger");
7
+ const specification = swaggerPlugin?.opts?.["specification"];
8
+ if (specification &&
9
+ typeof specification === "object" &&
10
+ "document" in specification) {
11
+ return specification.document;
12
+ }
13
+ return undefined;
14
+ }
5
15
  suite("defaultPlugins", () => {
6
16
  const locals = {
7
17
  pkg: { name: "ts-http-server", version: "0.0.0", description: "Test" },
8
18
  };
9
19
  test("returns all plugins using default baseDir", () => {
10
20
  const plugins = defaultPlugins({ locals });
11
- equal(plugins.size, 7);
21
+ equal(plugins.size, 9);
12
22
  ok(plugins.has("@fastify/accepts"));
13
23
  ok(plugins.has("@fastify/view"));
14
24
  ok(plugins.has("@fastify/static"));
25
+ ok(plugins.has("@fastify/swagger"));
26
+ ok(plugins.has("@fastify/swagger-ui"));
15
27
  });
16
28
  test("returns all plugins using explicit baseDir", () => {
17
29
  const plugins = defaultPlugins({ locals, baseDir: cwd() });
18
- equal(plugins.size, 7);
30
+ equal(plugins.size, 9);
19
31
  ok(plugins.has("@fastify/view"));
20
32
  ok(plugins.has("@fastify/static"));
33
+ ok(plugins.has("@fastify/swagger"));
34
+ ok(plugins.has("@fastify/swagger-ui"));
35
+ });
36
+ test("keeps /api/ public in OpenAPI when keycloakAuth is omitted", () => {
37
+ const plugins = defaultPlugins({ locals });
38
+ const document = getSwaggerDocument(plugins);
39
+ ok(document);
40
+ equal(document.security, undefined);
41
+ equal(document.paths?.["/api/"]?.get?.security, undefined);
42
+ equal(document.paths?.["/api/"]?.get?.responses?.["401"], undefined);
43
+ // The placeholder openIdConnect scheme defined in api.yaml is cleaned up
44
+ equal(document.components?.securitySchemes?.["openIdConnect"], undefined);
45
+ });
46
+ test("marks /api/ as OpenID Connect–protected in OpenAPI when keycloakAuth is provided", () => {
47
+ const plugins = defaultPlugins({
48
+ locals,
49
+ keycloakAuth: {
50
+ url: "https://auth.example.com",
51
+ realm: "test-realm",
52
+ clientId: "test-client",
53
+ clientSecret: "test-secret",
54
+ },
55
+ });
56
+ const document = getSwaggerDocument(plugins);
57
+ ok(document);
58
+ equal(Array.isArray(document.security), true);
59
+ equal(document.paths?.["/api/"]?.get?.security?.[0]?.["openIdConnect"]
60
+ ?.length, 0);
61
+ ok(document.paths?.["/api/"]?.get?.responses?.["401"]);
62
+ const scheme = document.components?.securitySchemes?.["openIdConnect"];
63
+ ok(scheme);
64
+ equal(scheme.type, "openIdConnect");
65
+ ok(scheme.openIdConnectUrl.includes("https://auth.example.com/realms/test-realm"));
21
66
  });
22
67
  });
23
68
  //# sourceMappingURL=defaultPlugins.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultPlugins.test.js","sourceRoot":"","sources":["../../src/__tests__/defaultPlugins.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,cAAc,MAAM,+BAA+B,CAAA;AAE1D,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE;IACzB,MAAM,MAAM,GAAG;QACX,GAAG,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE;KACzE,CAAA;IAED,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;QAC1C,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACnC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAA;QAChC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QAC1D,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACtB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAA;QAChC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"defaultPlugins.test.js","sourceRoot":"","sources":["../../src/__tests__/defaultPlugins.test.ts"],"names":[],"mappings":"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"}
@@ -41,12 +41,12 @@ suite("defaultRoutes [HTTP]", () => {
41
41
  const locals = {
42
42
  pkg: { name: "ts-http-server", version: "0.0.0", description: "Test" },
43
43
  };
44
- const plugins = defaultPlugins({ locals });
45
44
  const routes = new Map([...defaultRoutes(), ...errorRoute()]);
46
45
  const port = 19002;
47
46
  const base = `http://localhost:${port}`;
48
47
  let server;
49
48
  before(async () => {
49
+ const plugins = defaultPlugins({ locals });
50
50
  server = launcher({
51
51
  logger: testLogger,
52
52
  locals: { ...locals, port },
@@ -177,5 +177,230 @@ suite("defaultRoutes [HTTP]", () => {
177
177
  match(res.headers.get("content-type") ?? "", /text\/plain/);
178
178
  ok(body.includes("Not Found"));
179
179
  });
180
+ test("GET /api/ with application/json → 200 welcome message (auth disabled)", async () => {
181
+ const res = await fetch(`${base}/api/`, {
182
+ headers: { accept: "application/json" },
183
+ });
184
+ const body = (await res.json());
185
+ equal(res.status, 200);
186
+ match(res.headers.get("content-type") ?? "", /application\/json/);
187
+ ok(typeof body.message === "string");
188
+ });
189
+ test("GET /api/ with text/html → 406 Not Acceptable", async () => {
190
+ const res = await fetch(`${base}/api/`, {
191
+ headers: { accept: "text/html" },
192
+ });
193
+ equal(res.status, 406);
194
+ });
195
+ test("HEAD /api/ → 200", async () => {
196
+ const res = await fetch(`${base}/api/`, { method: "HEAD" });
197
+ equal(res.status, 200);
198
+ });
199
+ test("DELETE /api/ → 405 Method Not Allowed", async () => {
200
+ const res = await fetch(`${base}/api/`, { method: "DELETE" });
201
+ equal(res.status, 405);
202
+ equal(res.headers.get("allow"), "GET, HEAD");
203
+ });
204
+ test("PATCH /api/ → 405 Method Not Allowed", async () => {
205
+ const res = await fetch(`${base}/api/`, { method: "PATCH" });
206
+ equal(res.status, 405);
207
+ equal(res.headers.get("allow"), "GET, HEAD");
208
+ });
209
+ test("POST /api/ → 405 Method Not Allowed", async () => {
210
+ const res = await fetch(`${base}/api/`, { method: "POST" });
211
+ equal(res.status, 405);
212
+ equal(res.headers.get("allow"), "GET, HEAD");
213
+ });
214
+ test("PUT /api/ → 405 Method Not Allowed", async () => {
215
+ const res = await fetch(`${base}/api/`, { method: "PUT" });
216
+ equal(res.status, 405);
217
+ equal(res.headers.get("allow"), "GET, HEAD");
218
+ });
219
+ });
220
+ suite("defaultRoutes [HTTP] with authPaths=['/api/**'] and mock verifyToken", () => {
221
+ const noop = () => { };
222
+ const testLogger = {
223
+ category: ["test"],
224
+ info: noop,
225
+ error: noop,
226
+ warn: noop,
227
+ debug: noop,
228
+ getChild: () => testLogger,
229
+ };
230
+ const locals = {
231
+ pkg: {
232
+ name: "ts-http-server",
233
+ version: "0.0.0",
234
+ description: "Test",
235
+ },
236
+ };
237
+ const port = 19004;
238
+ const base = `http://localhost:${port}`;
239
+ let server;
240
+ before(async () => {
241
+ const plugins = defaultPlugins({ locals });
242
+ // Mock verifyToken: accepts only "Bearer test-token"
243
+ const verifyToken = async (authorizationHeader) => authorizationHeader === "Bearer test-token";
244
+ server = launcher({
245
+ logger: testLogger,
246
+ locals: { ...locals, port, authPaths: ["/api/**"] },
247
+ plugins,
248
+ routes: defaultRoutes(),
249
+ verifyToken,
250
+ opts: { disableRequestLogging: true },
251
+ });
252
+ await setTimeout(1000);
253
+ });
254
+ after(async () => {
255
+ await setTimeout(500);
256
+ await server.close();
257
+ });
258
+ test("GET /api/ without Authorization → 401 Unauthorized", async () => {
259
+ const res = await fetch(`${base}/api/`, {
260
+ headers: { accept: "application/json" },
261
+ });
262
+ const body = (await res.json());
263
+ equal(res.status, 401);
264
+ equal(res.headers.get("www-authenticate"), 'Bearer realm="api"');
265
+ match(res.headers.get("content-type") ?? "", /application\/json/);
266
+ equal(body.statusCode, 401);
267
+ equal(body.error, "Unauthorized");
268
+ });
269
+ test("GET /api/ with invalid Authorization → 401 Unauthorized", async () => {
270
+ const res = await fetch(`${base}/api/`, {
271
+ headers: {
272
+ accept: "application/json",
273
+ authorization: "Bearer wrong-token",
274
+ },
275
+ });
276
+ equal(res.status, 401);
277
+ equal(res.headers.get("www-authenticate"), 'Bearer realm="api"');
278
+ });
279
+ test("GET /api/ with valid Authorization → 200 welcome message", async () => {
280
+ const res = await fetch(`${base}/api/`, {
281
+ headers: {
282
+ accept: "application/json",
283
+ authorization: "Bearer test-token",
284
+ },
285
+ });
286
+ const body = (await res.json());
287
+ equal(res.status, 200);
288
+ match(res.headers.get("content-type") ?? "", /application\/json/);
289
+ ok(typeof body.message === "string");
290
+ });
291
+ test("DELETE /api/ with valid Authorization → 405 Method Not Allowed", async () => {
292
+ const res = await fetch(`${base}/api/`, {
293
+ method: "DELETE",
294
+ headers: { authorization: "Bearer test-token" },
295
+ });
296
+ equal(res.status, 405);
297
+ equal(res.headers.get("allow"), "GET, HEAD");
298
+ });
299
+ test("GET / without Authorization → 200 (non-protected path)", async () => {
300
+ const res = await fetch(`${base}/`, {
301
+ headers: { accept: "text/html" },
302
+ });
303
+ equal(res.status, 200);
304
+ });
305
+ });
306
+ suite("defaultRoutes [HTTP] with authPaths and custom authRealm", () => {
307
+ const noop = () => { };
308
+ const testLogger = {
309
+ category: ["test"],
310
+ info: noop,
311
+ error: noop,
312
+ warn: noop,
313
+ debug: noop,
314
+ getChild: () => testLogger,
315
+ };
316
+ const locals = {
317
+ pkg: {
318
+ name: "ts-http-server",
319
+ version: "0.0.0",
320
+ description: "Test",
321
+ },
322
+ };
323
+ const port = 19006;
324
+ const base = `http://localhost:${port}`;
325
+ let server;
326
+ before(async () => {
327
+ const plugins = defaultPlugins({ locals });
328
+ server = launcher({
329
+ logger: testLogger,
330
+ locals: {
331
+ ...locals,
332
+ port,
333
+ authPaths: ["/api/**"],
334
+ authRealm: "my-realm",
335
+ },
336
+ plugins,
337
+ routes: defaultRoutes(),
338
+ opts: { disableRequestLogging: true },
339
+ });
340
+ await setTimeout(1000);
341
+ });
342
+ after(async () => {
343
+ await setTimeout(500);
344
+ await server.close();
345
+ });
346
+ test("GET /api/ without Authorization → 401 with custom realm", async () => {
347
+ const res = await fetch(`${base}/api/`, {
348
+ headers: { accept: "application/json" },
349
+ });
350
+ equal(res.status, 401);
351
+ equal(res.headers.get("www-authenticate"), 'Bearer realm="my-realm"');
352
+ });
353
+ });
354
+ suite("defaultRoutes [HTTP] with no authPaths (auth disabled)", () => {
355
+ const noop = () => { };
356
+ const testLogger = {
357
+ category: ["test"],
358
+ info: noop,
359
+ error: noop,
360
+ warn: noop,
361
+ debug: noop,
362
+ getChild: () => testLogger,
363
+ };
364
+ const locals = {
365
+ pkg: { name: "ts-http-server", version: "0.0.0", description: "Test" },
366
+ };
367
+ const port = 19005;
368
+ const base = `http://localhost:${port}`;
369
+ let server;
370
+ before(async () => {
371
+ const plugins = defaultPlugins({ locals });
372
+ // verifyToken always returns false — but authPaths is unset so it is never called
373
+ const verifyToken = async () => false;
374
+ server = launcher({
375
+ logger: testLogger,
376
+ locals: { ...locals, port },
377
+ plugins,
378
+ routes: defaultRoutes(),
379
+ verifyToken,
380
+ opts: { disableRequestLogging: true },
381
+ });
382
+ await setTimeout(1000);
383
+ });
384
+ after(async () => {
385
+ await setTimeout(500);
386
+ await server.close();
387
+ });
388
+ test("GET /api/ without Authorization → 200 (auth disabled)", async () => {
389
+ const res = await fetch(`${base}/api/`, {
390
+ headers: { accept: "application/json" },
391
+ });
392
+ const body = (await res.json());
393
+ equal(res.status, 200);
394
+ ok(typeof body.message === "string");
395
+ });
396
+ test("GET /api/ with any Authorization → 200 (auth disabled)", async () => {
397
+ const res = await fetch(`${base}/api/`, {
398
+ headers: {
399
+ accept: "application/json",
400
+ authorization: "Bearer anything",
401
+ },
402
+ });
403
+ equal(res.status, 200);
404
+ });
180
405
  });
181
406
  //# sourceMappingURL=defaultRoutes.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultRoutes.test.js","sourceRoot":"","sources":["../../src/__tests__/defaultRoutes.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"defaultRoutes.test.js","sourceRoot":"","sources":["../../src/__tests__/defaultRoutes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=keycloak.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/keycloak.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ import { equal } from "node:assert/strict";
2
+ import { createServer } from "node:http";
3
+ import { after, before, suite, test } from "node:test";
4
+ import { exportJWK, generateKeyPair, SignJWT } from "jose";
5
+ import { createKeycloakVerifier } from "../auth/keycloak.js";
6
+ // ---------------------------------------------------------------------------
7
+ // Mock JWKS server + key pair used across all tests in this suite
8
+ // ---------------------------------------------------------------------------
9
+ suite("createKeycloakVerifier", () => {
10
+ const mockPort = 19010;
11
+ const mockBaseUrl = `http://localhost:${mockPort}`;
12
+ const testRealm = "test-realm";
13
+ const issuer = `${mockBaseUrl}/realms/${testRealm}`;
14
+ const config = {
15
+ url: mockBaseUrl,
16
+ realm: testRealm,
17
+ clientId: "test-client",
18
+ clientSecret: "test-secret",
19
+ };
20
+ let privateKey;
21
+ let jwksServer;
22
+ before(async () => {
23
+ const keyPair = await generateKeyPair("RS256");
24
+ privateKey = keyPair.privateKey;
25
+ const publicJwk = await exportJWK(keyPair.publicKey);
26
+ publicJwk.kid = "test-key-1";
27
+ publicJwk.use = "sig";
28
+ publicJwk.alg = "RS256";
29
+ const jwksBody = JSON.stringify({ keys: [publicJwk] });
30
+ const certsPath = `/realms/${testRealm}/protocol/openid-connect/certs`;
31
+ jwksServer = createServer((_req, res) => {
32
+ if (_req.url === certsPath) {
33
+ res.writeHead(200, { "Content-Type": "application/json" });
34
+ res.end(jwksBody);
35
+ }
36
+ else {
37
+ res.writeHead(404);
38
+ res.end();
39
+ }
40
+ });
41
+ await new Promise((resolve) => {
42
+ jwksServer.listen(mockPort, resolve);
43
+ });
44
+ });
45
+ after(async () => {
46
+ await new Promise((resolve, reject) => {
47
+ jwksServer.close((err) => (err ? reject(err) : resolve()));
48
+ });
49
+ });
50
+ /** Creates a valid JWT signed with the test key. */
51
+ async function validToken() {
52
+ return new SignJWT({})
53
+ .setProtectedHeader({ alg: "RS256", kid: "test-key-1" })
54
+ .setIssuer(issuer)
55
+ .setIssuedAt()
56
+ .setExpirationTime("1h")
57
+ .sign(privateKey);
58
+ }
59
+ test("returns false for undefined Authorization header", async () => {
60
+ const verify = createKeycloakVerifier(config);
61
+ equal(await verify(undefined), false);
62
+ });
63
+ test("returns false when Authorization does not start with 'Bearer '", async () => {
64
+ const verify = createKeycloakVerifier(config);
65
+ equal(await verify("Basic abc123"), false);
66
+ equal(await verify("bearer token"), false);
67
+ });
68
+ test("returns true for a valid signed JWT", async () => {
69
+ const verify = createKeycloakVerifier(config);
70
+ equal(await verify(`Bearer ${await validToken()}`), true);
71
+ });
72
+ test("returns false for a JWT with wrong issuer", async () => {
73
+ const verify = createKeycloakVerifier(config);
74
+ const token = await new SignJWT({})
75
+ .setProtectedHeader({ alg: "RS256", kid: "test-key-1" })
76
+ .setIssuer("https://wrong.example.com/realms/other")
77
+ .setIssuedAt()
78
+ .setExpirationTime("1h")
79
+ .sign(privateKey);
80
+ equal(await verify(`Bearer ${token}`), false);
81
+ });
82
+ test("returns false for an expired JWT", async () => {
83
+ const verify = createKeycloakVerifier(config);
84
+ const now = Math.floor(Date.now() / 1000);
85
+ const token = await new SignJWT({})
86
+ .setProtectedHeader({ alg: "RS256", kid: "test-key-1" })
87
+ .setIssuer(issuer)
88
+ .setIssuedAt(now - 120)
89
+ .setExpirationTime(now - 60)
90
+ .sign(privateKey);
91
+ equal(await verify(`Bearer ${token}`), false);
92
+ });
93
+ test("returns false for a malformed token string", async () => {
94
+ const verify = createKeycloakVerifier(config);
95
+ equal(await verify("Bearer not-a-real-jwt"), false);
96
+ });
97
+ test("strips trailing slash from base URL", async () => {
98
+ const verify = createKeycloakVerifier({
99
+ ...config,
100
+ url: `${mockBaseUrl}/`,
101
+ });
102
+ equal(await verify(`Bearer ${await validToken()}`), true);
103
+ });
104
+ });
105
+ //# sourceMappingURL=keycloak.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.test.js","sourceRoot":"","sources":["../../src/__tests__/keycloak.test.ts"],"names":[],"mappings":"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"}
@@ -51,6 +51,28 @@ const routes = new Map([
51
51
  },
52
52
  },
53
53
  ],
54
+ [
55
+ "ERROR_INVALID_STATUS",
56
+ {
57
+ method: "GET",
58
+ url: "/error-invalid-status",
59
+ handler: async (_request, reply) => {
60
+ reply.status(600);
61
+ throw new Error("error with out-of-range status code");
62
+ },
63
+ },
64
+ ],
65
+ [
66
+ "ERROR_VALID_STATUS",
67
+ {
68
+ method: "GET",
69
+ url: "/error-valid-status",
70
+ handler: async (_request, reply) => {
71
+ reply.status(503);
72
+ throw new Error("error with valid 5xx status code");
73
+ },
74
+ },
75
+ ],
54
76
  ]);
55
77
  // ---------------------------------------------------------------------------
56
78
  // HTTP server suite
@@ -112,5 +134,17 @@ suite("launcher [HTTP]", () => {
112
134
  });
113
135
  equal(res.status, 500);
114
136
  });
137
+ test("GET /error-invalid-status → 500 (statusCode > 599 reset to 500)", async () => {
138
+ const res = await fetch(`${base}/error-invalid-status`, {
139
+ headers: { accept: "application/json" },
140
+ });
141
+ equal(res.status, 500);
142
+ });
143
+ test("GET /error-valid-status → 503 (valid 4xx–5xx status preserved)", async () => {
144
+ const res = await fetch(`${base}/error-valid-status`, {
145
+ headers: { accept: "application/json" },
146
+ });
147
+ equal(res.status, 503);
148
+ });
115
149
  });
116
150
  //# sourceMappingURL=launcher.test.js.map