hono 4.10.1 → 4.10.3
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/adapter/aws-lambda/handler.js +1 -1
- package/dist/cjs/adapter/aws-lambda/handler.js +1 -1
- package/dist/cjs/middleware/cors/index.js +6 -8
- package/dist/cjs/middleware/request-id/request-id.js +1 -1
- package/dist/cjs/utils/jwt/jwt.js +30 -18
- package/dist/cjs/utils/jwt/types.js +18 -0
- package/dist/middleware/cors/index.js +6 -8
- package/dist/middleware/request-id/request-id.js +1 -1
- package/dist/types/utils/jwt/jwt.d.ts +2 -0
- package/dist/types/utils/jwt/types.d.ts +10 -0
- package/dist/utils/jwt/jwt.js +32 -18
- package/dist/utils/jwt/types.js +16 -0
- package/package.json +1 -1
|
@@ -282,7 +282,7 @@ var isProxyEventV2 = (event) => {
|
|
|
282
282
|
return Object.hasOwn(event, "rawPath");
|
|
283
283
|
};
|
|
284
284
|
var defaultIsContentTypeBinary = (contentType) => {
|
|
285
|
-
return !/^
|
|
285
|
+
return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/.test(
|
|
286
286
|
contentType
|
|
287
287
|
);
|
|
288
288
|
};
|
|
@@ -312,7 +312,7 @@ const isProxyEventV2 = (event) => {
|
|
|
312
312
|
return Object.hasOwn(event, "rawPath");
|
|
313
313
|
};
|
|
314
314
|
const defaultIsContentTypeBinary = (contentType) => {
|
|
315
|
-
return !/^
|
|
315
|
+
return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/.test(
|
|
316
316
|
contentType
|
|
317
317
|
);
|
|
318
318
|
};
|
|
@@ -62,14 +62,6 @@ const cors = (options) => {
|
|
|
62
62
|
if (allowOrigin) {
|
|
63
63
|
set("Access-Control-Allow-Origin", allowOrigin);
|
|
64
64
|
}
|
|
65
|
-
if (opts.origin !== "*") {
|
|
66
|
-
const existingVary = c.req.header("Vary");
|
|
67
|
-
if (existingVary) {
|
|
68
|
-
set("Vary", existingVary);
|
|
69
|
-
} else {
|
|
70
|
-
set("Vary", "Origin");
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
65
|
if (opts.credentials) {
|
|
74
66
|
set("Access-Control-Allow-Credentials", "true");
|
|
75
67
|
}
|
|
@@ -77,6 +69,9 @@ const cors = (options) => {
|
|
|
77
69
|
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
|
|
78
70
|
}
|
|
79
71
|
if (c.req.method === "OPTIONS") {
|
|
72
|
+
if (opts.origin !== "*") {
|
|
73
|
+
set("Vary", "Origin");
|
|
74
|
+
}
|
|
80
75
|
if (opts.maxAge != null) {
|
|
81
76
|
set("Access-Control-Max-Age", opts.maxAge.toString());
|
|
82
77
|
}
|
|
@@ -104,6 +99,9 @@ const cors = (options) => {
|
|
|
104
99
|
});
|
|
105
100
|
}
|
|
106
101
|
await next();
|
|
102
|
+
if (opts.origin !== "*") {
|
|
103
|
+
c.header("Vary", "Origin", { append: true });
|
|
104
|
+
}
|
|
107
105
|
};
|
|
108
106
|
};
|
|
109
107
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -28,7 +28,7 @@ const requestId = ({
|
|
|
28
28
|
} = {}) => {
|
|
29
29
|
return async function requestId2(c, next) {
|
|
30
30
|
let reqId = headerName ? c.req.header(headerName) : void 0;
|
|
31
|
-
if (!reqId || reqId.length > limitLength || /[^\w
|
|
31
|
+
if (!reqId || reqId.length > limitLength || /[^\w\-=]/.test(reqId)) {
|
|
32
32
|
reqId = generator(c);
|
|
33
33
|
}
|
|
34
34
|
c.set("requestId", reqId);
|
|
@@ -56,14 +56,14 @@ const sign = async (payload, privateKey, alg = "HS256") => {
|
|
|
56
56
|
return `${partialToken}.${signature}`;
|
|
57
57
|
};
|
|
58
58
|
const verify = async (token, publicKey, algOrOptions) => {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
59
|
+
const {
|
|
60
|
+
alg = "HS256",
|
|
61
|
+
iss,
|
|
62
|
+
nbf = true,
|
|
63
|
+
exp = true,
|
|
64
|
+
iat = true,
|
|
65
|
+
aud
|
|
66
|
+
} = typeof algOrOptions === "string" ? { alg: algOrOptions } : algOrOptions || {};
|
|
67
67
|
const tokenParts = token.split(".");
|
|
68
68
|
if (tokenParts.length !== 3) {
|
|
69
69
|
throw new import_types.JwtTokenInvalid(token);
|
|
@@ -73,30 +73,42 @@ const verify = async (token, publicKey, algOrOptions) => {
|
|
|
73
73
|
throw new import_types.JwtHeaderInvalid(header);
|
|
74
74
|
}
|
|
75
75
|
const now = Date.now() / 1e3 | 0;
|
|
76
|
-
if (
|
|
76
|
+
if (nbf && payload.nbf && payload.nbf > now) {
|
|
77
77
|
throw new import_types.JwtTokenNotBefore(token);
|
|
78
78
|
}
|
|
79
|
-
if (
|
|
79
|
+
if (exp && payload.exp && payload.exp <= now) {
|
|
80
80
|
throw new import_types.JwtTokenExpired(token);
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
82
|
+
if (iat && payload.iat && now < payload.iat) {
|
|
83
83
|
throw new import_types.JwtTokenIssuedAt(now, payload.iat);
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
85
|
+
if (iss) {
|
|
86
86
|
if (!payload.iss) {
|
|
87
|
-
throw new import_types.JwtTokenIssuer(
|
|
87
|
+
throw new import_types.JwtTokenIssuer(iss, null);
|
|
88
88
|
}
|
|
89
|
-
if (typeof
|
|
90
|
-
throw new import_types.JwtTokenIssuer(
|
|
89
|
+
if (typeof iss === "string" && payload.iss !== iss) {
|
|
90
|
+
throw new import_types.JwtTokenIssuer(iss, payload.iss);
|
|
91
91
|
}
|
|
92
|
-
if (
|
|
93
|
-
throw new import_types.JwtTokenIssuer(
|
|
92
|
+
if (iss instanceof RegExp && !iss.test(payload.iss)) {
|
|
93
|
+
throw new import_types.JwtTokenIssuer(iss, payload.iss);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (aud) {
|
|
97
|
+
if (!payload.aud) {
|
|
98
|
+
throw new import_types.JwtPayloadRequiresAud(payload);
|
|
99
|
+
}
|
|
100
|
+
const audiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
|
|
101
|
+
const matched = audiences.some(
|
|
102
|
+
(payloadAud) => aud instanceof RegExp ? aud.test(payloadAud) : typeof aud === "string" ? payloadAud === aud : Array.isArray(aud) && aud.includes(payloadAud)
|
|
103
|
+
);
|
|
104
|
+
if (!matched) {
|
|
105
|
+
throw new import_types.JwtTokenAudience(aud, payload.aud);
|
|
94
106
|
}
|
|
95
107
|
}
|
|
96
108
|
const headerPayload = token.substring(0, token.lastIndexOf("."));
|
|
97
109
|
const verified = await (0, import_jws.verifying)(
|
|
98
110
|
publicKey,
|
|
99
|
-
|
|
111
|
+
alg,
|
|
100
112
|
(0, import_encode.decodeBase64Url)(tokenParts[2]),
|
|
101
113
|
import_utf8.utf8Encoder.encode(headerPayload)
|
|
102
114
|
);
|
|
@@ -22,6 +22,8 @@ __export(types_exports, {
|
|
|
22
22
|
JwtAlgorithmNotImplemented: () => JwtAlgorithmNotImplemented,
|
|
23
23
|
JwtHeaderInvalid: () => JwtHeaderInvalid,
|
|
24
24
|
JwtHeaderRequiresKid: () => JwtHeaderRequiresKid,
|
|
25
|
+
JwtPayloadRequiresAud: () => JwtPayloadRequiresAud,
|
|
26
|
+
JwtTokenAudience: () => JwtTokenAudience,
|
|
25
27
|
JwtTokenExpired: () => JwtTokenExpired,
|
|
26
28
|
JwtTokenInvalid: () => JwtTokenInvalid,
|
|
27
29
|
JwtTokenIssuedAt: () => JwtTokenIssuedAt,
|
|
@@ -86,6 +88,20 @@ class JwtTokenSignatureMismatched extends Error {
|
|
|
86
88
|
this.name = "JwtTokenSignatureMismatched";
|
|
87
89
|
}
|
|
88
90
|
}
|
|
91
|
+
class JwtPayloadRequiresAud extends Error {
|
|
92
|
+
constructor(payload) {
|
|
93
|
+
super(`required "aud" in jwt payload: ${JSON.stringify(payload)}`);
|
|
94
|
+
this.name = "JwtPayloadRequiresAud";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class JwtTokenAudience extends Error {
|
|
98
|
+
constructor(expected, aud) {
|
|
99
|
+
super(
|
|
100
|
+
`expected audience "${Array.isArray(expected) ? expected.join(", ") : expected}", got "${aud}"`
|
|
101
|
+
);
|
|
102
|
+
this.name = "JwtTokenAudience";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
89
105
|
var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
|
|
90
106
|
CryptoKeyUsage2["Encrypt"] = "encrypt";
|
|
91
107
|
CryptoKeyUsage2["Decrypt"] = "decrypt";
|
|
@@ -103,6 +119,8 @@ var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
|
|
|
103
119
|
JwtAlgorithmNotImplemented,
|
|
104
120
|
JwtHeaderInvalid,
|
|
105
121
|
JwtHeaderRequiresKid,
|
|
122
|
+
JwtPayloadRequiresAud,
|
|
123
|
+
JwtTokenAudience,
|
|
106
124
|
JwtTokenExpired,
|
|
107
125
|
JwtTokenInvalid,
|
|
108
126
|
JwtTokenIssuedAt,
|
|
@@ -40,14 +40,6 @@ var cors = (options) => {
|
|
|
40
40
|
if (allowOrigin) {
|
|
41
41
|
set("Access-Control-Allow-Origin", allowOrigin);
|
|
42
42
|
}
|
|
43
|
-
if (opts.origin !== "*") {
|
|
44
|
-
const existingVary = c.req.header("Vary");
|
|
45
|
-
if (existingVary) {
|
|
46
|
-
set("Vary", existingVary);
|
|
47
|
-
} else {
|
|
48
|
-
set("Vary", "Origin");
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
43
|
if (opts.credentials) {
|
|
52
44
|
set("Access-Control-Allow-Credentials", "true");
|
|
53
45
|
}
|
|
@@ -55,6 +47,9 @@ var cors = (options) => {
|
|
|
55
47
|
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
|
|
56
48
|
}
|
|
57
49
|
if (c.req.method === "OPTIONS") {
|
|
50
|
+
if (opts.origin !== "*") {
|
|
51
|
+
set("Vary", "Origin");
|
|
52
|
+
}
|
|
58
53
|
if (opts.maxAge != null) {
|
|
59
54
|
set("Access-Control-Max-Age", opts.maxAge.toString());
|
|
60
55
|
}
|
|
@@ -82,6 +77,9 @@ var cors = (options) => {
|
|
|
82
77
|
});
|
|
83
78
|
}
|
|
84
79
|
await next();
|
|
80
|
+
if (opts.origin !== "*") {
|
|
81
|
+
c.header("Vary", "Origin", { append: true });
|
|
82
|
+
}
|
|
85
83
|
};
|
|
86
84
|
};
|
|
87
85
|
export {
|
|
@@ -6,7 +6,7 @@ var requestId = ({
|
|
|
6
6
|
} = {}) => {
|
|
7
7
|
return async function requestId2(c, next) {
|
|
8
8
|
let reqId = headerName ? c.req.header(headerName) : void 0;
|
|
9
|
-
if (!reqId || reqId.length > limitLength || /[^\w
|
|
9
|
+
if (!reqId || reqId.length > limitLength || /[^\w\-=]/.test(reqId)) {
|
|
10
10
|
reqId = generator(c);
|
|
11
11
|
}
|
|
12
12
|
c.set("requestId", reqId);
|
|
@@ -22,6 +22,8 @@ export type VerifyOptions = {
|
|
|
22
22
|
exp?: boolean;
|
|
23
23
|
/** Verify the `iat` claim (default: `true`) */
|
|
24
24
|
iat?: boolean;
|
|
25
|
+
/** Acceptable audience(s) for the token */
|
|
26
|
+
aud?: string | string[] | RegExp;
|
|
25
27
|
};
|
|
26
28
|
export type VerifyOptionsWithAlg = {
|
|
27
29
|
/** The algorithm used for decoding the token */
|
|
@@ -29,6 +29,12 @@ export declare class JwtHeaderRequiresKid extends Error {
|
|
|
29
29
|
export declare class JwtTokenSignatureMismatched extends Error {
|
|
30
30
|
constructor(token: string);
|
|
31
31
|
}
|
|
32
|
+
export declare class JwtPayloadRequiresAud extends Error {
|
|
33
|
+
constructor(payload: object);
|
|
34
|
+
}
|
|
35
|
+
export declare class JwtTokenAudience extends Error {
|
|
36
|
+
constructor(expected: string | string[] | RegExp, aud: string | string[]);
|
|
37
|
+
}
|
|
32
38
|
export declare enum CryptoKeyUsage {
|
|
33
39
|
Encrypt = "encrypt",
|
|
34
40
|
Decrypt = "decrypt",
|
|
@@ -60,5 +66,9 @@ export type JWTPayload = {
|
|
|
60
66
|
* The token is checked to ensure it has been issued by a trusted issuer.
|
|
61
67
|
*/
|
|
62
68
|
iss?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The token is checked to ensure it is intended for a specific audience.
|
|
71
|
+
*/
|
|
72
|
+
aud?: string | string[];
|
|
63
73
|
};
|
|
64
74
|
export type { HonoJsonWebKey } from './jws';
|
package/dist/utils/jwt/jwt.js
CHANGED
|
@@ -5,6 +5,8 @@ import { signing, verifying } from "./jws.js";
|
|
|
5
5
|
import {
|
|
6
6
|
JwtHeaderInvalid,
|
|
7
7
|
JwtHeaderRequiresKid,
|
|
8
|
+
JwtPayloadRequiresAud,
|
|
9
|
+
JwtTokenAudience,
|
|
8
10
|
JwtTokenExpired,
|
|
9
11
|
JwtTokenInvalid,
|
|
10
12
|
JwtTokenIssuedAt,
|
|
@@ -38,14 +40,14 @@ var sign = async (payload, privateKey, alg = "HS256") => {
|
|
|
38
40
|
return `${partialToken}.${signature}`;
|
|
39
41
|
};
|
|
40
42
|
var verify = async (token, publicKey, algOrOptions) => {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
};
|
|
43
|
+
const {
|
|
44
|
+
alg = "HS256",
|
|
45
|
+
iss,
|
|
46
|
+
nbf = true,
|
|
47
|
+
exp = true,
|
|
48
|
+
iat = true,
|
|
49
|
+
aud
|
|
50
|
+
} = typeof algOrOptions === "string" ? { alg: algOrOptions } : algOrOptions || {};
|
|
49
51
|
const tokenParts = token.split(".");
|
|
50
52
|
if (tokenParts.length !== 3) {
|
|
51
53
|
throw new JwtTokenInvalid(token);
|
|
@@ -55,30 +57,42 @@ var verify = async (token, publicKey, algOrOptions) => {
|
|
|
55
57
|
throw new JwtHeaderInvalid(header);
|
|
56
58
|
}
|
|
57
59
|
const now = Date.now() / 1e3 | 0;
|
|
58
|
-
if (
|
|
60
|
+
if (nbf && payload.nbf && payload.nbf > now) {
|
|
59
61
|
throw new JwtTokenNotBefore(token);
|
|
60
62
|
}
|
|
61
|
-
if (
|
|
63
|
+
if (exp && payload.exp && payload.exp <= now) {
|
|
62
64
|
throw new JwtTokenExpired(token);
|
|
63
65
|
}
|
|
64
|
-
if (
|
|
66
|
+
if (iat && payload.iat && now < payload.iat) {
|
|
65
67
|
throw new JwtTokenIssuedAt(now, payload.iat);
|
|
66
68
|
}
|
|
67
|
-
if (
|
|
69
|
+
if (iss) {
|
|
68
70
|
if (!payload.iss) {
|
|
69
|
-
throw new JwtTokenIssuer(
|
|
71
|
+
throw new JwtTokenIssuer(iss, null);
|
|
70
72
|
}
|
|
71
|
-
if (typeof
|
|
72
|
-
throw new JwtTokenIssuer(
|
|
73
|
+
if (typeof iss === "string" && payload.iss !== iss) {
|
|
74
|
+
throw new JwtTokenIssuer(iss, payload.iss);
|
|
73
75
|
}
|
|
74
|
-
if (
|
|
75
|
-
throw new JwtTokenIssuer(
|
|
76
|
+
if (iss instanceof RegExp && !iss.test(payload.iss)) {
|
|
77
|
+
throw new JwtTokenIssuer(iss, payload.iss);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (aud) {
|
|
81
|
+
if (!payload.aud) {
|
|
82
|
+
throw new JwtPayloadRequiresAud(payload);
|
|
83
|
+
}
|
|
84
|
+
const audiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
|
|
85
|
+
const matched = audiences.some(
|
|
86
|
+
(payloadAud) => aud instanceof RegExp ? aud.test(payloadAud) : typeof aud === "string" ? payloadAud === aud : Array.isArray(aud) && aud.includes(payloadAud)
|
|
87
|
+
);
|
|
88
|
+
if (!matched) {
|
|
89
|
+
throw new JwtTokenAudience(aud, payload.aud);
|
|
76
90
|
}
|
|
77
91
|
}
|
|
78
92
|
const headerPayload = token.substring(0, token.lastIndexOf("."));
|
|
79
93
|
const verified = await verifying(
|
|
80
94
|
publicKey,
|
|
81
|
-
|
|
95
|
+
alg,
|
|
82
96
|
decodeBase64Url(tokenParts[2]),
|
|
83
97
|
utf8Encoder.encode(headerPayload)
|
|
84
98
|
);
|
package/dist/utils/jwt/types.js
CHANGED
|
@@ -55,6 +55,20 @@ var JwtTokenSignatureMismatched = class extends Error {
|
|
|
55
55
|
this.name = "JwtTokenSignatureMismatched";
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
|
+
var JwtPayloadRequiresAud = class extends Error {
|
|
59
|
+
constructor(payload) {
|
|
60
|
+
super(`required "aud" in jwt payload: ${JSON.stringify(payload)}`);
|
|
61
|
+
this.name = "JwtPayloadRequiresAud";
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var JwtTokenAudience = class extends Error {
|
|
65
|
+
constructor(expected, aud) {
|
|
66
|
+
super(
|
|
67
|
+
`expected audience "${Array.isArray(expected) ? expected.join(", ") : expected}", got "${aud}"`
|
|
68
|
+
);
|
|
69
|
+
this.name = "JwtTokenAudience";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
58
72
|
var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
|
|
59
73
|
CryptoKeyUsage2["Encrypt"] = "encrypt";
|
|
60
74
|
CryptoKeyUsage2["Decrypt"] = "decrypt";
|
|
@@ -71,6 +85,8 @@ export {
|
|
|
71
85
|
JwtAlgorithmNotImplemented,
|
|
72
86
|
JwtHeaderInvalid,
|
|
73
87
|
JwtHeaderRequiresKid,
|
|
88
|
+
JwtPayloadRequiresAud,
|
|
89
|
+
JwtTokenAudience,
|
|
74
90
|
JwtTokenExpired,
|
|
75
91
|
JwtTokenInvalid,
|
|
76
92
|
JwtTokenIssuedAt,
|