@suveren/gateway 0.7.3 → 0.7.6
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/content/integrations/gmail.json +3 -6
- package/dist/control-plane/index.mjs +294 -62
- package/dist/mcp-server/http.mjs +467 -73
- package/dist/ui/assets/{index-CkWaRck1.css → index-BYVb_0oG.css} +1 -1
- package/dist/ui/assets/index-CsrM6RQr.js +110 -0
- package/dist/ui/index.html +2 -2
- package/node_modules/@hap/core/dist/index.d.mts +258 -9
- package/node_modules/@hap/core/dist/index.d.ts +258 -9
- package/node_modules/@hap/core/dist/index.js +227 -5
- package/node_modules/@hap/core/dist/index.mjs +213 -4
- package/node_modules/@hap/core/package.json +3 -2
- package/node_modules/@hap/core/src/did-key.ts +126 -0
- package/node_modules/@hap/core/src/identity.ts +21 -5
- package/node_modules/@hap/core/src/index.ts +3 -0
- package/node_modules/@hap/core/src/mandate.ts +207 -0
- package/node_modules/@hap/core/src/receipt.ts +74 -0
- package/node_modules/@hap/core/src/types.ts +81 -5
- package/node_modules/@hono/node-server/dist/index.cjs +151 -9
- package/node_modules/@hono/node-server/dist/index.mjs +151 -9
- package/node_modules/@hono/node-server/package.json +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/README.md +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/package.json +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/package.json +16 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/README.md +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/package.json +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.buffer.d.ts +5 -5
- package/node_modules/@types/node/crypto.d.ts +2 -2
- package/node_modules/@types/node/http.d.ts +16 -0
- package/node_modules/@types/node/http2.d.ts +10 -2
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +52 -0
- package/node_modules/@types/node/quic.d.ts +210 -28
- package/node_modules/@types/node/sqlite.d.ts +6 -2
- package/node_modules/@types/node/test.d.ts +36 -0
- package/node_modules/eventsource-parser/dist/index.cjs +2 -2
- package/node_modules/eventsource-parser/dist/index.cjs.map +1 -1
- package/node_modules/eventsource-parser/dist/index.js +2 -2
- package/node_modules/eventsource-parser/dist/index.js.map +1 -1
- package/node_modules/eventsource-parser/package.json +1 -1
- package/node_modules/eventsource-parser/src/parse.ts +4 -2
- package/node_modules/fast-uri/index.js +201 -48
- package/node_modules/fast-uri/lib/schemes.js +9 -4
- package/node_modules/fast-uri/lib/utils.js +388 -91
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +105 -0
- package/node_modules/fast-uri/test/equal.test.js +31 -3
- package/node_modules/fast-uri/test/fixtures/uri-js-parse.json +2 -0
- package/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +90 -0
- package/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
- package/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
- package/node_modules/fast-uri/test/parse.test.js +7 -3
- package/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
- package/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
- package/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
- package/node_modules/fast-uri/test/security-normalization.test.js +101 -0
- package/node_modules/fast-uri/test/security.test.js +75 -3
- package/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
- package/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
- package/node_modules/hono/dist/cjs/client/client.js +27 -13
- package/node_modules/hono/dist/cjs/client/utils.js +4 -1
- package/node_modules/hono/dist/cjs/context.js +4 -0
- package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/cjs/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/cjs/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +16 -13
- package/node_modules/hono/dist/cjs/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/etag/digest.js +47 -1
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +6 -3
- package/node_modules/hono/dist/cjs/request.js +8 -4
- package/node_modules/hono/dist/cjs/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/cjs/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +10 -3
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +47 -83
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/cjs/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/cjs/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/cjs/router/utils.js +27 -0
- package/node_modules/hono/dist/cjs/utils/body.js +15 -3
- package/node_modules/hono/dist/cjs/utils/cookie.js +1 -1
- package/node_modules/hono/dist/cjs/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/cjs/utils/stream.js +7 -1
- package/node_modules/hono/dist/cjs/utils/url.js +11 -3
- package/node_modules/hono/dist/client/client.js +27 -13
- package/node_modules/hono/dist/client/utils.js +4 -1
- package/node_modules/hono/dist/context.js +4 -0
- package/node_modules/hono/dist/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/jsx/intrinsic-element/components.js +1 -1
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/cors/index.js +16 -13
- package/node_modules/hono/dist/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/middleware/etag/digest.js +47 -1
- package/node_modules/hono/dist/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +6 -3
- package/node_modules/hono/dist/request.js +8 -4
- package/node_modules/hono/dist/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/router/reg-exp-router/node.js +6 -2
- package/node_modules/hono/dist/router/reg-exp-router/router.js +53 -84
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/router/utils.js +5 -0
- package/node_modules/hono/dist/types/context.d.ts +4 -0
- package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +3 -0
- package/node_modules/hono/dist/types/router/trie-router/node.d.ts +1 -2
- package/node_modules/hono/dist/types/router/trie-router/router.d.ts +0 -1
- package/node_modules/hono/dist/types/router/utils.d.ts +1 -0
- package/node_modules/hono/dist/types/utils/url.d.ts +4 -0
- package/node_modules/hono/dist/utils/body.js +15 -3
- package/node_modules/hono/dist/utils/cookie.js +1 -1
- package/node_modules/hono/dist/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/utils/stream.js +7 -1
- package/node_modules/hono/dist/utils/url.js +11 -3
- package/node_modules/hono/package.json +1 -1
- package/node_modules/ip-address/README.md +134 -134
- package/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +22 -6
- package/node_modules/ip-address/dist/ipv4.js +22 -6
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +10 -3
- package/node_modules/ip-address/dist/ipv6.js +26 -17
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/is-plain-object/README.md +39 -95
- package/node_modules/is-plain-object/dist/is-plain-object.js +0 -2
- package/node_modules/is-plain-object/is-plain-object.d.ts +6 -1
- package/node_modules/is-plain-object/package.json +8 -34
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwks/remote.d.ts +4 -4
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +3 -3
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +12 -17
- package/node_modules/jose/dist/types/jwt/sign.d.ts +8 -14
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +9 -15
- package/node_modules/jose/dist/types/types.d.ts +4 -2
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +30 -8
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +8 -4
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +6 -13
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +19 -19
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +32 -21
- package/node_modules/jose/dist/webapi/jwk/embedded.js +15 -1
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +11 -5
- package/node_modules/jose/dist/webapi/jwks/local.js +45 -53
- package/node_modules/jose/dist/webapi/jwks/remote.js +82 -103
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +10 -9
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +2 -1
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +8 -7
- package/node_modules/jose/dist/webapi/jws/general/sign.js +5 -3
- package/node_modules/jose/dist/webapi/jws/general/verify.js +51 -21
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +7 -9
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +21 -50
- package/node_modules/jose/dist/webapi/jwt/sign.js +8 -41
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +21 -42
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +6 -2
- package/node_modules/jose/dist/webapi/key/generate_secret.js +7 -6
- package/node_modules/jose/dist/webapi/key/import.js +16 -12
- package/node_modules/jose/dist/webapi/lib/asn1.js +7 -2
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +7 -15
- package/node_modules/jose/dist/webapi/lib/deflate.js +8 -0
- package/node_modules/jose/dist/webapi/lib/helpers.js +1 -1
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +85 -28
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +45 -13
- package/node_modules/jose/dist/webapi/lib/jwk_metadata.js +20 -0
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +47 -36
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +77 -45
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +82 -47
- package/node_modules/jose/dist/webapi/lib/key.js +24 -9
- package/node_modules/jose/dist/webapi/lib/key_management.js +10 -4
- package/node_modules/jose/dist/webapi/lib/key_options.js +6 -0
- package/node_modules/jose/dist/webapi/lib/options.js +26 -0
- package/node_modules/jose/dist/webapi/lib/type_checks.js +11 -13
- package/node_modules/jose/package.json +1 -1
- package/package.json +2 -2
- package/dist/ui/assets/index-DdJeSfV9.js +0 -110
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/HISTORY.md +0 -114
|
@@ -37,3 +37,104 @@ test('equal does not treat reserved path escapes as live path syntax', (t) => {
|
|
|
37
37
|
|
|
38
38
|
t.end()
|
|
39
39
|
})
|
|
40
|
+
|
|
41
|
+
test('serialize preserves literal RFC 3986 reserved path characters', (t) => {
|
|
42
|
+
// GHSA-7mh8-fcmq-x23c: literal reserved path chars must not be rewritten to
|
|
43
|
+
// percent escapes by the escape()-style safe set.
|
|
44
|
+
const cases = [
|
|
45
|
+
'http://example.com/a;b',
|
|
46
|
+
'http://example.com/a=b',
|
|
47
|
+
'http://example.com/a&b',
|
|
48
|
+
'http://example.com/a$b',
|
|
49
|
+
'http://example.com/a:b',
|
|
50
|
+
'http://example.com/a@b'
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
t.plan(cases.length)
|
|
54
|
+
|
|
55
|
+
cases.forEach((uri) => {
|
|
56
|
+
t.equal(fastURI.serialize(fastURI.parse(uri)), uri, uri)
|
|
57
|
+
})
|
|
58
|
+
t.end()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('serialize preserves existing reserved path escapes as data', (t) => {
|
|
62
|
+
// GHSA-7mh8-fcmq-x23c: an existing %3A escape must stay %3A instead of being
|
|
63
|
+
// rewritten into a live colon.
|
|
64
|
+
const cases = [
|
|
65
|
+
'http://example.com/a%3Ab',
|
|
66
|
+
'http://example.com/a%3Bb',
|
|
67
|
+
'http://example.com/a%3D%3D'
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
t.plan(cases.length)
|
|
71
|
+
|
|
72
|
+
cases.forEach((uri) => {
|
|
73
|
+
t.equal(fastURI.serialize(fastURI.parse(uri)), uri, uri)
|
|
74
|
+
})
|
|
75
|
+
t.end()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('serialize keeps path-noscheme colon escaping', (t) => {
|
|
79
|
+
// Without a scheme a literal colon would be reparsed as a scheme separator,
|
|
80
|
+
// so it must stay percent-escaped while an existing %3A is preserved.
|
|
81
|
+
t.equal(fastURI.serialize({ path: 'foo:bar' }), 'foo%3Abar')
|
|
82
|
+
t.equal(fastURI.serialize({ path: 'a%3Ab' }), 'a%3Ab')
|
|
83
|
+
t.end()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('hostname normalization never decodes an escape more than once', (t) => {
|
|
87
|
+
const encodedLocalhost = 'http://%256c%256f%2563%2561%256c%2568%256f%2573%2574/'
|
|
88
|
+
const encodedLoopback = '//127%252e0%252e0%252e1/private'
|
|
89
|
+
const encodedMetadataAddress = '//169%252E254%252E169%252E254/latest/meta-data/'
|
|
90
|
+
|
|
91
|
+
t.equal(fastURI.normalize(encodedLocalhost), encodedLocalhost, 'nested hostname letters remain encoded')
|
|
92
|
+
t.equal(fastURI.normalize(encodedLoopback), encodedLoopback, 'nested IPv4 dots remain encoded')
|
|
93
|
+
t.equal(
|
|
94
|
+
fastURI.resolve('https://safe.example/', encodedLoopback),
|
|
95
|
+
'https://127%252e0%252e0%252e1/private',
|
|
96
|
+
'resolve does not turn nested dots into a loopback address'
|
|
97
|
+
)
|
|
98
|
+
t.equal(
|
|
99
|
+
fastURI.resolve('https://allowed.com/api/v1/', encodedMetadataAddress),
|
|
100
|
+
'https://169%252e254%252e169%252e254/latest/meta-data/',
|
|
101
|
+
'resolve does not turn nested dots into a metadata address'
|
|
102
|
+
)
|
|
103
|
+
t.equal(
|
|
104
|
+
fastURI.normalize('http://allowed.com%255Cevil.com/'),
|
|
105
|
+
'http://allowed.com%255Cevil.com/',
|
|
106
|
+
'normalize does not activate a nested backslash'
|
|
107
|
+
)
|
|
108
|
+
t.equal(
|
|
109
|
+
fastURI.serialize({ scheme: 'http', host: '%256cocalhost', path: '/' }),
|
|
110
|
+
'http://%256cocalhost/',
|
|
111
|
+
'component serialization preserves an encoded percent sign'
|
|
112
|
+
)
|
|
113
|
+
t.equal(
|
|
114
|
+
fastURI.equal(encodedLocalhost, 'http://localhost/', {}),
|
|
115
|
+
false,
|
|
116
|
+
'nested escapes do not compare equal to their twice-decoded target'
|
|
117
|
+
)
|
|
118
|
+
t.end()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('hostname normalization decodes only current unreserved escapes', (t) => {
|
|
122
|
+
t.equal(fastURI.normalize('x://%6cocalhost/'), 'x://localhost/', 'a current unreserved escape is decoded')
|
|
123
|
+
t.equal(fastURI.normalize('x://%256cocalhost/'), 'x://%256cocalhost/', 'an encoded percent is preserved')
|
|
124
|
+
t.equal(fastURI.normalize('x://host%2540evil/'), 'x://host%2540evil/', 'a nested authority delimiter stays inert')
|
|
125
|
+
t.equal(fastURI.normalize('x://%2525/'), 'x://%2525/', 'nested encoded percent signs stay encoded')
|
|
126
|
+
t.end()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test('host conversion failures are not treated as comparable URLs', (t) => {
|
|
130
|
+
const malformedHost = 'http://trusted.test%2540evil.test/'
|
|
131
|
+
|
|
132
|
+
t.equal(fastURI.normalize(malformedHost), malformedHost, 'normalization preserves the failing input')
|
|
133
|
+
t.equal(fastURI.equal(malformedHost, malformedHost, {}), false, 'equal rejects a failed host conversion')
|
|
134
|
+
t.throws(
|
|
135
|
+
() => fastURI.resolve(malformedHost, 'child', { domainHost: true }),
|
|
136
|
+
/Host's domain name can not be converted to ASCII/,
|
|
137
|
+
'resolve propagates a host conversion failure'
|
|
138
|
+
)
|
|
139
|
+
t.end()
|
|
140
|
+
})
|
|
@@ -125,11 +125,13 @@ test('serialize escapes authority delimiters in host field', (t) => {
|
|
|
125
125
|
})
|
|
126
126
|
|
|
127
127
|
test('normalize does not double-decode %2540 into a live @', (t) => {
|
|
128
|
-
const
|
|
128
|
+
const input = 'http://trusted.com%2540evil.com/'
|
|
129
|
+
const result = fastURI.normalize(input)
|
|
129
130
|
const parsed = fastURI.parse(result)
|
|
130
131
|
|
|
131
|
-
t.plan(
|
|
132
|
-
t.
|
|
132
|
+
t.plan(2)
|
|
133
|
+
t.equal(result, input, 'the encoded percent sign is preserved')
|
|
134
|
+
t.notEqual(parsed.host, 'trusted.com@evil.com', input)
|
|
133
135
|
})
|
|
134
136
|
|
|
135
137
|
test('parse canonicalises IDN / Unicode hosts to their ASCII form', (t) => {
|
|
@@ -160,6 +162,76 @@ test('parse canonicalises IDN / Unicode hosts to their ASCII form', (t) => {
|
|
|
160
162
|
})
|
|
161
163
|
})
|
|
162
164
|
|
|
165
|
+
test('resolve canonicalises the host using the final resolved scheme', (t) => {
|
|
166
|
+
const cases = [
|
|
167
|
+
{
|
|
168
|
+
base: 'http://trusted.example/base',
|
|
169
|
+
relative: '//127\u30020\u30020\u30021/private',
|
|
170
|
+
expected: 'http://127.0.0.1/private',
|
|
171
|
+
expectedHost: '127.0.0.1',
|
|
172
|
+
description: 'scheme-relative loopback host'
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
base: 'https://ex\u00ADample.com/base',
|
|
176
|
+
relative: 'child',
|
|
177
|
+
expected: 'https://example.com/child',
|
|
178
|
+
expectedHost: 'example.com',
|
|
179
|
+
description: 'host inherited from the base'
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
base: 'http://trusted.example/base',
|
|
183
|
+
relative: 'http://ex\u200Bample.com/',
|
|
184
|
+
expected: 'http://example.com/',
|
|
185
|
+
expectedHost: 'example.com',
|
|
186
|
+
description: 'absolute relative reference'
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
t.plan(cases.length * 2)
|
|
191
|
+
|
|
192
|
+
cases.forEach(({ base, relative, expected, expectedHost, description }) => {
|
|
193
|
+
const resolved = fastURI.resolve(base, relative)
|
|
194
|
+
t.equal(resolved, expected, description)
|
|
195
|
+
t.equal(fastURI.parse(resolved).host, expectedHost, `${description} reparses consistently`)
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test('resolve applies domain canonicalisation only when the effective scheme opts in', (t) => {
|
|
200
|
+
const host = 'ex\u00ADample.com'
|
|
201
|
+
|
|
202
|
+
t.plan(2)
|
|
203
|
+
t.equal(
|
|
204
|
+
fastURI.resolve('uri://trusted.example/', `//${host}/`),
|
|
205
|
+
`uri://${host}/`,
|
|
206
|
+
'an unsupported scheme preserves the host'
|
|
207
|
+
)
|
|
208
|
+
t.equal(
|
|
209
|
+
fastURI.resolve('http://trusted.example/', `//${host}/`, { unicodeSupport: true }),
|
|
210
|
+
`http://${host}/`,
|
|
211
|
+
'unicodeSupport preserves the Unicode host'
|
|
212
|
+
)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
test('resolve throws when the final scheme cannot canonicalise the host', (t) => {
|
|
216
|
+
const invalidHost = '\u200D.example'
|
|
217
|
+
const cases = [
|
|
218
|
+
['http://trusted.example/', `//${invalidHost}/`],
|
|
219
|
+
[`https://${invalidHost}/base`, 'child'],
|
|
220
|
+
['http://trusted.example/', `http://${invalidHost}/`],
|
|
221
|
+
['http://trusted.example/', `//${invalidHost}%2Etest/`]
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
t.plan(cases.length)
|
|
225
|
+
|
|
226
|
+
cases.forEach(([base, relative]) => {
|
|
227
|
+
t.throws(
|
|
228
|
+
() => fastURI.resolve(base, relative),
|
|
229
|
+
/Host's domain name can not be converted to ASCII/,
|
|
230
|
+
`${base} + ${relative}`
|
|
231
|
+
)
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
163
235
|
test('parse rejects a literal backslash in the authority as malformed (RFC 3986)', (t) => {
|
|
164
236
|
// Regression for the host-confusion bypass: a literal "\" is invalid RFC 3986
|
|
165
237
|
// syntax and must be flagged malformed, not silently rewritten. Otherwise "\"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('tape')
|
|
4
|
+
const fastURI = require('..')
|
|
5
|
+
|
|
6
|
+
test('URN parsing validates the complete scheme-specific input', (t) => {
|
|
7
|
+
const embedded = fastURI.parse('urn:x|foo:bar')
|
|
8
|
+
t.equal(embedded.error, 'URN can not be parsed.', 'does not search for a later nid:nss substring')
|
|
9
|
+
t.equal(embedded.nid, undefined, 'does not adopt the later nid')
|
|
10
|
+
t.equal(embedded.nss, undefined, 'does not adopt the later nss')
|
|
11
|
+
|
|
12
|
+
const trailing = fastURI.parse('urn:foo:bar|ignored')
|
|
13
|
+
t.equal(trailing.error, 'URN can not be parsed.', 'rejects trailing input outside the RFC 2141 NSS grammar')
|
|
14
|
+
t.equal(trailing.nid, undefined, 'does not return an nid from a partial match')
|
|
15
|
+
t.equal(trailing.nss, undefined, 'does not return a truncated nss')
|
|
16
|
+
|
|
17
|
+
t.end()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('URN parsing preserves the complete RFC 2141 NSS', (t) => {
|
|
21
|
+
const parsed = fastURI.parse('urn:foo:allowed/evil')
|
|
22
|
+
t.equal(parsed.error, undefined, 'accepts slash in an RFC 2141 NSS')
|
|
23
|
+
t.equal(parsed.nid, 'foo', 'parses the nid')
|
|
24
|
+
t.equal(parsed.nss, 'allowed/evil', 'preserves the complete NSS')
|
|
25
|
+
t.equal(fastURI.normalize('urn:foo:allowed/evil'), 'urn:foo:allowed/evil', 'normalization retains slash data')
|
|
26
|
+
t.equal(fastURI.equal('urn:foo:allowed/evil', 'urn:foo:allowed'), false, 'distinct NSS values do not compare equal')
|
|
27
|
+
|
|
28
|
+
t.end()
|
|
29
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('tape')
|
|
4
|
+
const fastURI = require('..')
|
|
5
|
+
|
|
6
|
+
test('WebSocket queries preserve additional question marks', (t) => {
|
|
7
|
+
for (const scheme of ['ws', 'wss']) {
|
|
8
|
+
const uri = `${scheme}://example.com/chat?a?b`
|
|
9
|
+
const truncatedURI = `${scheme}://example.com/chat?a`
|
|
10
|
+
const parsed = fastURI.parse(uri)
|
|
11
|
+
|
|
12
|
+
t.equal(parsed.resourceName, '/chat?a?b', `${scheme} parse preserves the resource name`)
|
|
13
|
+
t.equal(fastURI.serialize(parsed), uri, `${scheme} parsed components round-trip`)
|
|
14
|
+
t.equal(
|
|
15
|
+
fastURI.serialize({ scheme, host: 'example.com', resourceName: '/chat?a?b' }),
|
|
16
|
+
uri,
|
|
17
|
+
`${scheme} resource name serializes without truncation`
|
|
18
|
+
)
|
|
19
|
+
t.equal(fastURI.normalize(uri), uri, `${scheme} normalization preserves the full query`)
|
|
20
|
+
t.equal(fastURI.equal(uri, truncatedURI), false, `${scheme} equality distinguishes the full query`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
t.end()
|
|
24
|
+
})
|
|
@@ -40,6 +40,10 @@ const createProxy = (callback, path) => {
|
|
|
40
40
|
});
|
|
41
41
|
return proxy;
|
|
42
42
|
};
|
|
43
|
+
const appendQueryParams = (url, searchParams) => {
|
|
44
|
+
const queryString = searchParams.toString();
|
|
45
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
46
|
+
};
|
|
43
47
|
class ClientRequestImpl {
|
|
44
48
|
url;
|
|
45
49
|
method;
|
|
@@ -66,6 +70,9 @@ class ClientRequestImpl {
|
|
|
66
70
|
}
|
|
67
71
|
if (Array.isArray(v)) {
|
|
68
72
|
for (const v2 of v) {
|
|
73
|
+
if (v2 === void 0) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
69
76
|
form.append(k, v2);
|
|
70
77
|
}
|
|
71
78
|
} else {
|
|
@@ -74,7 +81,7 @@ class ClientRequestImpl {
|
|
|
74
81
|
}
|
|
75
82
|
this.rBody = form;
|
|
76
83
|
}
|
|
77
|
-
if (args.json) {
|
|
84
|
+
if (args.json !== void 0) {
|
|
78
85
|
this.rBody = JSON.stringify(args.json);
|
|
79
86
|
this.cType = "application/json";
|
|
80
87
|
}
|
|
@@ -90,19 +97,29 @@ class ClientRequestImpl {
|
|
|
90
97
|
if (args?.cookie) {
|
|
91
98
|
const cookies = [];
|
|
92
99
|
for (const [key, value] of Object.entries(args.cookie)) {
|
|
93
|
-
|
|
100
|
+
if (value === void 0) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
cookies.push((0, import_cookie.serialize)(key, value));
|
|
104
|
+
}
|
|
105
|
+
if (cookies.length > 0) {
|
|
106
|
+
headerValues["Cookie"] = cookies.join("; ");
|
|
94
107
|
}
|
|
95
|
-
headerValues["Cookie"] = cookies.join(",");
|
|
96
108
|
}
|
|
97
109
|
if (this.cType) {
|
|
98
110
|
headerValues["Content-Type"] = this.cType;
|
|
99
111
|
}
|
|
100
|
-
const headers = new Headers(
|
|
112
|
+
const headers = new Headers();
|
|
113
|
+
for (const [key, value] of Object.entries(headerValues)) {
|
|
114
|
+
if (value !== void 0) {
|
|
115
|
+
headers.set(key, value);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
101
118
|
let url = this.url;
|
|
102
119
|
url = (0, import_utils.removeIndexString)(url);
|
|
103
120
|
url = (0, import_utils.replaceUrlParam)(url, this.pathParams);
|
|
104
121
|
if (this.queryParams) {
|
|
105
|
-
url = url
|
|
122
|
+
url = appendQueryParams(url, this.queryParams);
|
|
106
123
|
}
|
|
107
124
|
methodUpperCase = this.method.toUpperCase();
|
|
108
125
|
const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
|
|
@@ -146,7 +163,7 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
146
163
|
result = (0, import_utils.replaceUrlParam)(url, opts.args[0].param);
|
|
147
164
|
}
|
|
148
165
|
if (opts.args[0].query) {
|
|
149
|
-
result = result
|
|
166
|
+
result = appendQueryParams(result, buildSearchParamsOption(opts.args[0].query));
|
|
150
167
|
}
|
|
151
168
|
}
|
|
152
169
|
result = (0, import_utils.removeIndexString)(result);
|
|
@@ -157,18 +174,15 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
157
174
|
}
|
|
158
175
|
if (method === "ws") {
|
|
159
176
|
const webSocketUrl = (0, import_utils.replaceUrlProtocol)(
|
|
160
|
-
opts.args[0]
|
|
177
|
+
opts.args[0]?.param ? (0, import_utils.replaceUrlParam)(url, opts.args[0].param) : url,
|
|
161
178
|
"ws"
|
|
162
179
|
);
|
|
163
180
|
const targetUrl = new URL(webSocketUrl);
|
|
164
181
|
const queryParams = opts.args[0]?.query;
|
|
165
182
|
if (queryParams) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
} else {
|
|
170
|
-
targetUrl.searchParams.set(key, value);
|
|
171
|
-
}
|
|
183
|
+
const searchParams = buildSearchParamsOption(queryParams);
|
|
184
|
+
searchParams.forEach((value, key) => {
|
|
185
|
+
targetUrl.searchParams.append(key, value);
|
|
172
186
|
});
|
|
173
187
|
}
|
|
174
188
|
const establishWebSocket = (...args) => {
|
|
@@ -37,7 +37,7 @@ const mergePath = (base, path) => {
|
|
|
37
37
|
const replaceUrlParam = (urlString, params) => {
|
|
38
38
|
for (const [k, v] of Object.entries(params)) {
|
|
39
39
|
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
40
|
-
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
40
|
+
urlString = urlString.replace(reg, () => v ? `/${v}` : "");
|
|
41
41
|
}
|
|
42
42
|
return urlString;
|
|
43
43
|
};
|
|
@@ -49,6 +49,9 @@ const buildSearchParams = (query) => {
|
|
|
49
49
|
}
|
|
50
50
|
if (Array.isArray(v)) {
|
|
51
51
|
for (const v2 of v) {
|
|
52
|
+
if (v2 === void 0) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
52
55
|
searchParams.append(k, v2);
|
|
53
56
|
}
|
|
54
57
|
} else {
|
|
@@ -224,6 +224,10 @@ class Context {
|
|
|
224
224
|
* c.header('X-Message', 'Hello!')
|
|
225
225
|
* c.header('Content-Type', 'text/plain')
|
|
226
226
|
*
|
|
227
|
+
* // Append multiple headers using the append option (e.g. Vary)
|
|
228
|
+
* c.header('Vary', 'Accept-Encoding', { append: true })
|
|
229
|
+
* c.header('Vary', 'User-Agent', { append: true })
|
|
230
|
+
*
|
|
227
231
|
* return c.body('Thank you for coming')
|
|
228
232
|
* })
|
|
229
233
|
* ```
|
|
@@ -22,10 +22,44 @@ __export(accepts_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(accepts_exports);
|
|
24
24
|
var import_accept = require("../../utils/accept");
|
|
25
|
+
const matchType = (acceptType, supportedType) => {
|
|
26
|
+
if (acceptType === supportedType) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (acceptType === "*/*" || acceptType === "*") {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (acceptType.endsWith("/*")) {
|
|
33
|
+
const [acceptMain] = acceptType.split("/");
|
|
34
|
+
const [supportedMain] = supportedType.split("/");
|
|
35
|
+
return acceptMain === supportedMain;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
const getSpecificity = (type) => {
|
|
40
|
+
if (type === "*/*" || type === "*") {
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
if (type.endsWith("/*")) {
|
|
44
|
+
return 2;
|
|
45
|
+
}
|
|
46
|
+
return 3;
|
|
47
|
+
};
|
|
25
48
|
const defaultMatch = (accepts2, config) => {
|
|
26
49
|
const { supports, default: defaultSupport } = config;
|
|
27
|
-
const
|
|
28
|
-
|
|
50
|
+
const sortedAccepts = accepts2.slice().sort((a, b) => {
|
|
51
|
+
if (b.q !== a.q) {
|
|
52
|
+
return b.q - a.q;
|
|
53
|
+
}
|
|
54
|
+
return getSpecificity(b.type) - getSpecificity(a.type);
|
|
55
|
+
});
|
|
56
|
+
for (const accept of sortedAccepts) {
|
|
57
|
+
const matched = supports.find((supported) => matchType(accept.type, supported));
|
|
58
|
+
if (matched) {
|
|
59
|
+
return matched;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return defaultSupport;
|
|
29
63
|
};
|
|
30
64
|
const accepts = (c, options) => {
|
|
31
65
|
const acceptHeader = c.req.header(options.header);
|
|
@@ -206,7 +206,7 @@ const saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
|
|
|
206
206
|
const { routePath, content, mimeType } = awaitedData;
|
|
207
207
|
const filePath = generateFilePath(routePath, outDir, mimeType, extensionMap);
|
|
208
208
|
const dirPath = (0, import_utils2.dirname)(filePath);
|
|
209
|
-
if (!createdDirs.has(dirPath)) {
|
|
209
|
+
if (dirPath !== "" && !createdDirs.has(dirPath)) {
|
|
210
210
|
await fsModule.mkdir(dirPath, { recursive: true });
|
|
211
211
|
createdDirs.add(dirPath);
|
|
212
212
|
}
|
|
@@ -33,8 +33,14 @@ const dirname = (path) => {
|
|
|
33
33
|
const normalizePath = (path) => {
|
|
34
34
|
return path.replace(/(\\)/g, "/").replace(/\/$/g, "");
|
|
35
35
|
};
|
|
36
|
-
const
|
|
37
|
-
|
|
36
|
+
const getUncRoot = (path) => {
|
|
37
|
+
const uncRoot = path.replace(/\\/g, "/").match(/^\/\/([^/]+)\/([^/]+)/);
|
|
38
|
+
if (uncRoot) {
|
|
39
|
+
return `${uncRoot[1].toLowerCase()}/${uncRoot[2].toLowerCase()}`;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const handleParent = (resultPaths) => {
|
|
43
|
+
if (resultPaths.length === 0 || resultPaths[resultPaths.length - 1] === "..") {
|
|
38
44
|
resultPaths.push("..");
|
|
39
45
|
} else {
|
|
40
46
|
resultPaths.pop();
|
|
@@ -47,22 +53,20 @@ const handleNonDot = (path, resultPaths) => {
|
|
|
47
53
|
}
|
|
48
54
|
};
|
|
49
55
|
const handleSegments = (paths, resultPaths) => {
|
|
50
|
-
let beforeParentFlag = false;
|
|
51
56
|
for (const path of paths) {
|
|
52
57
|
if (path === "..") {
|
|
53
|
-
handleParent(resultPaths
|
|
54
|
-
beforeParentFlag = true;
|
|
58
|
+
handleParent(resultPaths);
|
|
55
59
|
} else {
|
|
56
60
|
handleNonDot(path, resultPaths);
|
|
57
|
-
beforeParentFlag = false;
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
};
|
|
61
64
|
const joinPaths = (...paths) => {
|
|
65
|
+
const hasUncPrefix = getUncRoot(paths[0]) !== void 0;
|
|
62
66
|
paths = paths.map(normalizePath);
|
|
63
67
|
const resultPaths = [];
|
|
64
68
|
handleSegments(paths.join("/").split("/"), resultPaths);
|
|
65
|
-
return (paths[0][0] === "/" ? "/" : "") + resultPaths.join("/");
|
|
69
|
+
return (hasUncPrefix ? "//" : paths[0][0] === "/" ? "/" : "") + resultPaths.join("/");
|
|
66
70
|
};
|
|
67
71
|
const filterStaticGenerateRoutes = (hono) => {
|
|
68
72
|
return hono.routes.reduce((acc, { method, handler, path }) => {
|
|
@@ -76,10 +80,26 @@ const filterStaticGenerateRoutes = (hono) => {
|
|
|
76
80
|
const isDynamicRoute = (path) => {
|
|
77
81
|
return path.split("/").some((segment) => segment.startsWith(":") || segment.includes("*"));
|
|
78
82
|
};
|
|
83
|
+
const toSegments = (path) => path === "" ? [] : path.split("/");
|
|
84
|
+
const getPathRoot = (path) => {
|
|
85
|
+
const normalizedPath = path.replace(/\\/g, "/");
|
|
86
|
+
const uncRoot = getUncRoot(normalizedPath);
|
|
87
|
+
if (uncRoot) {
|
|
88
|
+
return `unc:${uncRoot}`;
|
|
89
|
+
}
|
|
90
|
+
const driveRoot = normalizedPath.match(/^([A-Za-z]):/);
|
|
91
|
+
if (driveRoot) {
|
|
92
|
+
const kind = normalizedPath[2] === "/" ? "drive-absolute" : "drive-relative";
|
|
93
|
+
return `${kind}:${driveRoot[1].toLowerCase()}`;
|
|
94
|
+
}
|
|
95
|
+
return normalizedPath.startsWith("/") ? "absolute" : "relative";
|
|
96
|
+
};
|
|
79
97
|
const ensureWithinOutDir = (outDir, filePath) => {
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
|
|
98
|
+
const outDirSegments = toSegments(joinPaths(outDir));
|
|
99
|
+
const filePathSegments = toSegments(joinPaths(filePath));
|
|
100
|
+
const hasMismatchedPathRoot = getPathRoot(outDir) !== getPathRoot(filePath);
|
|
101
|
+
const climbsAboveOutDir = filePathSegments[outDirSegments.length] === "..";
|
|
102
|
+
if (hasMismatchedPathRoot || filePathSegments.length <= outDirSegments.length || !outDirSegments.every((segment, i) => segment === filePathSegments[i]) || climbsAboveOutDir) {
|
|
83
103
|
throw new Error(`Path traversal detected: "${filePath}" is outside the output directory`);
|
|
84
104
|
}
|
|
85
105
|
};
|
|
@@ -101,6 +101,7 @@ const applyProps = (container, attributes, oldAttributes) => {
|
|
|
101
101
|
} else if (key === "dangerouslySetInnerHTML" && value) {
|
|
102
102
|
container.innerHTML = value.__html;
|
|
103
103
|
} else if (key === "ref") {
|
|
104
|
+
refCleanupMap.get(container)?.();
|
|
104
105
|
let cleanup;
|
|
105
106
|
if (typeof value === "function") {
|
|
106
107
|
cleanup = value(container) || (() => value(null));
|
|
@@ -165,6 +166,7 @@ const applyProps = (container, attributes, oldAttributes) => {
|
|
|
165
166
|
container.removeEventListener(eventSpec[0], value, eventSpec[1]);
|
|
166
167
|
} else if (key === "ref") {
|
|
167
168
|
refCleanupMap.get(container)?.();
|
|
169
|
+
refCleanupMap.delete(container);
|
|
168
170
|
} else {
|
|
169
171
|
try {
|
|
170
172
|
container.removeAttribute(toAttributeName(container, key));
|
|
@@ -101,7 +101,7 @@ const documentMetadataTag = (tag, children, props, sort) => {
|
|
|
101
101
|
const string = new import_base.JSXNode(tag, restProps, (0, import_children.toArray)(children || [])).toString();
|
|
102
102
|
if (string instanceof Promise) {
|
|
103
103
|
return string.then(
|
|
104
|
-
(resString) => (0, import_html.raw)(
|
|
104
|
+
(resString) => (0, import_html.raw)(resString, [
|
|
105
105
|
...resString.callbacks || [],
|
|
106
106
|
insertIntoHead(tag, resString, restProps, precedence)
|
|
107
107
|
])
|
|
@@ -44,7 +44,7 @@ const parseVaryDirectives = (vary) => {
|
|
|
44
44
|
};
|
|
45
45
|
const createCacheKey = (key, requestUrl, request, varyHeaders) => {
|
|
46
46
|
const url = new URL(cacheKeyPath, requestUrl);
|
|
47
|
-
url.searchParams.append(cacheKeyParameter, key
|
|
47
|
+
url.searchParams.append(cacheKeyParameter, key);
|
|
48
48
|
url.searchParams.append(cacheMethodKeyParameter, request.method);
|
|
49
49
|
if (request.method === "QUERY") {
|
|
50
50
|
url.searchParams.append(queryDigestKeyParameter, request.digest);
|
|
@@ -28,6 +28,8 @@ const cors = (options) => {
|
|
|
28
28
|
exposeHeaders: [],
|
|
29
29
|
...options
|
|
30
30
|
};
|
|
31
|
+
const exposeHeadersStr = opts.exposeHeaders?.length ? opts.exposeHeaders.join(",") : void 0;
|
|
32
|
+
const allowHeadersStr = opts.allowHeaders?.length ? opts.allowHeaders.join(",") : void 0;
|
|
31
33
|
const findAllowOrigin = ((optsOrigin) => {
|
|
32
34
|
if (typeof optsOrigin === "string") {
|
|
33
35
|
if (optsOrigin === "*") {
|
|
@@ -43,11 +45,12 @@ const cors = (options) => {
|
|
|
43
45
|
})(opts.origin);
|
|
44
46
|
const findAllowMethods = ((optsAllowMethods) => {
|
|
45
47
|
if (typeof optsAllowMethods === "function") {
|
|
46
|
-
return optsAllowMethods;
|
|
48
|
+
return async (origin, c) => (await optsAllowMethods(origin, c)).join(",");
|
|
47
49
|
} else if (Array.isArray(optsAllowMethods)) {
|
|
48
|
-
|
|
50
|
+
const methodsStr = optsAllowMethods.join(",");
|
|
51
|
+
return () => methodsStr;
|
|
49
52
|
} else {
|
|
50
|
-
return () =>
|
|
53
|
+
return () => "";
|
|
51
54
|
}
|
|
52
55
|
})(opts.allowMethods);
|
|
53
56
|
return async function cors2(c, next) {
|
|
@@ -61,29 +64,29 @@ const cors = (options) => {
|
|
|
61
64
|
if (opts.credentials) {
|
|
62
65
|
set("Access-Control-Allow-Credentials", "true");
|
|
63
66
|
}
|
|
64
|
-
if (
|
|
65
|
-
set("Access-Control-Expose-Headers",
|
|
67
|
+
if (exposeHeadersStr) {
|
|
68
|
+
set("Access-Control-Expose-Headers", exposeHeadersStr);
|
|
66
69
|
}
|
|
67
70
|
if (c.req.method === "OPTIONS") {
|
|
68
71
|
if (opts.origin !== "*") {
|
|
69
|
-
|
|
72
|
+
c.res.headers.append("Vary", "Origin");
|
|
70
73
|
}
|
|
71
74
|
if (opts.maxAge != null) {
|
|
72
75
|
set("Access-Control-Max-Age", opts.maxAge.toString());
|
|
73
76
|
}
|
|
74
77
|
const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
|
|
75
|
-
if (allowMethods
|
|
76
|
-
set("Access-Control-Allow-Methods", allowMethods
|
|
78
|
+
if (allowMethods) {
|
|
79
|
+
set("Access-Control-Allow-Methods", allowMethods);
|
|
77
80
|
}
|
|
78
|
-
let
|
|
79
|
-
if (!
|
|
81
|
+
let headersStr = allowHeadersStr;
|
|
82
|
+
if (!headersStr) {
|
|
80
83
|
const requestHeaders = c.req.header("Access-Control-Request-Headers");
|
|
81
84
|
if (requestHeaders) {
|
|
82
|
-
|
|
85
|
+
headersStr = requestHeaders.split(",").map((h) => h.trim()).join(",");
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
|
-
if (
|
|
86
|
-
set("Access-Control-Allow-Headers",
|
|
88
|
+
if (headersStr) {
|
|
89
|
+
set("Access-Control-Allow-Headers", headersStr);
|
|
87
90
|
c.res.headers.append("Vary", "Access-Control-Request-Headers");
|
|
88
91
|
}
|
|
89
92
|
c.res.headers.delete("Content-Length");
|
|
@@ -23,7 +23,7 @@ module.exports = __toCommonJS(csrf_exports);
|
|
|
23
23
|
var import_http_exception = require("../../http-exception");
|
|
24
24
|
const secFetchSiteValues = ["same-origin", "same-site", "none", "cross-site"];
|
|
25
25
|
const isSecFetchSite = (value) => secFetchSiteValues.includes(value);
|
|
26
|
-
const isSafeMethodRe = /^(GET|HEAD)$/;
|
|
26
|
+
const isSafeMethodRe = /^(GET|HEAD|OPTIONS)$/;
|
|
27
27
|
const isRequestedByFormElementRe = /^\b(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)\b/i;
|
|
28
28
|
const csrf = (options) => {
|
|
29
29
|
const originHandler = ((optsOrigin) => {
|