@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
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
|
|
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,
|
|
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
|
|
138
|
-
|
|
|
139
|
-
| `HOST`
|
|
140
|
-
| `CONTAINER_EXPOSE_PORT`
|
|
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.
|
|
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,
|
|
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,
|
|
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;
|
|
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 @@
|
|
|
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
|