@openclaw/discord 2026.6.33 → 2026.6.35
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/action-runtime-api.js +1 -1
- package/dist/{api-CjnGBhM3.js → api-1GXlSrYP.js} +42 -21
- package/dist/api.js +14 -14
- package/dist/{approval-handler.runtime-BWPQrzpP.js → approval-handler.runtime-Dv4p7REU.js} +3 -3
- package/dist/{audit-BwJ_2OjL.js → audit-DEVi9nIs.js} +3 -3
- package/dist/{channel-Ddnonoy4.js → channel-CQIRiosn.js} +15 -15
- package/dist/{channel-actions-CwmIqnYN.js → channel-actions-JziPEcBU.js} +2 -2
- package/dist/{channel-actions.runtime-DvpTfaJ4.js → channel-actions.runtime-D7L47LY3.js} +5 -5
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-glZ5Y98a.js → channel.setup-oMeR19Cc.js} +2 -2
- package/dist/{components-j6lTZBsT.js → components-_s5UPJqU.js} +1 -1
- package/dist/{conversation-identity-36FFBwm5.js → conversation-identity-B0k94-bz.js} +2 -2
- package/dist/{directory-config-BYMFzL29.js → directory-config-CD1svkyN.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-9JtJCiu8.js → directory-live-DBTsSRxl.js} +5 -5
- package/dist/{handle-action.guild-admin-xxGYrp-I.js → handle-action.guild-admin-CYIFMxh-.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{manager.runtime-BK6cf2Zu.js → manager.runtime-BZVdGX2d.js} +17 -9
- package/dist/{message-handler-BqpJIavO.js → message-handler-DZd9Bpq8.js} +7 -6
- package/dist/{message-handler.preflight-C90MxCcv.js → message-handler.preflight-Axv9J9EO.js} +12 -11
- package/dist/{message-handler.process-CeQ7Bd_3.js → message-handler.process-CG0zFS-Z.js} +10 -10
- package/dist/{message-utils-CJeAoISH.js → message-utils-Dbuw27gd.js} +1 -1
- package/dist/{outbound-adapter-Dxs6iKEq.js → outbound-adapter-CKC_kmUN.js} +6 -6
- package/dist/pluralkit-CfTReLl3.js +40 -0
- package/dist/{probe-esE_Oqdm.js → probe-DcgZIpyF.js} +3 -2
- package/dist/{probe.runtime-C3Atgpvr.js → probe.runtime-CVwM9L5E.js} +1 -1
- package/dist/{provider-C7376XFH.js → provider-CwwSXIIj.js} +102 -37
- package/dist/{provider-session.runtime-CCdqogGf.js → provider-session.runtime-reBWkqHZ.js} +3 -3
- package/dist/provider.runtime-BsmTLYS_.js +2 -0
- package/dist/{resolve-allowlist-common-3gB2Gpmm.js → resolve-allowlist-common-D7bZqAw3.js} +3 -3
- package/dist/{resolve-channels-B3gQf8QL.js → resolve-channels--oE-RnO6.js} +6 -6
- package/dist/{resolve-users-BO10y5fJ.js → resolve-users-QXo8CXBU.js} +5 -5
- package/dist/{runtime-CFlR3L9X.js → runtime-CF7ramAs.js} +7 -7
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +19 -19
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-CzF8MUl_.js +6 -0
- package/dist/runtime-api.monitor.js +5 -5
- package/dist/runtime-api.send.js +5 -5
- package/dist/runtime-api.threads.js +3 -3
- package/dist/{send-JHxfT4Pk.js → send-Bb295iHT.js} +5 -5
- package/dist/{send.components-CN35E2Ck.js → send.components-COkDUO3B.js} +4 -4
- package/dist/{send.outbound-B-cA1Esv.js → send.outbound-B_sk0hNe.js} +3 -3
- package/dist/{send.receipt-CGecJDin.js → send.receipt-Cli6_9Sn.js} +19 -7
- package/dist/{send.shared-vcbfThdy.js → send.shared-BCG7MWnP.js} +2 -2
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{subagent-hooks-20wXhVzZ.js → subagent-hooks-CtqoWK4x.js} +2 -2
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{system-events-DR27TE7p.js → system-events-BxGNk_wE.js} +1 -1
- package/dist/{target-resolver-CDi1gI90.js → target-resolver-BcoK6b0g.js} +2 -2
- package/dist/targets-Q-ZoP7K4.js +3 -0
- package/dist/{thread-bindings-DU4T6nDo.js → thread-bindings-DJ_HT6GJ.js} +4 -4
- package/dist/{thread-bindings.discord-api-CYkr-3Gj.js → thread-bindings.discord-api-OPyjvgyz.js} +4 -4
- package/dist/{thread-bindings.manager-BqWs1UE2.js → thread-bindings.manager-Cd2HAVw_.js} +3 -3
- package/dist/{transcripts-source-D-lBI5ZD.js → transcripts-source-CPf5gURy.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-xr05bL-r.js → typing-DY0cwLdg.js} +1 -1
- package/node_modules/undici/README.md +8 -2
- package/node_modules/undici/docs/docs/api/Agent.md +248 -44
- package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
- package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
- package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
- package/node_modules/undici/docs/docs/api/Client.md +386 -179
- package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
- package/node_modules/undici/docs/docs/api/Connector.md +118 -36
- package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
- package/node_modules/undici/docs/docs/api/Cookies.md +122 -71
- package/node_modules/undici/docs/docs/api/Debug.md +34 -18
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
- package/node_modules/undici/docs/docs/api/Dispatcher.md +485 -1102
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +102 -87
- package/node_modules/undici/docs/docs/api/Errors.md +503 -40
- package/node_modules/undici/docs/docs/api/EventSource.md +298 -32
- package/node_modules/undici/docs/docs/api/Fetch.md +680 -31
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -98
- package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
- package/node_modules/undici/docs/docs/api/Interceptors.md +418 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +333 -314
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
- package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
- package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
- package/node_modules/undici/docs/docs/api/MockPool.md +321 -258
- package/node_modules/undici/docs/docs/api/Pool.md +235 -43
- package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -63
- package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -26
- package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -77
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +264 -542
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +177 -196
- package/node_modules/undici/docs/docs/api/Util.md +68 -11
- package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +6 -4
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
- package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
- package/node_modules/undici/docs/docs/{GettingStarted.md → getting-started.md} +22 -19
- package/node_modules/undici/docs/docs/index.md +784 -0
- package/node_modules/undici/docs/docs/site.json +125 -0
- package/node_modules/undici/docs/docs/type-map.json +79 -0
- package/node_modules/undici/lib/api/api-request.js +7 -1
- package/node_modules/undici/lib/api/readable.js +42 -7
- package/node_modules/undici/lib/cache/memory-cache-store.js +56 -11
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
- package/node_modules/undici/lib/core/connect.js +16 -2
- package/node_modules/undici/lib/core/errors.js +20 -0
- package/node_modules/undici/lib/core/request.js +14 -3
- package/node_modules/undici/lib/core/symbols.js +3 -0
- package/node_modules/undici/lib/core/util.js +30 -2
- package/node_modules/undici/lib/dispatcher/agent.js +10 -5
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +7 -4
- package/node_modules/undici/lib/dispatcher/client-h1.js +74 -9
- package/node_modules/undici/lib/dispatcher/client-h2.js +483 -151
- package/node_modules/undici/lib/dispatcher/client.js +76 -30
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +13 -1
- package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -1
- package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +3 -0
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +37 -8
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +58 -7
- package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +1 -1
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +106 -22
- package/node_modules/undici/lib/global.js +36 -16
- package/node_modules/undici/lib/handler/cache-handler.js +297 -65
- package/node_modules/undici/lib/handler/cache-revalidation-handler.js +13 -3
- package/node_modules/undici/lib/handler/decorator-handler.js +7 -1
- package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
- package/node_modules/undici/lib/handler/redirect-handler.js +26 -5
- package/node_modules/undici/lib/handler/retry-handler.js +238 -51
- package/node_modules/undici/lib/interceptor/cache.js +221 -58
- package/node_modules/undici/lib/interceptor/decompress.js +124 -15
- package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
- package/node_modules/undici/lib/interceptor/dns.js +7 -0
- package/node_modules/undici/lib/interceptor/dump.js +10 -23
- package/node_modules/undici/lib/mock/mock-agent.js +13 -1
- package/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
- package/node_modules/undici/lib/mock/mock-utils.js +246 -27
- package/node_modules/undici/lib/util/cache.js +415 -71
- package/node_modules/undici/lib/util/date.js +23 -6
- package/node_modules/undici/lib/web/cookies/parse.js +150 -146
- package/node_modules/undici/lib/web/cookies/util.js +79 -9
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +13 -3
- package/node_modules/undici/lib/web/eventsource/util.js +1 -1
- package/node_modules/undici/lib/web/fetch/body.js +2 -1
- package/node_modules/undici/lib/web/fetch/constants.js +1 -1
- package/node_modules/undici/lib/web/fetch/index.js +17 -2
- package/node_modules/undici/lib/web/fetch/request.js +2 -3
- package/node_modules/undici/lib/web/fetch/response.js +1 -3
- package/node_modules/undici/lib/web/fetch/util.js +10 -2
- package/node_modules/undici/lib/web/webidl/index.js +3 -3
- package/node_modules/undici/lib/web/websocket/connection.js +1 -1
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
- package/node_modules/undici/lib/web/websocket/websocket.js +22 -0
- package/node_modules/undici/package.json +4 -4
- package/node_modules/undici/types/client.d.ts +53 -3
- package/node_modules/undici/types/cookies.d.ts +1 -1
- package/node_modules/undici/types/dispatcher.d.ts +3 -3
- package/node_modules/undici/types/errors.d.ts +10 -0
- package/node_modules/undici/types/handlers.d.ts +2 -0
- package/node_modules/undici/types/interceptors.d.ts +2 -0
- package/node_modules/undici/types/mock-agent.d.ts +11 -10
- package/node_modules/undici/types/mock-interceptor.d.ts +5 -1
- package/node_modules/undici/types/proxy-agent.d.ts +7 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -0
- package/npm-shrinkwrap.json +7 -7
- package/package.json +6 -5
- package/dist/pluralkit-DI6RYaVj.js +0 -24
- package/dist/provider.runtime-D1m66kDS.js +0 -2
- package/dist/runtime-api.monitor-4oc58TSk.js +0 -6
- package/dist/targets-C6yd3y8R.js +0 -3
|
@@ -18,6 +18,26 @@ function parseHttpDate (date) {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
function makeDate (year, monthIdx, day, hour, minute, second, weekday) {
|
|
22
|
+
const result = new Date(Date.UTC(year, monthIdx, day, hour, minute, second))
|
|
23
|
+
|
|
24
|
+
// Date.UTC treats years 0-99 as 1900-1999. Reset the full year so component
|
|
25
|
+
// checks below validate the HTTP date as written.
|
|
26
|
+
if (year >= 0 && year <= 99) {
|
|
27
|
+
result.setUTCFullYear(year)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return result.getUTCFullYear() === year &&
|
|
31
|
+
result.getUTCMonth() === monthIdx &&
|
|
32
|
+
result.getUTCDate() === day &&
|
|
33
|
+
result.getUTCHours() === hour &&
|
|
34
|
+
result.getUTCMinutes() === minute &&
|
|
35
|
+
result.getUTCSeconds() === second &&
|
|
36
|
+
result.getUTCDay() === weekday
|
|
37
|
+
? result
|
|
38
|
+
: undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
21
41
|
/**
|
|
22
42
|
* @see https://httpwg.org/specs/rfc9110.html#preferred.date.format
|
|
23
43
|
*
|
|
@@ -224,8 +244,7 @@ function parseImfDate (date) {
|
|
|
224
244
|
second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number
|
|
225
245
|
}
|
|
226
246
|
|
|
227
|
-
|
|
228
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
247
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
229
248
|
}
|
|
230
249
|
|
|
231
250
|
/**
|
|
@@ -429,8 +448,7 @@ function parseAscTimeDate (date) {
|
|
|
429
448
|
}
|
|
430
449
|
const year = (yearDigit1 - 48) * 1000 + (yearDigit2 - 48) * 100 + (yearDigit3 - 48) * 10 + (yearDigit4 - 48)
|
|
431
450
|
|
|
432
|
-
|
|
433
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
451
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
434
452
|
}
|
|
435
453
|
|
|
436
454
|
/**
|
|
@@ -644,8 +662,7 @@ function parseRfc850Date (date) {
|
|
|
644
662
|
second = (code1 - 48) * 10 + (code2 - 48) // Convert ASCII codes to number
|
|
645
663
|
}
|
|
646
664
|
|
|
647
|
-
|
|
648
|
-
return result.getUTCDay() === weekday ? result : undefined
|
|
665
|
+
return makeDate(year, monthIdx, day, hour, minute, second, weekday)
|
|
649
666
|
}
|
|
650
667
|
|
|
651
668
|
module.exports = {
|
|
@@ -92,220 +92,224 @@ function parseSetCookie (header) {
|
|
|
92
92
|
* @param {Object.<string, unknown>} [cookieAttributeList={}]
|
|
93
93
|
*/
|
|
94
94
|
function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
while (true) {
|
|
96
|
+
// 1. If the unparsed-attributes string is empty, skip the rest of
|
|
97
|
+
// these steps.
|
|
98
|
+
if (unparsedAttributes.length === 0) {
|
|
99
|
+
return cookieAttributeList
|
|
100
|
+
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
// 2. Discard the first character of the unparsed-attributes (which
|
|
103
|
+
// will be a %x3B (";") character).
|
|
104
|
+
assert(unparsedAttributes[0] === ';')
|
|
105
|
+
unparsedAttributes = unparsedAttributes.slice(1)
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
let cookieAv = ''
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
// 3. If the remaining unparsed-attributes contains a %x3B (";")
|
|
110
|
+
// character:
|
|
111
|
+
if (unparsedAttributes.includes(';')) {
|
|
111
112
|
// 1. Consume the characters of the unparsed-attributes up to, but
|
|
112
113
|
// not including, the first %x3B (";") character.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
114
|
+
cookieAv = collectASequenceOfCodePointsFast(
|
|
115
|
+
';',
|
|
116
|
+
unparsedAttributes,
|
|
117
|
+
{ position: 0 }
|
|
118
|
+
)
|
|
119
|
+
unparsedAttributes = unparsedAttributes.slice(cookieAv.length)
|
|
120
|
+
} else {
|
|
120
121
|
// Otherwise:
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
// 1. Consume the remainder of the unparsed-attributes.
|
|
124
|
+
cookieAv = unparsedAttributes
|
|
125
|
+
unparsedAttributes = ''
|
|
126
|
+
}
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
// Let the cookie-av string be the characters consumed in this step.
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
let attributeName = ''
|
|
131
|
+
let attributeValue = ''
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
// 4. If the cookie-av string contains a %x3D ("=") character:
|
|
134
|
+
if (cookieAv.includes('=')) {
|
|
134
135
|
// 1. The (possibly empty) attribute-name string consists of the
|
|
135
136
|
// characters up to, but not including, the first %x3D ("=")
|
|
136
137
|
// character, and the (possibly empty) attribute-value string
|
|
137
138
|
// consists of the characters after the first %x3D ("=")
|
|
138
139
|
// character.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
const position = { position: 0 }
|
|
141
|
+
|
|
142
|
+
attributeName = collectASequenceOfCodePointsFast(
|
|
143
|
+
'=',
|
|
144
|
+
cookieAv,
|
|
145
|
+
position
|
|
146
|
+
)
|
|
147
|
+
attributeValue = cookieAv.slice(position.position + 1)
|
|
148
|
+
} else {
|
|
148
149
|
// Otherwise:
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
// 1. The attribute-name string consists of the entire cookie-av
|
|
152
|
+
// string, and the attribute-value string is empty.
|
|
153
|
+
attributeName = cookieAv
|
|
154
|
+
}
|
|
154
155
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
// 5. Remove any leading or trailing WSP characters from the attribute-
|
|
157
|
+
// name string and the attribute-value string.
|
|
158
|
+
attributeName = attributeName.trim()
|
|
159
|
+
attributeValue = attributeValue.trim()
|
|
159
160
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
// 6. If the attribute-value is longer than 1024 octets, ignore the
|
|
162
|
+
// cookie-av string and return to Step 1 of this algorithm.
|
|
163
|
+
if (attributeValue.length > maxAttributeValueSize) {
|
|
164
|
+
continue
|
|
165
|
+
}
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
// 7. Process the attribute-name and attribute-value according to the
|
|
168
|
+
// requirements in the following subsections. (Notice that
|
|
169
|
+
// attributes with unrecognized attribute-names are ignored.)
|
|
170
|
+
const attributeNameLowercase = attributeName.toLowerCase()
|
|
170
171
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1
|
|
173
|
+
// If the attribute-name case-insensitively matches the string
|
|
174
|
+
// "Expires", the user agent MUST process the cookie-av as follows.
|
|
175
|
+
if (attributeNameLowercase === 'expires') {
|
|
175
176
|
// 1. Let the expiry-time be the result of parsing the attribute-value
|
|
176
177
|
// as cookie-date (see Section 5.1.1).
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
const expiryTime = new Date(attributeValue)
|
|
179
|
+
|
|
180
|
+
// 2. If the attribute-value failed to parse as a cookie date, ignore
|
|
181
|
+
// the cookie-av.
|
|
182
|
+
if (!Number.isNaN(expiryTime.getTime())) {
|
|
183
|
+
cookieAttributeList.expires = expiryTime
|
|
184
|
+
}
|
|
185
|
+
} else if (attributeNameLowercase === 'max-age') {
|
|
184
186
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2
|
|
185
187
|
// If the attribute-name case-insensitively matches the string "Max-
|
|
186
188
|
// Age", the user agent MUST process the cookie-av as follows.
|
|
187
189
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
190
|
+
// 1. If the first character of the attribute-value is not a DIGIT or a
|
|
191
|
+
// "-" character, ignore the cookie-av.
|
|
192
|
+
const charCode = attributeValue.charCodeAt(0)
|
|
193
|
+
const startsWithDigit = charCode >= 48 && charCode <= 57
|
|
194
|
+
const startsWithSignedDigit = attributeValue[0] === '-' && attributeValue.length > 1
|
|
195
|
+
|
|
196
|
+
if (!startsWithDigit && !startsWithSignedDigit) {
|
|
197
|
+
continue
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 2. If the remainder of attribute-value contains a non-DIGIT
|
|
201
|
+
// character, ignore the cookie-av.
|
|
202
|
+
if (/[^\d]/.test(attributeValue.slice(1))) {
|
|
203
|
+
continue
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// 3. Let delta-seconds be the attribute-value converted to an integer.
|
|
207
|
+
const deltaSeconds = Number(attributeValue)
|
|
208
|
+
|
|
209
|
+
// 4. Let cookie-age-limit be the maximum age of the cookie (which
|
|
210
|
+
// SHOULD be 400 days or less, see Section 4.1.2.2).
|
|
211
|
+
|
|
212
|
+
// 5. Set delta-seconds to the smaller of its present value and cookie-
|
|
213
|
+
// age-limit.
|
|
214
|
+
// deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs)
|
|
215
|
+
|
|
216
|
+
// 6. If delta-seconds is less than or equal to zero (0), let expiry-
|
|
217
|
+
// time be the earliest representable date and time. Otherwise, let
|
|
218
|
+
// the expiry-time be the current date and time plus delta-seconds
|
|
219
|
+
// seconds.
|
|
220
|
+
// const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds
|
|
221
|
+
|
|
222
|
+
// 7. Append an attribute to the cookie-attribute-list with an
|
|
223
|
+
// attribute-name of Max-Age and an attribute-value of expiry-time.
|
|
224
|
+
cookieAttributeList.maxAge = deltaSeconds
|
|
225
|
+
} else if (attributeNameLowercase === 'domain') {
|
|
222
226
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3
|
|
223
227
|
// If the attribute-name case-insensitively matches the string "Domain",
|
|
224
228
|
// the user agent MUST process the cookie-av as follows.
|
|
225
229
|
|
|
226
|
-
|
|
227
|
-
|
|
230
|
+
// 1. Let cookie-domain be the attribute-value.
|
|
231
|
+
let cookieDomain = attributeValue
|
|
228
232
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
233
|
+
// 2. If cookie-domain starts with %x2E ("."), let cookie-domain be
|
|
234
|
+
// cookie-domain without its leading %x2E (".").
|
|
235
|
+
if (cookieDomain[0] === '.') {
|
|
236
|
+
cookieDomain = cookieDomain.slice(1)
|
|
237
|
+
}
|
|
234
238
|
|
|
235
|
-
|
|
236
|
-
|
|
239
|
+
// 3. Convert the cookie-domain to lower case.
|
|
240
|
+
cookieDomain = cookieDomain.toLowerCase()
|
|
237
241
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
+
// 4. Append an attribute to the cookie-attribute-list with an
|
|
243
|
+
// attribute-name of Domain and an attribute-value of cookie-domain.
|
|
244
|
+
cookieAttributeList.domain = cookieDomain
|
|
245
|
+
} else if (attributeNameLowercase === 'path') {
|
|
242
246
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4
|
|
243
247
|
// If the attribute-name case-insensitively matches the string "Path",
|
|
244
248
|
// the user agent MUST process the cookie-av as follows.
|
|
245
249
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
+
// 1. If the attribute-value is empty or if the first character of the
|
|
251
|
+
// attribute-value is not %x2F ("/"):
|
|
252
|
+
let cookiePath = ''
|
|
253
|
+
if (attributeValue.length === 0 || attributeValue[0] !== '/') {
|
|
250
254
|
// 1. Let cookie-path be the default-path.
|
|
251
|
-
|
|
252
|
-
|
|
255
|
+
cookiePath = '/'
|
|
256
|
+
} else {
|
|
253
257
|
// Otherwise:
|
|
254
258
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
259
|
+
// 1. Let cookie-path be the attribute-value.
|
|
260
|
+
cookiePath = attributeValue
|
|
261
|
+
}
|
|
258
262
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
// 2. Append an attribute to the cookie-attribute-list with an
|
|
264
|
+
// attribute-name of Path and an attribute-value of cookie-path.
|
|
265
|
+
cookieAttributeList.path = cookiePath
|
|
266
|
+
} else if (attributeNameLowercase === 'secure') {
|
|
263
267
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5
|
|
264
268
|
// If the attribute-name case-insensitively matches the string "Secure",
|
|
265
269
|
// the user agent MUST append an attribute to the cookie-attribute-list
|
|
266
270
|
// with an attribute-name of Secure and an empty attribute-value.
|
|
267
271
|
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
cookieAttributeList.secure = true
|
|
273
|
+
} else if (attributeNameLowercase === 'httponly') {
|
|
270
274
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6
|
|
271
275
|
// If the attribute-name case-insensitively matches the string
|
|
272
276
|
// "HttpOnly", the user agent MUST append an attribute to the cookie-
|
|
273
277
|
// attribute-list with an attribute-name of HttpOnly and an empty
|
|
274
278
|
// attribute-value.
|
|
275
279
|
|
|
276
|
-
|
|
277
|
-
|
|
280
|
+
cookieAttributeList.httpOnly = true
|
|
281
|
+
} else if (attributeNameLowercase === 'samesite') {
|
|
278
282
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7
|
|
279
283
|
// If the attribute-name case-insensitively matches the string
|
|
280
284
|
// "SameSite", the user agent MUST process the cookie-av as follows:
|
|
281
285
|
|
|
282
|
-
|
|
286
|
+
const attributeValueLowercase = attributeValue.toLowerCase()
|
|
283
287
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
// 1. If cookie-av's attribute-value is a case-insensitive match for
|
|
289
|
+
// "None", append an attribute to the cookie-attribute-list with an
|
|
290
|
+
// attribute-name of "SameSite" and an attribute-value of "None".
|
|
291
|
+
if (attributeValueLowercase === 'none') {
|
|
292
|
+
cookieAttributeList.sameSite = 'None'
|
|
293
|
+
} else if (attributeValueLowercase === 'strict') {
|
|
290
294
|
// 2. If cookie-av's attribute-value is a case-insensitive match for
|
|
291
295
|
// "Strict", append an attribute to the cookie-attribute-list with
|
|
292
296
|
// an attribute-name of "SameSite" and an attribute-value of
|
|
293
297
|
// "Strict".
|
|
294
|
-
|
|
295
|
-
|
|
298
|
+
cookieAttributeList.sameSite = 'Strict'
|
|
299
|
+
} else if (attributeValueLowercase === 'lax') {
|
|
296
300
|
// 3. If cookie-av's attribute-value is a case-insensitive match for
|
|
297
301
|
// "Lax", append an attribute to the cookie-attribute-list with an
|
|
298
302
|
// attribute-name of "SameSite" and an attribute-value of "Lax".
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
+
cookieAttributeList.sameSite = 'Lax'
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
cookieAttributeList.unparsed ??= []
|
|
303
307
|
|
|
304
|
-
|
|
305
|
-
|
|
308
|
+
cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`)
|
|
309
|
+
}
|
|
306
310
|
|
|
307
311
|
// 8. Return to Step 1 of this algorithm.
|
|
308
|
-
|
|
312
|
+
}
|
|
309
313
|
}
|
|
310
314
|
|
|
311
315
|
module.exports = {
|
|
@@ -105,7 +105,7 @@ function validateCookiePath (path) {
|
|
|
105
105
|
|
|
106
106
|
if (
|
|
107
107
|
code < 0x20 || // exclude CTLs (0-31)
|
|
108
|
-
code
|
|
108
|
+
code > 0x7E || // exclude non-ascii and DEL
|
|
109
109
|
code === 0x3B // ;
|
|
110
110
|
) {
|
|
111
111
|
throw new Error('Invalid cookie path')
|
|
@@ -114,16 +114,80 @@ function validateCookiePath (path) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
117
|
+
* <let-dig> ::= <letter> | <digit>
|
|
118
|
+
*
|
|
119
|
+
* <letter> ::= any one of the 52 alphabetic characters A through Z in
|
|
120
|
+
* upper case and a through z in lower case
|
|
121
|
+
*
|
|
122
|
+
* <digit> ::= any one of the ten digits 0 through 9r
|
|
123
|
+
*
|
|
124
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
125
|
+
* @param {number} code
|
|
126
|
+
*/
|
|
127
|
+
function isLetterOrDigit (code) {
|
|
128
|
+
return (
|
|
129
|
+
(code >= 0x30 && code <= 0x39) || // 0-9
|
|
130
|
+
(code >= 0x41 && code <= 0x5A) || // A-Z
|
|
131
|
+
(code >= 0x61 && code <= 0x7A) // a-z
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Validates a cookie domain against the "preferred name syntax".
|
|
137
|
+
*
|
|
138
|
+
* <domain> ::= <subdomain> | " "
|
|
139
|
+
* <subdomain> ::= <label> | <subdomain> "." <label>
|
|
140
|
+
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
|
|
141
|
+
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
|
|
142
|
+
* <let-dig-hyp> ::= <let-dig> | "-"
|
|
143
|
+
*
|
|
144
|
+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
|
|
145
|
+
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
|
|
146
|
+
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
|
|
119
147
|
* @param {string} domain
|
|
120
148
|
*/
|
|
121
149
|
function validateCookieDomain (domain) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
150
|
+
// <domain> ::= <subdomain> | " "
|
|
151
|
+
if (domain === ' ') {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (domain.length > 255) {
|
|
156
|
+
throw new Error('Invalid cookie domain')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let labelLength = 0
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < domain.length; ++i) {
|
|
162
|
+
const code = domain.charCodeAt(i)
|
|
163
|
+
|
|
164
|
+
if (code === 0x2E) {
|
|
165
|
+
if (labelLength === 0) {
|
|
166
|
+
throw new Error('Invalid cookie domain')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
|
|
170
|
+
throw new Error('Invalid cookie domain')
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
labelLength = 0
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (labelLength === 0 && !isLetterOrDigit(code)) {
|
|
178
|
+
throw new Error('Invalid cookie domain')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
|
|
182
|
+
throw new Error('Invalid cookie domain')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (++labelLength > 63) {
|
|
186
|
+
throw new Error('Invalid cookie domain')
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
|
|
127
191
|
throw new Error('Invalid cookie domain')
|
|
128
192
|
}
|
|
129
193
|
}
|
|
@@ -266,7 +330,13 @@ function stringify (cookie) {
|
|
|
266
330
|
|
|
267
331
|
const [key, ...value] = part.split('=')
|
|
268
332
|
|
|
269
|
-
|
|
333
|
+
const trimmedKey = key.trim()
|
|
334
|
+
const joinedValue = value.join('=')
|
|
335
|
+
|
|
336
|
+
validateCookieName(trimmedKey)
|
|
337
|
+
validateCookieValue(joinedValue)
|
|
338
|
+
|
|
339
|
+
out.push(`${trimmedKey}=${joinedValue}`)
|
|
270
340
|
}
|
|
271
341
|
|
|
272
342
|
return out.join('; ')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const buffer = require('node:buffer')
|
|
2
3
|
const { Transform } = require('node:stream')
|
|
3
4
|
const { isASCIINumber, isValidLastEventId } = require('./util')
|
|
4
5
|
|
|
@@ -23,6 +24,8 @@ const COLON = 0x3A
|
|
|
23
24
|
*/
|
|
24
25
|
const SPACE = 0x20
|
|
25
26
|
|
|
27
|
+
const defaultMaxEventSize = buffer.kStringMaxLength
|
|
28
|
+
|
|
26
29
|
const DATA = Buffer.from('data')
|
|
27
30
|
const EVENT = Buffer.from('event')
|
|
28
31
|
const ID = Buffer.from('id')
|
|
@@ -66,6 +69,12 @@ function isFieldName (line, length, field) {
|
|
|
66
69
|
return true
|
|
67
70
|
}
|
|
68
71
|
|
|
72
|
+
function createMaxEventSizeExceededError () {
|
|
73
|
+
const error = new Error('EventSource message size exceeded')
|
|
74
|
+
error.aborted = false
|
|
75
|
+
return error
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
/**
|
|
70
79
|
* @typedef {object} EventSourceStreamEvent
|
|
71
80
|
* @type {object}
|
|
@@ -114,6 +123,8 @@ class EventSourceStream extends Transform {
|
|
|
114
123
|
pos = 0
|
|
115
124
|
lineChunkIndex = 0
|
|
116
125
|
linePos = 0
|
|
126
|
+
eventDataSize = 0
|
|
127
|
+
maxEventSize
|
|
117
128
|
|
|
118
129
|
event = {
|
|
119
130
|
data: undefined,
|
|
@@ -125,6 +136,7 @@ class EventSourceStream extends Transform {
|
|
|
125
136
|
/**
|
|
126
137
|
* @param {object} options
|
|
127
138
|
* @param {boolean} [options.readableObjectMode]
|
|
139
|
+
* @param {number} [options.maxEventSize]
|
|
128
140
|
* @param {eventSourceSettings} [options.eventSourceSettings]
|
|
129
141
|
* @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push]
|
|
130
142
|
*/
|
|
@@ -136,6 +148,7 @@ class EventSourceStream extends Transform {
|
|
|
136
148
|
super(options)
|
|
137
149
|
|
|
138
150
|
this.state = options.eventSourceSettings || {}
|
|
151
|
+
this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
|
|
139
152
|
if (options.push) {
|
|
140
153
|
this.push = options.push
|
|
141
154
|
}
|
|
@@ -231,7 +244,12 @@ class EventSourceStream extends Transform {
|
|
|
231
244
|
|
|
232
245
|
// In any case, we can process the line as we reached an
|
|
233
246
|
// end-of-line character
|
|
234
|
-
|
|
247
|
+
try {
|
|
248
|
+
this.parseLine(this.readLine(), this.event)
|
|
249
|
+
} catch (error) {
|
|
250
|
+
callback(error)
|
|
251
|
+
return
|
|
252
|
+
}
|
|
235
253
|
this.consumeCurrentByte()
|
|
236
254
|
// A line was processed and this could be the end of the event. We need
|
|
237
255
|
// to check if the next line is empty to determine if the event is
|
|
@@ -282,6 +300,13 @@ class EventSourceStream extends Transform {
|
|
|
282
300
|
}
|
|
283
301
|
|
|
284
302
|
if (isFieldName(line, fieldLength, DATA)) {
|
|
303
|
+
const valueBytes = line.length - valueStart
|
|
304
|
+
const eventDataSize = this.eventDataSize + (event.data === undefined ? 0 : 1) + valueBytes
|
|
305
|
+
|
|
306
|
+
if (this.maxEventSize > 0 && eventDataSize > this.maxEventSize) {
|
|
307
|
+
throw createMaxEventSizeExceededError()
|
|
308
|
+
}
|
|
309
|
+
|
|
285
310
|
const value = line.toString('utf8', valueStart)
|
|
286
311
|
|
|
287
312
|
if (event.data === undefined) {
|
|
@@ -289,6 +314,7 @@ class EventSourceStream extends Transform {
|
|
|
289
314
|
} else {
|
|
290
315
|
event.data += `\n${value}`
|
|
291
316
|
}
|
|
317
|
+
this.eventDataSize = eventDataSize
|
|
292
318
|
return
|
|
293
319
|
}
|
|
294
320
|
|
|
@@ -345,6 +371,7 @@ class EventSourceStream extends Transform {
|
|
|
345
371
|
this.event.event = undefined
|
|
346
372
|
this.event.id = undefined
|
|
347
373
|
this.event.retry = undefined
|
|
374
|
+
this.eventDataSize = 0
|
|
348
375
|
}
|
|
349
376
|
|
|
350
377
|
hasPendingEvent () {
|