@blamejs/blamejs-shop 0.4.109 → 0.4.110

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 CHANGED
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.4.x
10
10
 
11
+ - v0.4.110 (2026-06-26) — **Inbound webhook bodies and external API responses are parsed through the size-bounded, prototype-pollution-stripping JSON primitive instead of a raw parse.** The remaining places that parsed externally-supplied JSON with a raw JSON.parse — the Stripe and PayPal inbound webhook bodies, the captcha provider's verification response, and the Stripe / PayPal / R2 API responses — now route through the framework's safe-JSON parser, which strips prototype-pollution keys ("__proto__") and bounds parse depth, key count, and byte size. This matters most for the PayPal webhook body, which is parsed up front before its signature is verified, and for every inbound or provider response that previously had no size bound. An audit confirmed the rest of the app's JSON parsing already reads only values it wrote itself to the database (validated at write time) or already used the safe parser, so those are unchanged. Valid payloads parse identically; a malformed, prototype-pollution-laden, or oversized body is now defused. No configuration changes. **Changed:** *Externally-supplied JSON (webhook bodies, provider responses) is parsed with the safe-JSON primitive* — The inbound Stripe and PayPal webhook bodies, the captcha siteverify response, and the Stripe / PayPal / R2 API responses were parsed with a raw JSON.parse, which keeps a "__proto__" member as an own key and imposes no size bound. These now route through the framework's safe-JSON parser (prototype-pollution-key strip + depth / key / size caps), so an inbound or external payload can no longer carry a prototype-pollution gadget or force an unbounded parse — notably the PayPal webhook body, which is decoded before its signature is verified. The change is parse-only: valid payloads decode exactly as before, each call keeps its existing error fallback, and the rest of the app's JSON parsing (values it serialized to its own database, validated at write time) is left as-is.
12
+
11
13
  - v0.4.109 (2026-06-26) — **Vendored framework refreshed to 0.15.29.** Updates the vendored blamejs framework to 0.15.29, an upstream security-hardening release. Upstream now routes the parsing of operator- and untrusted-supplied JSON through the framework's safe-JSON primitive — which strips prototype-pollution keys ("__proto__" and friends) and bounds parse depth, key count, and byte size — instead of a raw JSON.parse, across the OpenAPI and AsyncAPI document parsers, the sandbox result decoder, and the internal sealed-store and VEX parses. This storefront consumes those surfaces through the vendored framework, so the hardening applies on upgrade with no API or configuration change and no operator action required. Valid input parses identically; a "__proto__"-laden or oversized payload is defused. **Changed:** *Vendored framework refreshed to 0.15.29* — Refreshes the vendored blamejs framework to 0.15.29. Upstream routes operator- and untrusted-supplied JSON through the safe-JSON primitive (prototype-pollution-key strip + depth / key / size caps, fail-closed) rather than a raw JSON.parse — in the OpenAPI / AsyncAPI parsers, the sandbox result decoder, and the internal sealed-store and VEX parses — and adds a parse-string-or-object helper so a raw JSON.parse on operator input can't be reintroduced one call site at a time. Valid documents are unaffected; a prototype-pollution-laden or oversized payload is now stripped and bounded. No runtime API change and no operator action required.
12
14
 
13
15
  - v0.4.108 (2026-06-26) — **Vendored framework refreshed to 0.15.28.** Updates the vendored blamejs framework to 0.15.28. The upstream change corrects the terminal-vs-transient retry signal (err.permanent) on the framework's DNS and TLS network errors, so the vendored HTTP client's internal retry behavior only re-attempts failures a retry can actually fix and stops retrying hopeless ones. This storefront consumes those network primitives only transitively through the vendored HTTP client (payment-provider and outbound-webhook calls), so the improvement applies automatically with no API or configuration change and no operator action required. **Changed:** *Vendored framework refreshed to 0.15.28* — Refreshes the vendored blamejs framework to 0.15.28. Upstream, the DNS and TLS network errors now expose a correct err.permanent flag (fail-closed: an unknown code is treated as permanent), so a retry loop re-attempts only transient network round-trip failures and never spins on a permanent one — while a trust-verification failure stays terminal and is never silently retried. This storefront uses these primitives only through the vendored HTTP client, so the better retry behavior applies transitively to payment-provider and outbound-webhook calls; there is no API change and no operator action required.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.4.109",
2
+ "version": "0.4.110",
3
3
  "assets": {
4
4
  "css/admin.css": {
5
5
  "integrity": "sha384-imfe0otYErcB8rr2h6KLSGTtStirysptpXETSPY4zLv3bZoIT75Lo1dOvkOav+xL",
package/lib/payment.js CHANGED
@@ -280,7 +280,7 @@ async function _verifyWebhook(headers, rawBody, secret, opts) {
280
280
  }
281
281
 
282
282
  try {
283
- return { ok: true, event: JSON.parse(rawBody) };
283
+ return { ok: true, event: b.safeJson.parse(rawBody) };
284
284
  } catch (_e) {
285
285
  return { ok: false, reason: "bad-json" };
286
286
  }
@@ -335,7 +335,7 @@ async function _stripeCall(opts, method, path, params, idempotencyKey) {
335
335
  });
336
336
  var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
337
337
  var parsed = null;
338
- try { parsed = text.length ? JSON.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
338
+ try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
339
339
  if (res.statusCode < 200 || res.statusCode >= 300) {
340
340
  var err = new Error("stripe: " + method + " " + path + " → HTTP " + res.statusCode +
341
341
  (parsed && parsed.error && parsed.error.message ? " — " + parsed.error.message : ""));
@@ -919,7 +919,7 @@ async function _paypalToken(opts, state) {
919
919
  allowedHosts: [_paypalAllowedHost(opts)],
920
920
  });
921
921
  var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
922
- var parsed; try { parsed = text.length ? JSON.parse(text) : {}; } catch (_e) { parsed = {}; }
922
+ var parsed; try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = {}; }
923
923
  if (res.statusCode < 200 || res.statusCode >= 300 || !parsed.access_token) {
924
924
  var err = new Error("paypal: OAuth2 token exchange failed → HTTP " + res.statusCode +
925
925
  (parsed && parsed.error_description ? " — " + parsed.error_description : ""));
@@ -974,7 +974,7 @@ async function _paypalCall(opts, state, method, path, bodyObj, requestId, breake
974
974
  allowedHosts: [allowedHost],
975
975
  });
976
976
  var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
977
- var parsed; try { parsed = text.length ? JSON.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
977
+ var parsed; try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
978
978
  if (res.statusCode < 200 || res.statusCode >= 300) {
979
979
  var detail = parsed && (parsed.message || (parsed.details && parsed.details[0] && parsed.details[0].description)) || "";
980
980
  var err = new Error("paypal: " + method + " " + path + " → HTTP " + res.statusCode + (detail ? " — " + detail : ""));
@@ -1130,7 +1130,7 @@ function paypal(opts) {
1130
1130
  return { ok: false, reason: "missing-transmission-headers" };
1131
1131
  }
1132
1132
  var event;
1133
- try { event = typeof rawBody === "string" ? JSON.parse(rawBody) : rawBody; }
1133
+ try { event = typeof rawBody === "string" ? b.safeJson.parse(rawBody) : rawBody; }
1134
1134
  catch (_e) { return { ok: false, reason: "malformed-body" }; }
1135
1135
  var verifyBody = {
1136
1136
  auth_algo: authAlgo,
package/lib/r2-bridge.js CHANGED
@@ -140,7 +140,7 @@ function create(opts) {
140
140
  }
141
141
  var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
142
142
  var json = null;
143
- try { json = text.length ? JSON.parse(text) : null; } catch (_e) { json = null; }
143
+ try { json = text.length ? b.safeJson.parse(text) : null; } catch (_e) { json = null; }
144
144
  if (res.statusCode < 200 || res.statusCode >= 300) {
145
145
  var err = _httpErr(res.statusCode, "upload");
146
146
  if (json && json.error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/blamejs-shop",
3
- "version": "0.4.109",
3
+ "version": "0.4.110",
4
4
  "description": "Open-source framework built on blamejs. Vendored stack, zero npm runtime deps, PQC-first crypto, security-on by default.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {