@udibo/oauth2 0.40.1 → 0.41.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/dist/adapters/hono/log.d.ts +17 -11
- package/dist/adapters/hono/log.js +54 -11
- package/package.json +1 -1
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Request logging that removes query values, including OAuth callback credentials.
|
|
3
|
-
*
|
|
4
|
-
* @module hono/log
|
|
5
|
-
*/
|
|
6
1
|
import type { MiddlewareHandler } from "hono";
|
|
7
2
|
/**
|
|
8
3
|
* Produces a request target with every query value replaced by `[redacted]`.
|
|
@@ -26,14 +21,24 @@ import type { MiddlewareHandler } from "hono";
|
|
|
26
21
|
*/
|
|
27
22
|
export declare function redactedRequestTarget(url: string | URL): string;
|
|
28
23
|
/**
|
|
29
|
-
* Logs Hono
|
|
30
|
-
*
|
|
31
|
-
* Logs method, redacted target,
|
|
32
|
-
* does not log headers or bodies.
|
|
24
|
+
* Logs each Hono request as one line, written when the response is ready,
|
|
25
|
+
* without any query values. Mount before authentication routes so OAuth
|
|
26
|
+
* callback codes and state stay out of logs. Logs method, redacted target,
|
|
27
|
+
* response status and elapsed milliseconds; does not log headers or bodies.
|
|
28
|
+
* Paths and parameter names remain visible. A request whose handler throws
|
|
29
|
+
* something Hono does not answer (a non-`Error`) is still logged, as `500`.
|
|
30
|
+
*
|
|
31
|
+
* A request this middleware sees while it is handling another one (the app
|
|
32
|
+
* calling its own `fetch` from a handler or a server-rendered page's loader) is
|
|
33
|
+
* folded into the outer request's line, in brackets, in completion order,
|
|
34
|
+
* instead of writing its own. One that completes after the outer response was
|
|
35
|
+
* ready gets its own line, marked `(in-process)`; that includes a request
|
|
36
|
+
* started later from a timer or promise the outer request created. Each
|
|
37
|
+
* `requestLogger()` call folds only the requests it sees itself, so a sub-app
|
|
38
|
+
* with its own logger writes to its own sink.
|
|
33
39
|
*
|
|
34
40
|
* @param print Receives each log line; defaults to `console.log`, resolved per line.
|
|
35
|
-
* @returns Middleware emitting
|
|
36
|
-
* a response line.
|
|
41
|
+
* @returns Middleware emitting one line per request after downstream completion.
|
|
37
42
|
*
|
|
38
43
|
* @example
|
|
39
44
|
* ```ts
|
|
@@ -43,6 +48,7 @@ export declare function redactedRequestTarget(url: string | URL): string;
|
|
|
43
48
|
* const app = new Hono();
|
|
44
49
|
* app.use(requestLogger());
|
|
45
50
|
* app.get("/", (c) => c.text("Hello"));
|
|
51
|
+
* // --> GET /?code=[redacted] 200 3ms
|
|
46
52
|
* ```
|
|
47
53
|
*/
|
|
48
54
|
export declare function requestLogger(print?: (line: string) => void): MiddlewareHandler;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request logging that removes query values, including OAuth callback credentials.
|
|
3
|
+
*
|
|
4
|
+
* @module hono/log
|
|
5
|
+
*/
|
|
6
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
1
7
|
/**
|
|
2
8
|
* Produces a request target with every query value replaced by `[redacted]`.
|
|
3
9
|
* Keeps the pathname and percent-encoded parameter names, including repeats,
|
|
@@ -28,15 +34,28 @@ export function redactedRequestTarget(url) {
|
|
|
28
34
|
.join("&");
|
|
29
35
|
return `${pathname}?${query}`;
|
|
30
36
|
}
|
|
37
|
+
function summary(method, url, status, started) {
|
|
38
|
+
return `${method} ${redactedRequestTarget(url)} ${status} ${Date.now() - started}ms`;
|
|
39
|
+
}
|
|
31
40
|
/**
|
|
32
|
-
* Logs Hono
|
|
33
|
-
*
|
|
34
|
-
* Logs method, redacted target,
|
|
35
|
-
* does not log headers or bodies.
|
|
41
|
+
* Logs each Hono request as one line, written when the response is ready,
|
|
42
|
+
* without any query values. Mount before authentication routes so OAuth
|
|
43
|
+
* callback codes and state stay out of logs. Logs method, redacted target,
|
|
44
|
+
* response status and elapsed milliseconds; does not log headers or bodies.
|
|
45
|
+
* Paths and parameter names remain visible. A request whose handler throws
|
|
46
|
+
* something Hono does not answer (a non-`Error`) is still logged, as `500`.
|
|
47
|
+
*
|
|
48
|
+
* A request this middleware sees while it is handling another one (the app
|
|
49
|
+
* calling its own `fetch` from a handler or a server-rendered page's loader) is
|
|
50
|
+
* folded into the outer request's line, in brackets, in completion order,
|
|
51
|
+
* instead of writing its own. One that completes after the outer response was
|
|
52
|
+
* ready gets its own line, marked `(in-process)`; that includes a request
|
|
53
|
+
* started later from a timer or promise the outer request created. Each
|
|
54
|
+
* `requestLogger()` call folds only the requests it sees itself, so a sub-app
|
|
55
|
+
* with its own logger writes to its own sink.
|
|
36
56
|
*
|
|
37
57
|
* @param print Receives each log line; defaults to `console.log`, resolved per line.
|
|
38
|
-
* @returns Middleware emitting
|
|
39
|
-
* a response line.
|
|
58
|
+
* @returns Middleware emitting one line per request after downstream completion.
|
|
40
59
|
*
|
|
41
60
|
* @example
|
|
42
61
|
* ```ts
|
|
@@ -46,15 +65,39 @@ export function redactedRequestTarget(url) {
|
|
|
46
65
|
* const app = new Hono();
|
|
47
66
|
* app.use(requestLogger());
|
|
48
67
|
* app.get("/", (c) => c.text("Hello"));
|
|
68
|
+
* // --> GET /?code=[redacted] 200 3ms
|
|
49
69
|
* ```
|
|
50
70
|
*/
|
|
51
71
|
export function requestLogger(print) {
|
|
52
72
|
const emit = print ?? ((line) => console.log(line));
|
|
73
|
+
const outerRequest = new AsyncLocalStorage();
|
|
53
74
|
return async (c, next) => {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
const started = Date.now();
|
|
76
|
+
const outer = outerRequest.getStore();
|
|
77
|
+
let status = 500;
|
|
78
|
+
if (outer) {
|
|
79
|
+
try {
|
|
80
|
+
await next();
|
|
81
|
+
status = c.res.status;
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
const call = summary(c.req.method, c.req.url, status, started);
|
|
85
|
+
if (outer.answered)
|
|
86
|
+
emit(`--> (in-process) ${call}`);
|
|
87
|
+
else
|
|
88
|
+
outer.calls.push(call);
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const request = { calls: [], answered: false };
|
|
93
|
+
try {
|
|
94
|
+
await outerRequest.run(request, next);
|
|
95
|
+
status = c.res.status;
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
request.answered = true;
|
|
99
|
+
const calls = request.calls.length === 0 ? "" : ` [${request.calls.join(", ")}]`;
|
|
100
|
+
emit(`--> ${summary(c.req.method, c.req.url, status, started)}${calls}`);
|
|
101
|
+
}
|
|
59
102
|
};
|
|
60
103
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@udibo/oauth2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "A flexible OAuth2 toolkit: framework-agnostic authorization & resource servers, a typed client, Hono adapters (including a backend-for-frontend), and React bindings.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authorization-server",
|