@blamejs/blamejs-shop 0.4.100 → 0.4.102
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/CHANGELOG.md +4 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/cart-bulk-ops.js +7 -1
- package/lib/vendor/MANIFEST.json +55 -51
- package/lib/vendor/blamejs/.gitignore +5 -0
- package/lib/vendor/blamejs/CHANGELOG.md +4 -0
- package/lib/vendor/blamejs/api-snapshot.json +2 -2
- package/lib/vendor/blamejs/lib/sandbox.js +23 -5
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.15.25.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.15.26.json +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-adverse-decision.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-open-nofollow.test.js +7 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-bucket-ops.test.js +30 -10
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bearer-auth.test.js +22 -17
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-chunked-malformed.test.js +23 -18
- package/lib/vendor/blamejs/test/layer-0-primitives/breach-deadline.test.js +8 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +13 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/cra-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/daily-byte-quota.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +8 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +34 -15
- package/lib/vendor/blamejs/test/layer-0-primitives/gcs-bucket-ops.test.js +30 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +15 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +41 -18
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +33 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-throttle-transform.test.js +21 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/incident-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp.test.js +29 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +42 -23
- package/lib/vendor/blamejs/test/layer-0-primitives/network-byte-quota.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +20 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts-handshake-byte-cap.test.js +20 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/nis2-report.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +22 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +8 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parser-verify-hardening.test.js +21 -16
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-sqs.test.js +31 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/request-id-async-context.test.js +21 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +35 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update-poll-asset-digest.test.js +21 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +29 -10
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +51 -33
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-multipart-sse.test.js +31 -13
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +41 -21
- package/lib/vendor/blamejs/test/layer-0-primitives/testing-request.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-exporter.test.js +30 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +91 -20
- package/package.json +1 -1
|
@@ -21,6 +21,60 @@ function rejects(label, fn, pattern) {
|
|
|
21
21
|
|
|
22
22
|
function _sleep(ms) { return helpers.passiveObserve(ms, "ws-client: handshake/echo/close real-time observation"); }
|
|
23
23
|
|
|
24
|
+
// Every wsClient dialed in the test holds a client socket. A client that
|
|
25
|
+
// errors, times out, or schedules a reconnect never reaches a graceful
|
|
26
|
+
// close(), so its socket finalizes its async destroy past the forked worker's
|
|
27
|
+
// post-run grace window. Track every live client here so the drain can retire
|
|
28
|
+
// each one (cancel reconnect + destroy the socket) and then poll until the TCP
|
|
29
|
+
// handles release inside run().
|
|
30
|
+
var _liveClients = [];
|
|
31
|
+
function _trackedConnect(url, opts) {
|
|
32
|
+
var c = b.wsClient.connect(url, opts);
|
|
33
|
+
_liveClients.push(c);
|
|
34
|
+
return c;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The in-process fixture servers keep their accepted upgrade sockets open (the
|
|
38
|
+
// flood / stub / hold-open scenarios never send FIN), so server.close() alone
|
|
39
|
+
// stops listening but leaves those sockets — and their TCPSocketWrap handles —
|
|
40
|
+
// alive. Track every server so the drain can force its live connections shut.
|
|
41
|
+
var _liveServers = [];
|
|
42
|
+
function _trackServer(server) {
|
|
43
|
+
_liveServers.push(server);
|
|
44
|
+
return server;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function _drainTcpHandles() {
|
|
48
|
+
_liveClients.forEach(function (c) {
|
|
49
|
+
try { c.cancelReconnect(); } catch (_e) { /* best-effort */ }
|
|
50
|
+
try { c.close(); } catch (_e) { /* best-effort */ }
|
|
51
|
+
// Force the socket down NOW — close()'s graceful path defers the socket
|
|
52
|
+
// teardown behind a 1s timer, which would itself outlive run().
|
|
53
|
+
try { c._teardown(b.wsClient.CLOSE_NORMAL, "", false); } catch (_e) { /* best-effort */ }
|
|
54
|
+
});
|
|
55
|
+
_liveServers.forEach(function (s) {
|
|
56
|
+
// Destroy any accepted upgrade / hold-open sockets the server is keeping
|
|
57
|
+
// alive (these are detached from the HTTP server's connection tracking, so
|
|
58
|
+
// closeAllConnections can't see them), then stop listening.
|
|
59
|
+
if (Array.isArray(s._wsSockets)) {
|
|
60
|
+
s._wsSockets.forEach(function (sock) {
|
|
61
|
+
try { if (sock && !sock.destroyed) sock.destroy(); } catch (_e) { /* best-effort */ }
|
|
62
|
+
});
|
|
63
|
+
s._wsSockets = [];
|
|
64
|
+
}
|
|
65
|
+
try { if (typeof s.closeAllConnections === "function") s.closeAllConnections(); } catch (_e) { /* best-effort */ }
|
|
66
|
+
try { s.close(); } catch (_e) { /* best-effort */ }
|
|
67
|
+
});
|
|
68
|
+
_liveClients = [];
|
|
69
|
+
_liveServers = [];
|
|
70
|
+
if (typeof process.getActiveResourcesInfo !== "function") return;
|
|
71
|
+
await helpers.waitUntil(function () {
|
|
72
|
+
return process.getActiveResourcesInfo().filter(function (t) {
|
|
73
|
+
return t === "TCPSocketWrap" || t === "TCPServerWrap";
|
|
74
|
+
}).length === 0;
|
|
75
|
+
}, { timeoutMs: 5000, label: "ws-client: TCP handle drain after client teardown" });
|
|
76
|
+
}
|
|
77
|
+
|
|
24
78
|
// Minimal in-process WebSocket server using lib/websocket primitives.
|
|
25
79
|
function _makeServer(opts) {
|
|
26
80
|
opts = opts || {};
|
|
@@ -28,7 +82,12 @@ function _makeServer(opts) {
|
|
|
28
82
|
res.writeHead(404);
|
|
29
83
|
res.end();
|
|
30
84
|
});
|
|
85
|
+
// Upgrade hands socket ownership to this handler, so the HTTP server no
|
|
86
|
+
// longer tracks it — closeAllConnections() can't reach it. Record each one
|
|
87
|
+
// so the drain can destroy them directly.
|
|
88
|
+
server._wsSockets = [];
|
|
31
89
|
server.on("upgrade", function (req, socket /*, head */) {
|
|
90
|
+
server._wsSockets.push(socket);
|
|
32
91
|
var key = req.headers["sec-websocket-key"];
|
|
33
92
|
if (!key) {
|
|
34
93
|
socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
|
|
@@ -92,12 +151,20 @@ function _makeServer(opts) {
|
|
|
92
151
|
});
|
|
93
152
|
return new Promise(function (resolve) {
|
|
94
153
|
server.listen(0, "127.0.0.1", function () {
|
|
95
|
-
resolve(server);
|
|
154
|
+
resolve(_trackServer(server));
|
|
96
155
|
});
|
|
97
156
|
});
|
|
98
157
|
}
|
|
99
158
|
|
|
100
159
|
async function run() {
|
|
160
|
+
try {
|
|
161
|
+
await _runTests();
|
|
162
|
+
} finally {
|
|
163
|
+
await _drainTcpHandles();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function _runTests() {
|
|
101
168
|
// ---- shape ----
|
|
102
169
|
check("b.wsClient is object", typeof b.wsClient === "object");
|
|
103
170
|
check("b.wsClient.connect is fn", typeof b.wsClient.connect === "function");
|
|
@@ -141,7 +208,7 @@ async function run() {
|
|
|
141
208
|
// ---- happy path: connect + send + echo ----
|
|
142
209
|
var server = await _makeServer({});
|
|
143
210
|
var port = server.address().port;
|
|
144
|
-
var client =
|
|
211
|
+
var client = _trackedConnect("ws://127.0.0.1:" + port + "/", {
|
|
145
212
|
reconnect: false,
|
|
146
213
|
audit: false,
|
|
147
214
|
allowInternal: true,
|
|
@@ -189,7 +256,7 @@ async function run() {
|
|
|
189
256
|
// ---- send before open ----
|
|
190
257
|
var server2 = await _makeServer({});
|
|
191
258
|
var port2 = server2.address().port;
|
|
192
|
-
var c2 =
|
|
259
|
+
var c2 = _trackedConnect("ws://127.0.0.1:" + port2, { reconnect: false, audit: false, allowInternal: true });
|
|
193
260
|
rejects("send: not open yet",
|
|
194
261
|
function () { c2.send("data"); }, /not open/);
|
|
195
262
|
c2.close();
|
|
@@ -199,7 +266,7 @@ async function run() {
|
|
|
199
266
|
// ---- bad accept hash ----
|
|
200
267
|
var server3 = await _makeServer({ tamperKey: true });
|
|
201
268
|
var port3 = server3.address().port;
|
|
202
|
-
var c3 =
|
|
269
|
+
var c3 = _trackedConnect("ws://127.0.0.1:" + port3, {
|
|
203
270
|
reconnect: false, audit: false, allowInternal: true,
|
|
204
271
|
});
|
|
205
272
|
var c3Err = null;
|
|
@@ -211,7 +278,7 @@ async function run() {
|
|
|
211
278
|
// ---- non-101 status ----
|
|
212
279
|
var server4 = await _makeServer({ rejectStatus: 403 });
|
|
213
280
|
var port4 = server4.address().port;
|
|
214
|
-
var c4 =
|
|
281
|
+
var c4 = _trackedConnect("ws://127.0.0.1:" + port4, {
|
|
215
282
|
reconnect: false, audit: false, allowInternal: true,
|
|
216
283
|
});
|
|
217
284
|
var c4Err = null;
|
|
@@ -229,7 +296,7 @@ async function run() {
|
|
|
229
296
|
// bad-status code is split by the carried status, not re-derived by the caller.
|
|
230
297
|
var server4b = await _makeServer({ rejectStatus: 503 });
|
|
231
298
|
var port4b = server4b.address().port;
|
|
232
|
-
var c4b =
|
|
299
|
+
var c4b = _trackedConnect("ws://127.0.0.1:" + port4b, {
|
|
233
300
|
reconnect: false, audit: false, allowInternal: true,
|
|
234
301
|
});
|
|
235
302
|
var c4bErr = null;
|
|
@@ -243,7 +310,7 @@ async function run() {
|
|
|
243
310
|
// ---- subprotocol negotiation ----
|
|
244
311
|
var server5 = await _makeServer({ subprotocol: "json-stream-v1" });
|
|
245
312
|
var port5 = server5.address().port;
|
|
246
|
-
var c5 =
|
|
313
|
+
var c5 = _trackedConnect("ws://127.0.0.1:" + port5, {
|
|
247
314
|
subprotocols: ["json-stream-v1", "msgpack-stream"],
|
|
248
315
|
reconnect: false, audit: false, allowInternal: true,
|
|
249
316
|
});
|
|
@@ -259,7 +326,7 @@ async function run() {
|
|
|
259
326
|
// ---- subprotocol-not-in-offer rejected ----
|
|
260
327
|
var server6 = await _makeServer({ subprotocol: "ghost-protocol" });
|
|
261
328
|
var port6 = server6.address().port;
|
|
262
|
-
var c6 =
|
|
329
|
+
var c6 = _trackedConnect("ws://127.0.0.1:" + port6, {
|
|
263
330
|
subprotocols: ["json-stream-v1"],
|
|
264
331
|
reconnect: false, audit: false, allowInternal: true,
|
|
265
332
|
});
|
|
@@ -274,7 +341,7 @@ async function run() {
|
|
|
274
341
|
// is attempted (where the CRLF check fires).
|
|
275
342
|
var server7a = await _makeServer({});
|
|
276
343
|
var port7a = server7a.address().port;
|
|
277
|
-
var c7a =
|
|
344
|
+
var c7a = _trackedConnect("ws://127.0.0.1:" + port7a, {
|
|
278
345
|
headers: { "X-Evil": "value\r\nX-Other: injected" },
|
|
279
346
|
reconnect: false, audit: false, allowInternal: true,
|
|
280
347
|
});
|
|
@@ -287,7 +354,7 @@ async function run() {
|
|
|
287
354
|
// ---- maxMessageBytes guard on send ----
|
|
288
355
|
var server7 = await _makeServer({});
|
|
289
356
|
var port7 = server7.address().port;
|
|
290
|
-
var c7 =
|
|
357
|
+
var c7 = _trackedConnect("ws://127.0.0.1:" + port7, {
|
|
291
358
|
maxMessageBytes: 100,
|
|
292
359
|
reconnect: false, audit: false, allowInternal: true,
|
|
293
360
|
});
|
|
@@ -304,7 +371,7 @@ async function run() {
|
|
|
304
371
|
// enforced on the running fragment total, not only at FIN (CWE-770).
|
|
305
372
|
var serverFlood = await _makeServer({ floodFragments: { partBytes: 600, count: 4 } });
|
|
306
373
|
var portFlood = serverFlood.address().port;
|
|
307
|
-
var cFlood =
|
|
374
|
+
var cFlood = _trackedConnect("ws://127.0.0.1:" + portFlood, {
|
|
308
375
|
maxMessageBytes: 1024, // 600 + 600 = 1200 > 1024 before any FIN
|
|
309
376
|
reconnect: false, audit: false, allowInternal: true,
|
|
310
377
|
});
|
|
@@ -320,7 +387,7 @@ async function run() {
|
|
|
320
387
|
// ---- url + readyState getters ----
|
|
321
388
|
var server8 = await _makeServer({});
|
|
322
389
|
var port8 = server8.address().port;
|
|
323
|
-
var c8 =
|
|
390
|
+
var c8 = _trackedConnect("ws://127.0.0.1:" + port8 + "/foo", {
|
|
324
391
|
reconnect: false, audit: false, allowInternal: true,
|
|
325
392
|
});
|
|
326
393
|
// Poll for handshake completion rather than a fixed-budget sleep — the
|
|
@@ -335,10 +402,14 @@ async function run() {
|
|
|
335
402
|
|
|
336
403
|
// ---- handshake timeout ----
|
|
337
404
|
// Connect to a TCP server that accepts then never responds.
|
|
338
|
-
var stubServer = net.createServer(function (sock) {
|
|
405
|
+
var stubServer = _trackServer(net.createServer(function (sock) {
|
|
406
|
+
// Accept and hold — record it so the drain destroys the held socket.
|
|
407
|
+
stubServer._wsSockets.push(sock);
|
|
408
|
+
}));
|
|
409
|
+
stubServer._wsSockets = [];
|
|
339
410
|
await new Promise(function (r) { stubServer.listen(0, "127.0.0.1", r); });
|
|
340
411
|
var stubPort = stubServer.address().port;
|
|
341
|
-
var c9 =
|
|
412
|
+
var c9 = _trackedConnect("ws://127.0.0.1:" + stubPort, {
|
|
342
413
|
handshakeTimeoutMs: 200,
|
|
343
414
|
reconnect: false, audit: false, allowInternal: true,
|
|
344
415
|
});
|
|
@@ -350,7 +421,7 @@ async function run() {
|
|
|
350
421
|
|
|
351
422
|
// ---- reconnect: connection refused → schedules reconnect ----
|
|
352
423
|
// Use a port we know nobody listens on.
|
|
353
|
-
var c10 =
|
|
424
|
+
var c10 = _trackedConnect("ws://127.0.0.1:1", {
|
|
354
425
|
reconnect: { maxAttempts: 1, baseMs: 50, maxMs: 100 },
|
|
355
426
|
handshakeTimeoutMs: 200,
|
|
356
427
|
audit: false,
|
|
@@ -367,7 +438,7 @@ async function run() {
|
|
|
367
438
|
// ---- permanent error: 4xx skips reconnect ----
|
|
368
439
|
var server4xx = await _makeServer({ rejectStatus: 403 });
|
|
369
440
|
var port4xx = server4xx.address().port;
|
|
370
|
-
var c11 =
|
|
441
|
+
var c11 = _trackedConnect("ws://127.0.0.1:" + port4xx, {
|
|
371
442
|
reconnect: { maxAttempts: 5, baseMs: 50, maxMs: 100 },
|
|
372
443
|
audit: false,
|
|
373
444
|
allowInternal: true,
|
|
@@ -385,7 +456,7 @@ async function run() {
|
|
|
385
456
|
// alwaysPermanent → _isPermanentError always true → willReconnect always false).
|
|
386
457
|
var server5xx = await _makeServer({ rejectStatus: 503 });
|
|
387
458
|
var port5xx = server5xx.address().port;
|
|
388
|
-
var c12 =
|
|
459
|
+
var c12 = _trackedConnect("ws://127.0.0.1:" + port5xx, {
|
|
389
460
|
reconnect: { maxAttempts: 1, baseMs: 50, maxMs: 100 },
|
|
390
461
|
audit: false,
|
|
391
462
|
allowInternal: true,
|
|
@@ -401,7 +472,7 @@ async function run() {
|
|
|
401
472
|
// ---- close() reason length cap (>123 bytes truncated) ----
|
|
402
473
|
var serverCl = await _makeServer({});
|
|
403
474
|
var portCl = serverCl.address().port;
|
|
404
|
-
var cCl =
|
|
475
|
+
var cCl = _trackedConnect("ws://127.0.0.1:" + portCl, { reconnect: false, audit: false, allowInternal: true });
|
|
405
476
|
await _sleep(200);
|
|
406
477
|
// Should not throw — close() truncates internally.
|
|
407
478
|
cCl.close(1000, "x".repeat(500));
|
|
@@ -420,7 +491,7 @@ async function run() {
|
|
|
420
491
|
// Custom GUID accepted at config time. Wire round-trip is exercised in the
|
|
421
492
|
// ws-client integration test; here we only confirm config-time validation
|
|
422
493
|
// does not refuse a valid string.
|
|
423
|
-
var cGuid =
|
|
494
|
+
var cGuid = _trackedConnect("ws://127.0.0.1:1", {
|
|
424
495
|
handshakeGuid: "MY-CUSTOM-GUID-12345678",
|
|
425
496
|
reconnect: false, audit: false, allowInternal: true,
|
|
426
497
|
handshakeTimeoutMs: 100,
|
|
@@ -439,7 +510,7 @@ async function run() {
|
|
|
439
510
|
function _onUnhandled(e) { sawUnhandled = e; }
|
|
440
511
|
process.on("unhandledRejection", _onUnhandled);
|
|
441
512
|
var ssrfErr = null;
|
|
442
|
-
var cSwap =
|
|
513
|
+
var cSwap = _trackedConnect("ws://127.0.0.1:1", {
|
|
443
514
|
urlFor: function () { return "ws://169.254.169.254:1/"; }, // cloud-metadata — hard-deny
|
|
444
515
|
reconnect: false, audit: false, allowInternal: true, // allowInternal must NOT bypass metadata
|
|
445
516
|
});
|
package/package.json
CHANGED