@blamejs/blamejs-shop 0.5.20 → 0.5.22
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/README.md +1 -0
- package/SECURITY.md +23 -0
- package/lib/addresses.js +17 -3
- package/lib/admin.js +14 -5
- package/lib/affiliates.js +7 -23
- package/lib/announcement-bar.js +5 -22
- package/lib/api-keys.js +4 -13
- package/lib/asset-manifest.json +1 -1
- package/lib/banner-ab-tests.js +5 -9
- package/lib/blog-articles.js +8 -26
- package/lib/captcha-gate.js +7 -17
- package/lib/carrier-accounts.js +3 -10
- package/lib/catalog-drafts.js +5 -12
- package/lib/category-navigation.js +7 -20
- package/lib/cms-blocks.js +4 -7
- package/lib/compliance-export.js +11 -11
- package/lib/consent-ledger.js +2 -4
- package/lib/cost-layers.js +56 -21
- package/lib/customer-import.js +2 -2
- package/lib/customer-notes.js +7 -23
- package/lib/customer-roles.js +3 -5
- package/lib/customer-segments.js +17 -14
- package/lib/customer-surveys.js +7 -14
- package/lib/customers.js +2 -4
- package/lib/dispute-resolution.js +5 -13
- package/lib/dropship-forwarding.js +3 -5
- package/lib/dunning.js +2 -7
- package/lib/email-ab-tests.js +4 -8
- package/lib/email-campaigns.js +39 -15
- package/lib/email-warmup.js +2 -7
- package/lib/experiments.js +6 -10
- package/lib/externaldb-d1.js +47 -31
- package/lib/geolocation.js +18 -28
- package/lib/gift-options.js +5 -23
- package/lib/knowledge-base.js +7 -22
- package/lib/line-gift-wrap.js +7 -17
- package/lib/live-chat.js +5 -18
- package/lib/metered-usage.js +3 -8
- package/lib/notifications.js +3 -7
- package/lib/operator-accounts.js +3 -5
- package/lib/operator-approvals.js +6 -8
- package/lib/operator-audit-log.js +2 -7
- package/lib/operator-help-center.js +5 -21
- package/lib/operator-inbox.js +4 -11
- package/lib/operator-roles.js +5 -7
- package/lib/order-escalation.js +2 -2
- package/lib/order-export.js +24 -20
- package/lib/order-notes.js +4 -14
- package/lib/order-ratings.js +4 -10
- package/lib/payment-methods.js +5 -13
- package/lib/payment-retries.js +2 -7
- package/lib/pixel-events.js +21 -28
- package/lib/plan-changes.js +2 -7
- package/lib/product-qa.js +4 -8
- package/lib/promo-banners.js +7 -15
- package/lib/purchase-orders.js +3 -6
- package/lib/push-notifications.js +7 -32
- package/lib/pwa-manifest.js +6 -11
- package/lib/quotes.js +5 -9
- package/lib/reviews.js +4 -10
- package/lib/robots-config.js +6 -14
- package/lib/sales-tax-filings.js +2 -2
- package/lib/search-facets.js +5 -5
- package/lib/search-ranking.js +4 -7
- package/lib/search-synonyms.js +7 -21
- package/lib/security-middleware.js +86 -58
- package/lib/seller-signup.js +10 -26
- package/lib/sidebar-widgets.js +6 -15
- package/lib/site-redirects.js +5 -16
- package/lib/sitemap-generator.js +3 -7
- package/lib/sms-dispatcher.js +7 -23
- package/lib/stock-receipts.js +4 -10
- package/lib/storefront-dashboards.js +2 -10
- package/lib/storefront-forms.js +9 -22
- package/lib/storefront-pages.js +6 -20
- package/lib/storefront.js +2 -2
- package/lib/subscription-billing.js +3 -8
- package/lib/subscription-controls.js +2 -7
- package/lib/suggestion-box.js +9 -26
- package/lib/support-tickets.js +6 -24
- package/lib/tax-remittance.js +2 -2
- package/lib/tenants.js +2 -7
- package/lib/text-guard.js +179 -35
- package/lib/theme-assets.js +4 -16
- package/lib/translations.js +3 -6
- package/lib/trust-badges.js +4 -7
- package/lib/vendor/MANIFEST.json +12 -12
- package/lib/vendor/blamejs/CHANGELOG.md +32 -0
- package/lib/vendor/blamejs/NOTICE +1 -1
- package/lib/vendor/blamejs/README.md +1 -1
- package/lib/vendor/blamejs/lib/network-tls.js +98 -13
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +12 -12
- package/lib/vendor/blamejs/lib/vendor/blamejs-pki.cjs +568 -304
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/sbom.cdx.json +6 -6
- package/lib/vendor-invoices.js +3 -6
- package/lib/vendors.js +5 -19
- package/lib/webhook-receiver.js +3 -10
- package/lib/webhook-subscriptions.js +3 -13
- package/lib/wishlist-sharing.js +5 -10
- package/package.json +1 -1
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:6fba0fbc-d16f-4c2c-864f-99f1c662d2af",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-08-
|
|
8
|
+
"timestamp": "2026-08-11T01:57:40.816Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "build"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@blamejs/core@0.18.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.18.24",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.18.
|
|
25
|
+
"version": "0.18.24",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"author": "blamejs contributors",
|
|
28
28
|
"description": "The Node framework that owns its stack.",
|
|
29
|
-
"purl": "pkg:npm/%40blamejs/core@0.18.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.18.24",
|
|
30
30
|
"properties": [],
|
|
31
31
|
"externalReferences": [
|
|
32
32
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"components": [],
|
|
55
55
|
"dependencies": [
|
|
56
56
|
{
|
|
57
|
-
"ref": "@blamejs/core@0.18.
|
|
57
|
+
"ref": "@blamejs/core@0.18.24",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|
package/lib/vendor-invoices.js
CHANGED
|
@@ -95,10 +95,6 @@ var CURRENCY_RE = /^[A-Z]{3}$/;
|
|
|
95
95
|
// as the sibling accounts-payable primitives — operator-rendered text
|
|
96
96
|
// fields refuse these to keep the dashboard + printout safe from
|
|
97
97
|
// header-injection + visual-spoofing attacks.
|
|
98
|
-
var CONTROL_BYTE_RE = /[\x00-\x1f\x7f]/;
|
|
99
|
-
var ZERO_WIDTH_RE = new RegExp(
|
|
100
|
-
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
101
|
-
);
|
|
102
98
|
|
|
103
99
|
var INVOICE_STATUSES = Object.freeze([
|
|
104
100
|
"received", "approved", "paid", "disputed", "voided",
|
|
@@ -107,6 +103,7 @@ var INVOICE_STATUSES = Object.freeze([
|
|
|
107
103
|
var MAX_DUE_WITHIN_DAYS = 3650; // ~10 years — bound the predicate
|
|
108
104
|
|
|
109
105
|
var b = require("./vendor/blamejs");
|
|
106
|
+
var textGuard = require("./text-guard");
|
|
110
107
|
|
|
111
108
|
var MS_PER_DAY = b.constants.TIME.days(1);
|
|
112
109
|
|
|
@@ -219,10 +216,10 @@ function _shortText(s, label, max) {
|
|
|
219
216
|
if (s.length > max) {
|
|
220
217
|
throw new TypeError("vendor-invoices: " + label + " must be <= " + max + " characters");
|
|
221
218
|
}
|
|
222
|
-
if (
|
|
219
|
+
if (textGuard.hasCodepointThreat(s, { singleLine: "reject" })) {
|
|
223
220
|
throw new TypeError("vendor-invoices: " + label + " contains control bytes");
|
|
224
221
|
}
|
|
225
|
-
if (
|
|
222
|
+
if (textGuard.hasCodepointThreat(s, { zeroWidth: "reject" })) {
|
|
226
223
|
throw new TypeError("vendor-invoices: " + label + " contains zero-width / direction-override bytes");
|
|
227
224
|
}
|
|
228
225
|
return s;
|
package/lib/vendors.js
CHANGED
|
@@ -97,10 +97,6 @@ var PHONE_RE = /^\+?[1-9]\d{1,14}$/;
|
|
|
97
97
|
// direction-override bytes are a slipping-class for header injection
|
|
98
98
|
// + visual-spoofing attacks downstream. Spelled with \u-escapes so
|
|
99
99
|
// ESLint's no-irregular-whitespace stays happy.
|
|
100
|
-
var CONTROL_BYTE_STRICT_RE = /[\x00-\x1f\x7f]/;
|
|
101
|
-
var ZERO_WIDTH_RE = new RegExp(
|
|
102
|
-
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
103
|
-
);
|
|
104
100
|
|
|
105
101
|
// Mutable columns for `updateVendor(slug, patch)`. Slug is immutable
|
|
106
102
|
// — it's the public handle + the join-table key; mutating it would
|
|
@@ -119,6 +115,7 @@ var ALLOWED_UPDATE_COLUMNS = Object.freeze([
|
|
|
119
115
|
|
|
120
116
|
// Framework handle (the vendored blamejs); index.js re-exports this as .framework.
|
|
121
117
|
var b = require("./vendor/blamejs");
|
|
118
|
+
var textGuard = require("./text-guard");
|
|
122
119
|
|
|
123
120
|
// ---- validators ---------------------------------------------------------
|
|
124
121
|
|
|
@@ -159,12 +156,7 @@ function _name(s) {
|
|
|
159
156
|
if (s.length > MAX_NAME_LEN) {
|
|
160
157
|
throw new TypeError("vendors: name must be <= " + MAX_NAME_LEN + " characters");
|
|
161
158
|
}
|
|
162
|
-
|
|
163
|
-
throw new TypeError("vendors: name contains control bytes");
|
|
164
|
-
}
|
|
165
|
-
if (ZERO_WIDTH_RE.test(s)) {
|
|
166
|
-
throw new TypeError("vendors: name contains zero-width / direction-override bytes");
|
|
167
|
-
}
|
|
159
|
+
textGuard.freeText(s, "vendors: name", { singleLine: "reject", zeroWidth: "reject", bidiMarks: "allow" });
|
|
168
160
|
return s;
|
|
169
161
|
}
|
|
170
162
|
|
|
@@ -186,9 +178,7 @@ function _payoutAddress(s) {
|
|
|
186
178
|
if (s.length > MAX_PAYOUT_ADDRESS_LEN) {
|
|
187
179
|
throw new TypeError("vendors: payout_address must be <= " + MAX_PAYOUT_ADDRESS_LEN + " characters");
|
|
188
180
|
}
|
|
189
|
-
|
|
190
|
-
throw new TypeError("vendors: payout_address contains control / zero-width bytes");
|
|
191
|
-
}
|
|
181
|
+
textGuard.freeText(s, "vendors: payout_address", { singleLine: "reject", zeroWidth: "reject", bidiMarks: "allow" });
|
|
192
182
|
return s;
|
|
193
183
|
}
|
|
194
184
|
|
|
@@ -221,9 +211,7 @@ function _addressJson(value) {
|
|
|
221
211
|
if (encoded.length > MAX_ADDRESS_JSON_LEN) {
|
|
222
212
|
throw new TypeError("vendors: address JSON must be <= " + MAX_ADDRESS_JSON_LEN + " characters serialised");
|
|
223
213
|
}
|
|
224
|
-
|
|
225
|
-
throw new TypeError("vendors: address contains control / zero-width bytes");
|
|
226
|
-
}
|
|
214
|
+
textGuard.freeText(encoded, "vendors: address", { singleLine: "reject", zeroWidth: "reject", bidiMarks: "allow" });
|
|
227
215
|
return encoded;
|
|
228
216
|
}
|
|
229
217
|
|
|
@@ -265,9 +253,7 @@ function _orderId(s) {
|
|
|
265
253
|
if (s.length > 256) {
|
|
266
254
|
throw new TypeError("vendors: order_id must be <= 256 characters");
|
|
267
255
|
}
|
|
268
|
-
|
|
269
|
-
throw new TypeError("vendors: order_id contains control / zero-width bytes");
|
|
270
|
-
}
|
|
256
|
+
textGuard.freeText(s, "vendors: order_id", { singleLine: "reject", zeroWidth: "reject" });
|
|
271
257
|
return s;
|
|
272
258
|
}
|
|
273
259
|
|
package/lib/webhook-receiver.js
CHANGED
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
*/
|
|
80
80
|
|
|
81
81
|
var b = require("./vendor/blamejs");
|
|
82
|
+
var textGuard = require("./text-guard");
|
|
82
83
|
var C = b.constants;
|
|
83
84
|
|
|
84
85
|
var SECRET_NAMESPACE = "webhook-receiver-secret";
|
|
@@ -118,10 +119,6 @@ var MAX_REASON_LEN = 1024;
|
|
|
118
119
|
|
|
119
120
|
var SIGNATURE_HEX_RE = /^[0-9a-f]{64}$/i; // 32 bytes of HMAC-SHA-256 = 64 hex chars
|
|
120
121
|
|
|
121
|
-
var CONTROL_BYTE_STRICT_RE = /[\x00-\x1f\x7f]/;
|
|
122
|
-
var ZERO_WIDTH_RE = new RegExp(
|
|
123
|
-
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
124
|
-
);
|
|
125
122
|
|
|
126
123
|
var STATUSES = ["received", "processed", "failed"];
|
|
127
124
|
|
|
@@ -198,9 +195,7 @@ function _outcome(s) {
|
|
|
198
195
|
if (s.length > MAX_OUTCOME_LEN) {
|
|
199
196
|
throw new TypeError("webhookReceiver: outcome must be <= " + MAX_OUTCOME_LEN + " characters");
|
|
200
197
|
}
|
|
201
|
-
|
|
202
|
-
throw new TypeError("webhookReceiver: outcome contains control / zero-width bytes");
|
|
203
|
-
}
|
|
198
|
+
textGuard.freeText(s, "webhookReceiver: outcome", { singleLine: "reject", zeroWidth: "reject" });
|
|
204
199
|
return s;
|
|
205
200
|
}
|
|
206
201
|
|
|
@@ -215,9 +210,7 @@ function _reason(s) {
|
|
|
215
210
|
if (s.length > MAX_REASON_LEN) {
|
|
216
211
|
throw new TypeError("webhookReceiver: reason must be <= " + MAX_REASON_LEN + " characters");
|
|
217
212
|
}
|
|
218
|
-
|
|
219
|
-
throw new TypeError("webhookReceiver: reason contains control / zero-width bytes");
|
|
220
|
-
}
|
|
213
|
+
textGuard.freeText(s, "webhookReceiver: reason", { singleLine: "reject", zeroWidth: "reject", bidiMarks: "allow" });
|
|
221
214
|
return s;
|
|
222
215
|
}
|
|
223
216
|
|
|
@@ -68,10 +68,6 @@ var WILDCARD_EVENT = "*";
|
|
|
68
68
|
// control bytes are a slipping-class for header injection + visual
|
|
69
69
|
// spoofing downstream. Spelled with \u-escapes so ESLint's
|
|
70
70
|
// no-irregular-whitespace stays happy.
|
|
71
|
-
var CONTROL_BYTE_RE = /[\x00-\x1f\x7f]/;
|
|
72
|
-
var ZERO_WIDTH_RE = new RegExp(
|
|
73
|
-
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
74
|
-
);
|
|
75
71
|
|
|
76
72
|
// Event-type identifier shape — `domain.action[.qualifier]` segments
|
|
77
73
|
// of ASCII letters / digits / underscore, joined by `.`. The wildcard
|
|
@@ -111,9 +107,7 @@ function _ownerId(s) {
|
|
|
111
107
|
if (s.length > MAX_OWNER_ID_LEN) {
|
|
112
108
|
throw new TypeError("webhookSubscriptions: owner_id must be <= " + MAX_OWNER_ID_LEN + " characters");
|
|
113
109
|
}
|
|
114
|
-
|
|
115
|
-
throw new TypeError("webhookSubscriptions: owner_id contains control / zero-width bytes");
|
|
116
|
-
}
|
|
110
|
+
textGuard.freeText(s, "webhookSubscriptions: owner_id", { singleLine: "reject", zeroWidth: "reject" });
|
|
117
111
|
return s;
|
|
118
112
|
}
|
|
119
113
|
|
|
@@ -191,9 +185,7 @@ function _name(s) {
|
|
|
191
185
|
if (s.length > MAX_NAME_LEN) {
|
|
192
186
|
throw new TypeError("webhookSubscriptions: name must be <= " + MAX_NAME_LEN + " characters");
|
|
193
187
|
}
|
|
194
|
-
|
|
195
|
-
throw new TypeError("webhookSubscriptions: name contains control / zero-width bytes");
|
|
196
|
-
}
|
|
188
|
+
textGuard.freeText(s, "webhookSubscriptions: name", { singleLine: "reject", zeroWidth: "reject", bidiMarks: "allow" });
|
|
197
189
|
return s;
|
|
198
190
|
}
|
|
199
191
|
|
|
@@ -219,9 +211,7 @@ function _signingSecret(s) {
|
|
|
219
211
|
if (s.length > 512) {
|
|
220
212
|
throw new TypeError("webhookSubscriptions: signing_secret must be <= 512 characters");
|
|
221
213
|
}
|
|
222
|
-
|
|
223
|
-
throw new TypeError("webhookSubscriptions: signing_secret contains control / zero-width bytes");
|
|
224
|
-
}
|
|
214
|
+
textGuard.freeText(s, "webhookSubscriptions: signing_secret", { singleLine: "reject", zeroWidth: "reject" });
|
|
225
215
|
return s;
|
|
226
216
|
}
|
|
227
217
|
|
package/lib/wishlist-sharing.js
CHANGED
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
*/
|
|
64
64
|
|
|
65
65
|
var b = require("./vendor/blamejs");
|
|
66
|
+
var textGuard = require("./text-guard");
|
|
66
67
|
var wishlistModule = require("./wishlist");
|
|
67
68
|
|
|
68
69
|
// ---- constants ----------------------------------------------------------
|
|
@@ -82,8 +83,6 @@ var MAX_REASON_LEN = 500;
|
|
|
82
83
|
var MAX_EMAIL_LEN = 254;
|
|
83
84
|
var MAX_MEMBER_EMAILS = 50;
|
|
84
85
|
|
|
85
|
-
var CONTROL_BYTE_RE = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/;
|
|
86
|
-
var CONTROL_BYTE_STRICT_RE = /[\x00-\x1f\x7f]/;
|
|
87
86
|
|
|
88
87
|
// Conservative single-line email shape — defence in depth against
|
|
89
88
|
// header-injection / control-byte smuggling when the operator
|
|
@@ -127,7 +126,7 @@ function _title(s, label) {
|
|
|
127
126
|
if (typeof s !== "string" || s.length > MAX_TITLE_LEN) {
|
|
128
127
|
throw new TypeError("wishlistSharing: " + label + " must be a string <= " + MAX_TITLE_LEN + " chars");
|
|
129
128
|
}
|
|
130
|
-
if (
|
|
129
|
+
if (textGuard.hasCodepointThreat(s)) {
|
|
131
130
|
throw new TypeError("wishlistSharing: " + label + " must not contain control bytes");
|
|
132
131
|
}
|
|
133
132
|
return s;
|
|
@@ -137,7 +136,7 @@ function _requiredTitle(s, label) {
|
|
|
137
136
|
if (typeof s !== "string" || !s.length || s.length > MAX_TITLE_LEN) {
|
|
138
137
|
throw new TypeError("wishlistSharing: " + label + " must be a non-empty string <= " + MAX_TITLE_LEN + " chars");
|
|
139
138
|
}
|
|
140
|
-
if (
|
|
139
|
+
if (textGuard.hasCodepointThreat(s)) {
|
|
141
140
|
throw new TypeError("wishlistSharing: " + label + " must not contain control bytes");
|
|
142
141
|
}
|
|
143
142
|
return s;
|
|
@@ -162,9 +161,7 @@ function _reason(s) {
|
|
|
162
161
|
if (typeof s !== "string" || !s.length || s.length > MAX_REASON_LEN) {
|
|
163
162
|
throw new TypeError("wishlistSharing: reason must be a non-empty string <= " + MAX_REASON_LEN + " chars");
|
|
164
163
|
}
|
|
165
|
-
|
|
166
|
-
throw new TypeError("wishlistSharing: reason must not contain control bytes");
|
|
167
|
-
}
|
|
164
|
+
textGuard.freeText(s, "wishlistSharing: reason", { bidiMarks: "allow" });
|
|
168
165
|
return s;
|
|
169
166
|
}
|
|
170
167
|
|
|
@@ -205,9 +202,7 @@ function _viewerSessionId(s) {
|
|
|
205
202
|
// Session ids are opaque to this primitive; refuse control bytes
|
|
206
203
|
// so the hashed breadcrumb has no log-injection vector even if a
|
|
207
204
|
// downstream tool ever rendered the raw value.
|
|
208
|
-
|
|
209
|
-
throw new TypeError("wishlistSharing: viewer_session_id must not contain control bytes");
|
|
210
|
-
}
|
|
205
|
+
textGuard.freeText(s, "wishlistSharing: viewer_session_id", { singleLine: "reject" });
|
|
211
206
|
return s;
|
|
212
207
|
}
|
|
213
208
|
|
package/package.json
CHANGED