hono 4.8.12 → 4.9.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/adapter/aws-lambda/handler.js +6 -5
- package/dist/adapter/aws-lambda/index.js +2 -1
- package/dist/adapter/bun/index.js +4 -2
- package/dist/adapter/bun/serve-static.js +2 -5
- package/dist/adapter/bun/websocket.js +47 -50
- package/dist/adapter/deno/serve-static.js +2 -4
- package/dist/cjs/adapter/aws-lambda/handler.js +7 -6
- package/dist/cjs/adapter/aws-lambda/index.js +2 -0
- package/dist/cjs/adapter/bun/index.js +6 -2
- package/dist/cjs/adapter/bun/serve-static.js +2 -5
- package/dist/cjs/adapter/bun/websocket.js +50 -51
- package/dist/cjs/adapter/deno/serve-static.js +2 -4
- package/dist/cjs/client/fetch-result-please.js +73 -0
- package/dist/cjs/client/index.js +7 -2
- package/dist/cjs/client/utils.js +8 -0
- package/dist/cjs/helper/cookie/index.js +14 -2
- package/dist/cjs/middleware/jwk/jwk.js +4 -2
- package/dist/cjs/middleware/jwt/index.js +4 -2
- package/dist/cjs/middleware/jwt/jwt.js +10 -3
- package/dist/cjs/middleware/serve-static/index.js +22 -60
- package/dist/cjs/middleware/serve-static/path.js +41 -0
- package/dist/cjs/utils/jwt/index.js +1 -1
- package/dist/cjs/utils/jwt/jwt.js +33 -10
- package/dist/cjs/utils/jwt/types.js +8 -0
- package/dist/client/fetch-result-please.js +49 -0
- package/dist/client/index.js +4 -1
- package/dist/client/utils.js +6 -0
- package/dist/helper/cookie/index.js +12 -2
- package/dist/middleware/jwk/jwk.js +4 -2
- package/dist/middleware/jwt/index.js +3 -2
- package/dist/middleware/jwt/jwt.js +8 -2
- package/dist/middleware/serve-static/index.js +22 -60
- package/dist/middleware/serve-static/path.js +18 -0
- package/dist/types/adapter/aws-lambda/handler.d.ts +50 -4
- package/dist/types/adapter/aws-lambda/index.d.ts +1 -1
- package/dist/types/adapter/bun/index.d.ts +1 -1
- package/dist/types/adapter/bun/websocket.d.ts +6 -0
- package/dist/types/client/fetch-result-please.d.ts +35 -0
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/client/utils.d.ts +11 -0
- package/dist/types/helper/adapter/index.d.ts +1 -1
- package/dist/types/helper/cookie/index.d.ts +2 -0
- package/dist/types/helper/ssg/ssg.d.ts +9 -0
- package/dist/types/middleware/jwk/jwk.d.ts +9 -1
- package/dist/types/middleware/jwt/index.d.ts +1 -1
- package/dist/types/middleware/jwt/jwt.d.ts +9 -1
- package/dist/types/middleware/serve-static/index.d.ts +8 -0
- package/dist/types/middleware/serve-static/path.d.ts +5 -0
- package/dist/types/request.d.ts +0 -5
- package/dist/types/utils/jwt/index.d.ts +3 -2
- package/dist/types/utils/jwt/jwt.d.ts +17 -2
- package/dist/types/utils/jwt/types.d.ts +7 -0
- package/dist/utils/jwt/index.js +2 -2
- package/dist/utils/jwt/jwt.js +33 -9
- package/dist/utils/jwt/types.js +7 -0
- package/package.json +3 -3
|
@@ -19,6 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var cookie_exports = {};
|
|
20
20
|
__export(cookie_exports, {
|
|
21
21
|
deleteCookie: () => deleteCookie,
|
|
22
|
+
generateCookie: () => generateCookie,
|
|
23
|
+
generateSignedCookie: () => generateSignedCookie,
|
|
22
24
|
getCookie: () => getCookie,
|
|
23
25
|
getSignedCookie: () => getSignedCookie,
|
|
24
26
|
setCookie: () => setCookie,
|
|
@@ -68,7 +70,7 @@ const getSignedCookie = async (c, secret, key, prefix) => {
|
|
|
68
70
|
const obj = await (0, import_cookie.parseSigned)(cookie, secret);
|
|
69
71
|
return obj;
|
|
70
72
|
};
|
|
71
|
-
const
|
|
73
|
+
const generateCookie = (name, value, opt) => {
|
|
72
74
|
let cookie;
|
|
73
75
|
if (opt?.prefix === "secure") {
|
|
74
76
|
cookie = (0, import_cookie.serialize)("__Secure-" + name, value, { path: "/", ...opt, secure: true });
|
|
@@ -82,9 +84,13 @@ const setCookie = (c, name, value, opt) => {
|
|
|
82
84
|
} else {
|
|
83
85
|
cookie = (0, import_cookie.serialize)(name, value, { path: "/", ...opt });
|
|
84
86
|
}
|
|
87
|
+
return cookie;
|
|
88
|
+
};
|
|
89
|
+
const setCookie = (c, name, value, opt) => {
|
|
90
|
+
const cookie = generateCookie(name, value, opt);
|
|
85
91
|
c.header("Set-Cookie", cookie, { append: true });
|
|
86
92
|
};
|
|
87
|
-
const
|
|
93
|
+
const generateSignedCookie = async (name, value, secret, opt) => {
|
|
88
94
|
let cookie;
|
|
89
95
|
if (opt?.prefix === "secure") {
|
|
90
96
|
cookie = await (0, import_cookie.serializeSigned)("__Secure-" + name, value, secret, {
|
|
@@ -102,6 +108,10 @@ const setSignedCookie = async (c, name, value, secret, opt) => {
|
|
|
102
108
|
} else {
|
|
103
109
|
cookie = await (0, import_cookie.serializeSigned)(name, value, secret, { path: "/", ...opt });
|
|
104
110
|
}
|
|
111
|
+
return cookie;
|
|
112
|
+
};
|
|
113
|
+
const setSignedCookie = async (c, name, value, secret, opt) => {
|
|
114
|
+
const cookie = await generateSignedCookie(name, value, secret, opt);
|
|
105
115
|
c.header("set-cookie", cookie, { append: true });
|
|
106
116
|
};
|
|
107
117
|
const deleteCookie = (c, name, opt) => {
|
|
@@ -112,6 +122,8 @@ const deleteCookie = (c, name, opt) => {
|
|
|
112
122
|
// Annotate the CommonJS export names for ESM import in node:
|
|
113
123
|
0 && (module.exports = {
|
|
114
124
|
deleteCookie,
|
|
125
|
+
generateCookie,
|
|
126
|
+
generateSignedCookie,
|
|
115
127
|
getCookie,
|
|
116
128
|
getSignedCookie,
|
|
117
129
|
setCookie,
|
|
@@ -26,6 +26,7 @@ var import_http_exception = require("../../http-exception");
|
|
|
26
26
|
var import_jwt = require("../../utils/jwt");
|
|
27
27
|
var import_context = require("../../context");
|
|
28
28
|
const jwk = (options, init) => {
|
|
29
|
+
const verifyOpts = options.verification || {};
|
|
29
30
|
if (!options || !(options.keys || options.jwks_uri)) {
|
|
30
31
|
throw new Error('JWK auth middleware requires options for either "keys" or "jwks_uri" or both');
|
|
31
32
|
}
|
|
@@ -33,7 +34,8 @@ const jwk = (options, init) => {
|
|
|
33
34
|
throw new Error("`crypto.subtle.importKey` is undefined. JWK auth middleware requires it.");
|
|
34
35
|
}
|
|
35
36
|
return async function jwk2(ctx, next) {
|
|
36
|
-
const
|
|
37
|
+
const headerName = options.headerName || "Authorization";
|
|
38
|
+
const credentials = ctx.req.raw.headers.get(headerName);
|
|
37
39
|
let token;
|
|
38
40
|
if (credentials) {
|
|
39
41
|
const parts = credentials.split(/\s+/);
|
|
@@ -91,7 +93,7 @@ const jwk = (options, init) => {
|
|
|
91
93
|
try {
|
|
92
94
|
const keys = typeof options.keys === "function" ? await options.keys(ctx) : options.keys;
|
|
93
95
|
const jwks_uri = typeof options.jwks_uri === "function" ? await options.jwks_uri(ctx) : options.jwks_uri;
|
|
94
|
-
payload = await import_jwt.Jwt.
|
|
96
|
+
payload = await import_jwt.Jwt.verifyWithJwks(token, { keys, jwks_uri, verification: verifyOpts }, init);
|
|
95
97
|
} catch (e) {
|
|
96
98
|
cause = e;
|
|
97
99
|
}
|
|
@@ -21,7 +21,8 @@ __export(jwt_exports, {
|
|
|
21
21
|
decode: () => import_jwt.decode,
|
|
22
22
|
jwt: () => import_jwt.jwt,
|
|
23
23
|
sign: () => import_jwt.sign,
|
|
24
|
-
verify: () => import_jwt.verify
|
|
24
|
+
verify: () => import_jwt.verify,
|
|
25
|
+
verifyWithJwks: () => import_jwt.verifyWithJwks
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(jwt_exports);
|
|
27
28
|
var import_jwt = require("./jwt");
|
|
@@ -30,5 +31,6 @@ var import_jwt = require("./jwt");
|
|
|
30
31
|
decode,
|
|
31
32
|
jwt,
|
|
32
33
|
sign,
|
|
33
|
-
verify
|
|
34
|
+
verify,
|
|
35
|
+
verifyWithJwks
|
|
34
36
|
});
|
|
@@ -21,7 +21,8 @@ __export(jwt_exports, {
|
|
|
21
21
|
decode: () => decode,
|
|
22
22
|
jwt: () => jwt,
|
|
23
23
|
sign: () => sign,
|
|
24
|
-
verify: () => verify
|
|
24
|
+
verify: () => verify,
|
|
25
|
+
verifyWithJwks: () => verifyWithJwks
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(jwt_exports);
|
|
27
28
|
var import_cookie = require("../../helper/cookie");
|
|
@@ -29,6 +30,7 @@ var import_http_exception = require("../../http-exception");
|
|
|
29
30
|
var import_jwt = require("../../utils/jwt");
|
|
30
31
|
var import_context = require("../../context");
|
|
31
32
|
const jwt = (options) => {
|
|
33
|
+
const verifyOpts = options.verification || {};
|
|
32
34
|
if (!options || !options.secret) {
|
|
33
35
|
throw new Error('JWT auth middleware requires options for "secret"');
|
|
34
36
|
}
|
|
@@ -90,7 +92,10 @@ const jwt = (options) => {
|
|
|
90
92
|
let payload;
|
|
91
93
|
let cause;
|
|
92
94
|
try {
|
|
93
|
-
payload = await import_jwt.Jwt.verify(token, options.secret,
|
|
95
|
+
payload = await import_jwt.Jwt.verify(token, options.secret, {
|
|
96
|
+
alg: options.alg,
|
|
97
|
+
...verifyOpts
|
|
98
|
+
});
|
|
94
99
|
} catch (e) {
|
|
95
100
|
cause = e;
|
|
96
101
|
}
|
|
@@ -119,6 +124,7 @@ function unauthorizedResponse(opts) {
|
|
|
119
124
|
}
|
|
120
125
|
});
|
|
121
126
|
}
|
|
127
|
+
const verifyWithJwks = import_jwt.Jwt.verifyWithJwks;
|
|
122
128
|
const verify = import_jwt.Jwt.verify;
|
|
123
129
|
const decode = import_jwt.Jwt.decode;
|
|
124
130
|
const sign = import_jwt.Jwt.sign;
|
|
@@ -127,5 +133,6 @@ const sign = import_jwt.Jwt.sign;
|
|
|
127
133
|
decode,
|
|
128
134
|
jwt,
|
|
129
135
|
sign,
|
|
130
|
-
verify
|
|
136
|
+
verify,
|
|
137
|
+
verifyWithJwks
|
|
131
138
|
});
|
|
@@ -22,8 +22,8 @@ __export(serve_static_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(serve_static_exports);
|
|
24
24
|
var import_compress = require("../../utils/compress");
|
|
25
|
-
var import_filepath = require("../../utils/filepath");
|
|
26
25
|
var import_mime = require("../../utils/mime");
|
|
26
|
+
var import_path = require("./path");
|
|
27
27
|
const ENCODINGS = {
|
|
28
28
|
br: ".br",
|
|
29
29
|
zstd: ".zst",
|
|
@@ -31,75 +31,37 @@ const ENCODINGS = {
|
|
|
31
31
|
};
|
|
32
32
|
const ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
33
33
|
const DEFAULT_DOCUMENT = "index.html";
|
|
34
|
-
const defaultPathResolve = (path) => path;
|
|
35
|
-
const isAbsolutePath = (path) => {
|
|
36
|
-
const isUnixAbsolutePath = path.startsWith("/");
|
|
37
|
-
const hasDriveLetter = /^[a-zA-Z]:\\/.test(path);
|
|
38
|
-
const isUncPath = /^\\\\[^\\]+\\[^\\]+/.test(path);
|
|
39
|
-
return isUnixAbsolutePath || hasDriveLetter || isUncPath;
|
|
40
|
-
};
|
|
41
|
-
const windowsPathToUnixPath = (path) => {
|
|
42
|
-
return path.replace(/^[a-zA-Z]:/, "").replace(/\\/g, "/");
|
|
43
|
-
};
|
|
44
34
|
const serveStatic = (options) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (isAbsolutePath(options.root)) {
|
|
49
|
-
isAbsoluteRoot = true;
|
|
50
|
-
root = windowsPathToUnixPath(options.root);
|
|
51
|
-
root = new URL(`file://${root}`).pathname;
|
|
52
|
-
} else {
|
|
53
|
-
root = options.root;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
35
|
+
const root = options.root ?? "./";
|
|
36
|
+
const optionPath = options.path;
|
|
37
|
+
const join = options.join ?? import_path.defaultJoin;
|
|
56
38
|
return async (c, next) => {
|
|
57
39
|
if (c.finalized) {
|
|
58
|
-
|
|
59
|
-
return;
|
|
40
|
+
return next();
|
|
60
41
|
}
|
|
61
|
-
let filename
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
42
|
+
let filename;
|
|
43
|
+
if (options.path) {
|
|
44
|
+
filename = options.path;
|
|
45
|
+
} else {
|
|
46
|
+
try {
|
|
47
|
+
filename = decodeURIComponent(c.req.path);
|
|
48
|
+
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
49
|
+
throw new Error();
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
await options.onNotFound?.(c.req.path, c);
|
|
53
|
+
return next();
|
|
70
54
|
}
|
|
71
55
|
}
|
|
72
|
-
let path = (
|
|
73
|
-
filename,
|
|
56
|
+
let path = join(
|
|
74
57
|
root,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
if (isAbsoluteRoot) {
|
|
81
|
-
path = "/" + path;
|
|
58
|
+
!optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename
|
|
59
|
+
);
|
|
60
|
+
if (options.isDir && await options.isDir(path)) {
|
|
61
|
+
path = join(path, DEFAULT_DOCUMENT);
|
|
82
62
|
}
|
|
83
63
|
const getContent = options.getContent;
|
|
84
|
-
const pathResolve = options.pathResolve ?? defaultPathResolve;
|
|
85
|
-
path = pathResolve(path);
|
|
86
64
|
let content = await getContent(path, c);
|
|
87
|
-
if (!content) {
|
|
88
|
-
let pathWithoutDefaultDocument = (0, import_filepath.getFilePathWithoutDefaultDocument)({
|
|
89
|
-
filename,
|
|
90
|
-
root
|
|
91
|
-
});
|
|
92
|
-
if (!pathWithoutDefaultDocument) {
|
|
93
|
-
return await next();
|
|
94
|
-
}
|
|
95
|
-
pathWithoutDefaultDocument = pathResolve(pathWithoutDefaultDocument);
|
|
96
|
-
if (pathWithoutDefaultDocument !== path) {
|
|
97
|
-
content = await getContent(pathWithoutDefaultDocument, c);
|
|
98
|
-
if (content) {
|
|
99
|
-
path = pathWithoutDefaultDocument;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
65
|
if (content instanceof Response) {
|
|
104
66
|
return c.newResponse(content.body, content);
|
|
105
67
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var path_exports = {};
|
|
20
|
+
__export(path_exports, {
|
|
21
|
+
defaultJoin: () => defaultJoin
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(path_exports);
|
|
24
|
+
const defaultJoin = (...paths) => {
|
|
25
|
+
let result = paths.filter((p) => p !== "").join("/");
|
|
26
|
+
result = result.replace(/(?<=\/)\/+/g, "");
|
|
27
|
+
const segments = result.split("/");
|
|
28
|
+
const resolved = [];
|
|
29
|
+
for (const segment of segments) {
|
|
30
|
+
if (segment === ".." && resolved.length > 0 && resolved.at(-1) !== "..") {
|
|
31
|
+
resolved.pop();
|
|
32
|
+
} else if (segment !== ".") {
|
|
33
|
+
resolved.push(segment);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return resolved.join("/") || ".";
|
|
37
|
+
};
|
|
38
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
39
|
+
0 && (module.exports = {
|
|
40
|
+
defaultJoin
|
|
41
|
+
});
|
|
@@ -22,7 +22,7 @@ __export(jwt_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(jwt_exports);
|
|
24
24
|
var import_jwt = require("./jwt");
|
|
25
|
-
const Jwt = { sign: import_jwt.sign, verify: import_jwt.verify, decode: import_jwt.decode,
|
|
25
|
+
const Jwt = { sign: import_jwt.sign, verify: import_jwt.verify, decode: import_jwt.decode, verifyWithJwks: import_jwt.verifyWithJwks };
|
|
26
26
|
// Annotate the CommonJS export names for ESM import in node:
|
|
27
27
|
0 && (module.exports = {
|
|
28
28
|
Jwt
|
|
@@ -23,7 +23,7 @@ __export(jwt_exports, {
|
|
|
23
23
|
isTokenHeader: () => isTokenHeader,
|
|
24
24
|
sign: () => sign,
|
|
25
25
|
verify: () => verify,
|
|
26
|
-
|
|
26
|
+
verifyWithJwks: () => verifyWithJwks
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(jwt_exports);
|
|
29
29
|
var import_encode = require("../../utils/encode");
|
|
@@ -55,7 +55,15 @@ const sign = async (payload, privateKey, alg = "HS256") => {
|
|
|
55
55
|
const signature = encodeSignaturePart(signaturePart);
|
|
56
56
|
return `${partialToken}.${signature}`;
|
|
57
57
|
};
|
|
58
|
-
const verify = async (token, publicKey,
|
|
58
|
+
const verify = async (token, publicKey, algOrOptions) => {
|
|
59
|
+
const optsIn = typeof algOrOptions === "string" ? { alg: algOrOptions } : algOrOptions || {};
|
|
60
|
+
const opts = {
|
|
61
|
+
alg: optsIn.alg ?? "HS256",
|
|
62
|
+
iss: optsIn.iss,
|
|
63
|
+
nbf: optsIn.nbf ?? true,
|
|
64
|
+
exp: optsIn.exp ?? true,
|
|
65
|
+
iat: optsIn.iat ?? true
|
|
66
|
+
};
|
|
59
67
|
const tokenParts = token.split(".");
|
|
60
68
|
if (tokenParts.length !== 3) {
|
|
61
69
|
throw new import_types.JwtTokenInvalid(token);
|
|
@@ -65,19 +73,30 @@ const verify = async (token, publicKey, alg = "HS256") => {
|
|
|
65
73
|
throw new import_types.JwtHeaderInvalid(header);
|
|
66
74
|
}
|
|
67
75
|
const now = Date.now() / 1e3 | 0;
|
|
68
|
-
if (payload.nbf && payload.nbf > now) {
|
|
76
|
+
if (opts.nbf && payload.nbf && payload.nbf > now) {
|
|
69
77
|
throw new import_types.JwtTokenNotBefore(token);
|
|
70
78
|
}
|
|
71
|
-
if (payload.exp && payload.exp <= now) {
|
|
79
|
+
if (opts.exp && payload.exp && payload.exp <= now) {
|
|
72
80
|
throw new import_types.JwtTokenExpired(token);
|
|
73
81
|
}
|
|
74
|
-
if (payload.iat && now < payload.iat) {
|
|
82
|
+
if (opts.iat && payload.iat && now < payload.iat) {
|
|
75
83
|
throw new import_types.JwtTokenIssuedAt(now, payload.iat);
|
|
76
84
|
}
|
|
85
|
+
if (opts.iss) {
|
|
86
|
+
if (!payload.iss) {
|
|
87
|
+
throw new import_types.JwtTokenIssuer(opts.iss, null);
|
|
88
|
+
}
|
|
89
|
+
if (typeof opts.iss === "string" && payload.iss !== opts.iss) {
|
|
90
|
+
throw new import_types.JwtTokenIssuer(opts.iss, payload.iss);
|
|
91
|
+
}
|
|
92
|
+
if (opts.iss instanceof RegExp && !opts.iss.test(payload.iss)) {
|
|
93
|
+
throw new import_types.JwtTokenIssuer(opts.iss, payload.iss);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
77
96
|
const headerPayload = token.substring(0, token.lastIndexOf("."));
|
|
78
97
|
const verified = await (0, import_jws.verifying)(
|
|
79
98
|
publicKey,
|
|
80
|
-
alg,
|
|
99
|
+
opts.alg,
|
|
81
100
|
(0, import_encode.decodeBase64Url)(tokenParts[2]),
|
|
82
101
|
import_utf8.utf8Encoder.encode(headerPayload)
|
|
83
102
|
);
|
|
@@ -86,7 +105,8 @@ const verify = async (token, publicKey, alg = "HS256") => {
|
|
|
86
105
|
}
|
|
87
106
|
return payload;
|
|
88
107
|
};
|
|
89
|
-
const
|
|
108
|
+
const verifyWithJwks = async (token, options, init) => {
|
|
109
|
+
const verifyOpts = options.verification || {};
|
|
90
110
|
const header = decodeHeader(token);
|
|
91
111
|
if (!isTokenHeader(header)) {
|
|
92
112
|
throw new import_types.JwtHeaderInvalid(header);
|
|
@@ -112,13 +132,16 @@ const verifyFromJwks = async (token, options, init) => {
|
|
|
112
132
|
options.keys = data.keys;
|
|
113
133
|
}
|
|
114
134
|
} else if (!options.keys) {
|
|
115
|
-
throw new Error('
|
|
135
|
+
throw new Error('verifyWithJwks requires options for either "keys" or "jwks_uri" or both');
|
|
116
136
|
}
|
|
117
137
|
const matchingKey = options.keys.find((key) => key.kid === header.kid);
|
|
118
138
|
if (!matchingKey) {
|
|
119
139
|
throw new import_types.JwtTokenInvalid(token);
|
|
120
140
|
}
|
|
121
|
-
return await verify(token, matchingKey,
|
|
141
|
+
return await verify(token, matchingKey, {
|
|
142
|
+
alg: matchingKey.alg || header.alg,
|
|
143
|
+
...verifyOpts
|
|
144
|
+
});
|
|
122
145
|
};
|
|
123
146
|
const decode = (token) => {
|
|
124
147
|
try {
|
|
@@ -148,5 +171,5 @@ const decodeHeader = (token) => {
|
|
|
148
171
|
isTokenHeader,
|
|
149
172
|
sign,
|
|
150
173
|
verify,
|
|
151
|
-
|
|
174
|
+
verifyWithJwks
|
|
152
175
|
});
|
|
@@ -25,6 +25,7 @@ __export(types_exports, {
|
|
|
25
25
|
JwtTokenExpired: () => JwtTokenExpired,
|
|
26
26
|
JwtTokenInvalid: () => JwtTokenInvalid,
|
|
27
27
|
JwtTokenIssuedAt: () => JwtTokenIssuedAt,
|
|
28
|
+
JwtTokenIssuer: () => JwtTokenIssuer,
|
|
28
29
|
JwtTokenNotBefore: () => JwtTokenNotBefore,
|
|
29
30
|
JwtTokenSignatureMismatched: () => JwtTokenSignatureMismatched
|
|
30
31
|
});
|
|
@@ -61,6 +62,12 @@ class JwtTokenIssuedAt extends Error {
|
|
|
61
62
|
this.name = "JwtTokenIssuedAt";
|
|
62
63
|
}
|
|
63
64
|
}
|
|
65
|
+
class JwtTokenIssuer extends Error {
|
|
66
|
+
constructor(expected, iss) {
|
|
67
|
+
super(`expected issuer "${expected}", got ${iss ? `"${iss}"` : "none"} `);
|
|
68
|
+
this.name = "JwtTokenIssuer";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
64
71
|
class JwtHeaderInvalid extends Error {
|
|
65
72
|
constructor(header) {
|
|
66
73
|
super(`jwt header is invalid: ${JSON.stringify(header)}`);
|
|
@@ -99,6 +106,7 @@ var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
|
|
|
99
106
|
JwtTokenExpired,
|
|
100
107
|
JwtTokenInvalid,
|
|
101
108
|
JwtTokenIssuedAt,
|
|
109
|
+
JwtTokenIssuer,
|
|
102
110
|
JwtTokenNotBefore,
|
|
103
111
|
JwtTokenSignatureMismatched
|
|
104
112
|
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/client/fetch-result-please.ts
|
|
2
|
+
var nullBodyResponses = /* @__PURE__ */ new Set([101, 204, 205, 304]);
|
|
3
|
+
async function fetchRP(fetchRes) {
|
|
4
|
+
const _fetchRes = await fetchRes;
|
|
5
|
+
const hasBody = _fetchRes.body && !nullBodyResponses.has(_fetchRes.status);
|
|
6
|
+
if (hasBody) {
|
|
7
|
+
const responseType = detectResponseType(_fetchRes);
|
|
8
|
+
_fetchRes._data = await _fetchRes[responseType]();
|
|
9
|
+
}
|
|
10
|
+
if (!_fetchRes.ok) {
|
|
11
|
+
throw new DetailedError(`${_fetchRes.status} ${_fetchRes.statusText}`, {
|
|
12
|
+
statusCode: _fetchRes?.status,
|
|
13
|
+
detail: {
|
|
14
|
+
data: _fetchRes?._data,
|
|
15
|
+
statusText: _fetchRes?.statusText
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return _fetchRes._data;
|
|
20
|
+
}
|
|
21
|
+
var DetailedError = class extends Error {
|
|
22
|
+
detail;
|
|
23
|
+
code;
|
|
24
|
+
log;
|
|
25
|
+
statusCode;
|
|
26
|
+
constructor(message, options = {}) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.log = options.log;
|
|
29
|
+
this.detail = options.detail;
|
|
30
|
+
this.code = options.code;
|
|
31
|
+
this.statusCode = options.statusCode;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var jsonRegex = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(?:;.+)?$/i;
|
|
35
|
+
function detectResponseType(response) {
|
|
36
|
+
const _contentType = response.headers.get("content-type");
|
|
37
|
+
if (!_contentType) {
|
|
38
|
+
return "text";
|
|
39
|
+
}
|
|
40
|
+
const contentType = _contentType.split(";").shift();
|
|
41
|
+
if (jsonRegex.test(contentType)) {
|
|
42
|
+
return "json";
|
|
43
|
+
}
|
|
44
|
+
return "text";
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
DetailedError,
|
|
48
|
+
fetchRP
|
|
49
|
+
};
|
package/dist/client/index.js
CHANGED
package/dist/client/utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/client/utils.ts
|
|
2
|
+
import { fetchRP, DetailedError } from "./fetch-result-please.js";
|
|
2
3
|
var mergePath = (base, path) => {
|
|
3
4
|
base = base.replace(/\/+$/, "");
|
|
4
5
|
base = base + "/";
|
|
@@ -60,10 +61,15 @@ function deepMerge(target, source) {
|
|
|
60
61
|
}
|
|
61
62
|
return merged;
|
|
62
63
|
}
|
|
64
|
+
async function parseResponse(fetchRes) {
|
|
65
|
+
return fetchRP(fetchRes);
|
|
66
|
+
}
|
|
63
67
|
export {
|
|
68
|
+
DetailedError,
|
|
64
69
|
buildSearchParams,
|
|
65
70
|
deepMerge,
|
|
66
71
|
mergePath,
|
|
72
|
+
parseResponse,
|
|
67
73
|
removeIndexString,
|
|
68
74
|
replaceUrlParam,
|
|
69
75
|
replaceUrlProtocol
|
|
@@ -42,7 +42,7 @@ var getSignedCookie = async (c, secret, key, prefix) => {
|
|
|
42
42
|
const obj = await parseSigned(cookie, secret);
|
|
43
43
|
return obj;
|
|
44
44
|
};
|
|
45
|
-
var
|
|
45
|
+
var generateCookie = (name, value, opt) => {
|
|
46
46
|
let cookie;
|
|
47
47
|
if (opt?.prefix === "secure") {
|
|
48
48
|
cookie = serialize("__Secure-" + name, value, { path: "/", ...opt, secure: true });
|
|
@@ -56,9 +56,13 @@ var setCookie = (c, name, value, opt) => {
|
|
|
56
56
|
} else {
|
|
57
57
|
cookie = serialize(name, value, { path: "/", ...opt });
|
|
58
58
|
}
|
|
59
|
+
return cookie;
|
|
60
|
+
};
|
|
61
|
+
var setCookie = (c, name, value, opt) => {
|
|
62
|
+
const cookie = generateCookie(name, value, opt);
|
|
59
63
|
c.header("Set-Cookie", cookie, { append: true });
|
|
60
64
|
};
|
|
61
|
-
var
|
|
65
|
+
var generateSignedCookie = async (name, value, secret, opt) => {
|
|
62
66
|
let cookie;
|
|
63
67
|
if (opt?.prefix === "secure") {
|
|
64
68
|
cookie = await serializeSigned("__Secure-" + name, value, secret, {
|
|
@@ -76,6 +80,10 @@ var setSignedCookie = async (c, name, value, secret, opt) => {
|
|
|
76
80
|
} else {
|
|
77
81
|
cookie = await serializeSigned(name, value, secret, { path: "/", ...opt });
|
|
78
82
|
}
|
|
83
|
+
return cookie;
|
|
84
|
+
};
|
|
85
|
+
var setSignedCookie = async (c, name, value, secret, opt) => {
|
|
86
|
+
const cookie = await generateSignedCookie(name, value, secret, opt);
|
|
79
87
|
c.header("set-cookie", cookie, { append: true });
|
|
80
88
|
};
|
|
81
89
|
var deleteCookie = (c, name, opt) => {
|
|
@@ -85,6 +93,8 @@ var deleteCookie = (c, name, opt) => {
|
|
|
85
93
|
};
|
|
86
94
|
export {
|
|
87
95
|
deleteCookie,
|
|
96
|
+
generateCookie,
|
|
97
|
+
generateSignedCookie,
|
|
88
98
|
getCookie,
|
|
89
99
|
getSignedCookie,
|
|
90
100
|
setCookie,
|
|
@@ -4,6 +4,7 @@ import { HTTPException } from "../../http-exception.js";
|
|
|
4
4
|
import { Jwt } from "../../utils/jwt/index.js";
|
|
5
5
|
import "../../context.js";
|
|
6
6
|
var jwk = (options, init) => {
|
|
7
|
+
const verifyOpts = options.verification || {};
|
|
7
8
|
if (!options || !(options.keys || options.jwks_uri)) {
|
|
8
9
|
throw new Error('JWK auth middleware requires options for either "keys" or "jwks_uri" or both');
|
|
9
10
|
}
|
|
@@ -11,7 +12,8 @@ var jwk = (options, init) => {
|
|
|
11
12
|
throw new Error("`crypto.subtle.importKey` is undefined. JWK auth middleware requires it.");
|
|
12
13
|
}
|
|
13
14
|
return async function jwk2(ctx, next) {
|
|
14
|
-
const
|
|
15
|
+
const headerName = options.headerName || "Authorization";
|
|
16
|
+
const credentials = ctx.req.raw.headers.get(headerName);
|
|
15
17
|
let token;
|
|
16
18
|
if (credentials) {
|
|
17
19
|
const parts = credentials.split(/\s+/);
|
|
@@ -69,7 +71,7 @@ var jwk = (options, init) => {
|
|
|
69
71
|
try {
|
|
70
72
|
const keys = typeof options.keys === "function" ? await options.keys(ctx) : options.keys;
|
|
71
73
|
const jwks_uri = typeof options.jwks_uri === "function" ? await options.jwks_uri(ctx) : options.jwks_uri;
|
|
72
|
-
payload = await Jwt.
|
|
74
|
+
payload = await Jwt.verifyWithJwks(token, { keys, jwks_uri, verification: verifyOpts }, init);
|
|
73
75
|
} catch (e) {
|
|
74
76
|
cause = e;
|
|
75
77
|
}
|
|
@@ -4,6 +4,7 @@ import { HTTPException } from "../../http-exception.js";
|
|
|
4
4
|
import { Jwt } from "../../utils/jwt/index.js";
|
|
5
5
|
import "../../context.js";
|
|
6
6
|
var jwt = (options) => {
|
|
7
|
+
const verifyOpts = options.verification || {};
|
|
7
8
|
if (!options || !options.secret) {
|
|
8
9
|
throw new Error('JWT auth middleware requires options for "secret"');
|
|
9
10
|
}
|
|
@@ -65,7 +66,10 @@ var jwt = (options) => {
|
|
|
65
66
|
let payload;
|
|
66
67
|
let cause;
|
|
67
68
|
try {
|
|
68
|
-
payload = await Jwt.verify(token, options.secret,
|
|
69
|
+
payload = await Jwt.verify(token, options.secret, {
|
|
70
|
+
alg: options.alg,
|
|
71
|
+
...verifyOpts
|
|
72
|
+
});
|
|
69
73
|
} catch (e) {
|
|
70
74
|
cause = e;
|
|
71
75
|
}
|
|
@@ -94,6 +98,7 @@ function unauthorizedResponse(opts) {
|
|
|
94
98
|
}
|
|
95
99
|
});
|
|
96
100
|
}
|
|
101
|
+
var verifyWithJwks = Jwt.verifyWithJwks;
|
|
97
102
|
var verify = Jwt.verify;
|
|
98
103
|
var decode = Jwt.decode;
|
|
99
104
|
var sign = Jwt.sign;
|
|
@@ -101,5 +106,6 @@ export {
|
|
|
101
106
|
decode,
|
|
102
107
|
jwt,
|
|
103
108
|
sign,
|
|
104
|
-
verify
|
|
109
|
+
verify,
|
|
110
|
+
verifyWithJwks
|
|
105
111
|
};
|