@preprio/toolkit 0.2.0-beta.4 → 0.2.0-beta.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/dist/astro/index.cjs +27 -10
- package/dist/astro/index.js +27 -10
- package/dist/{chunk-6OOGNVJ4.js → chunk-C6YEXA5G.js} +27 -6
- package/dist/index.cjs +54 -16
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -11
- package/dist/nextjs/components.cjs +27 -6
- package/dist/nextjs/components.js +1 -1
- package/dist/nextjs/index.cjs +27 -10
- package/dist/nextjs/index.js +27 -10
- package/dist/nuxt/index.cjs +27 -10
- package/dist/nuxt/index.js +27 -10
- package/dist/react/components.cjs +27 -6
- package/dist/react/components.js +27 -6
- package/dist/sveltekit/index.cjs +27 -10
- package/dist/sveltekit/index.js +27 -10
- package/package.json +1 -1
package/dist/astro/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ __export(astro_exports, {
|
|
|
30
30
|
module.exports = __toCommonJS(astro_exports);
|
|
31
31
|
|
|
32
32
|
// src/version.ts
|
|
33
|
-
var VERSION = "0.2.0-beta.
|
|
33
|
+
var VERSION = "0.2.0-beta.6";
|
|
34
34
|
|
|
35
35
|
// src/core/features.ts
|
|
36
36
|
function isEnabled(config) {
|
|
@@ -193,6 +193,11 @@ var UTM_PARAMS = [
|
|
|
193
193
|
"utm_content",
|
|
194
194
|
"utm_campaign"
|
|
195
195
|
];
|
|
196
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
197
|
+
function sanitizeHeaderValue(value) {
|
|
198
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
199
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
200
|
+
}
|
|
196
201
|
function serializeCookie(cookie) {
|
|
197
202
|
const parts = [
|
|
198
203
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -224,6 +229,15 @@ function parseCookies(request) {
|
|
|
224
229
|
function processPreprRequest(request, opts) {
|
|
225
230
|
const requestHeaders = new Headers(request.headers);
|
|
226
231
|
const responseCookies = [];
|
|
232
|
+
const inboundPreprHeaders = [];
|
|
233
|
+
requestHeaders.forEach((_value, key) => {
|
|
234
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
235
|
+
inboundPreprHeaders.push(key);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
for (const key of inboundPreprHeaders) {
|
|
239
|
+
requestHeaders.delete(key);
|
|
240
|
+
}
|
|
227
241
|
const requestCookies = parseCookies(request);
|
|
228
242
|
const url = new URL(request.url);
|
|
229
243
|
const searchParams = url.searchParams;
|
|
@@ -233,25 +247,28 @@ function processPreprRequest(request, opts) {
|
|
|
233
247
|
for (const key of UTM_PARAMS) {
|
|
234
248
|
const value = searchParams.get(key);
|
|
235
249
|
if (value !== null) {
|
|
236
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
250
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
237
251
|
}
|
|
238
252
|
}
|
|
239
253
|
const referer = request.headers.get("referer");
|
|
240
254
|
if (referer) {
|
|
241
|
-
requestHeaders.set(
|
|
255
|
+
requestHeaders.set(
|
|
256
|
+
"Prepr-Context-initial_referral",
|
|
257
|
+
sanitizeHeaderValue(referer)
|
|
258
|
+
);
|
|
242
259
|
}
|
|
243
260
|
const userAgent = request.headers.get("user-agent");
|
|
244
261
|
if (userAgent) {
|
|
245
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
262
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
246
263
|
}
|
|
247
264
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
248
265
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
249
266
|
if (ip) {
|
|
250
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
267
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
251
268
|
}
|
|
252
269
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
253
270
|
if (hutkCookie) {
|
|
254
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
271
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
255
272
|
}
|
|
256
273
|
let uid = requestCookies.get(COOKIE_UID);
|
|
257
274
|
if (!uid) {
|
|
@@ -291,16 +308,16 @@ function processPreprRequest(request, opts) {
|
|
|
291
308
|
if (!isLivePreview) {
|
|
292
309
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
293
310
|
if (segmentCookie) {
|
|
294
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
311
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
295
312
|
}
|
|
296
313
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
297
314
|
if (abCookie) {
|
|
298
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
315
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
299
316
|
}
|
|
300
317
|
}
|
|
301
318
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
302
319
|
if (previewAb !== null) {
|
|
303
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
320
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
304
321
|
if (!isLivePreview) {
|
|
305
322
|
responseCookies.push({
|
|
306
323
|
name: COOKIE_VARIANT,
|
|
@@ -313,7 +330,7 @@ function processPreprRequest(request, opts) {
|
|
|
313
330
|
}
|
|
314
331
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
315
332
|
if (previewSegment !== null) {
|
|
316
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
333
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
317
334
|
if (!isLivePreview) {
|
|
318
335
|
responseCookies.push({
|
|
319
336
|
name: COOKIE_SEGMENT,
|
package/dist/astro/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "0.2.0-beta.
|
|
2
|
+
var VERSION = "0.2.0-beta.6";
|
|
3
3
|
|
|
4
4
|
// src/core/features.ts
|
|
5
5
|
function isEnabled(config) {
|
|
@@ -162,6 +162,11 @@ var UTM_PARAMS = [
|
|
|
162
162
|
"utm_content",
|
|
163
163
|
"utm_campaign"
|
|
164
164
|
];
|
|
165
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
166
|
+
function sanitizeHeaderValue(value) {
|
|
167
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
168
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
169
|
+
}
|
|
165
170
|
function serializeCookie(cookie) {
|
|
166
171
|
const parts = [
|
|
167
172
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -193,6 +198,15 @@ function parseCookies(request) {
|
|
|
193
198
|
function processPreprRequest(request, opts) {
|
|
194
199
|
const requestHeaders = new Headers(request.headers);
|
|
195
200
|
const responseCookies = [];
|
|
201
|
+
const inboundPreprHeaders = [];
|
|
202
|
+
requestHeaders.forEach((_value, key) => {
|
|
203
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
204
|
+
inboundPreprHeaders.push(key);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
for (const key of inboundPreprHeaders) {
|
|
208
|
+
requestHeaders.delete(key);
|
|
209
|
+
}
|
|
196
210
|
const requestCookies = parseCookies(request);
|
|
197
211
|
const url = new URL(request.url);
|
|
198
212
|
const searchParams = url.searchParams;
|
|
@@ -202,25 +216,28 @@ function processPreprRequest(request, opts) {
|
|
|
202
216
|
for (const key of UTM_PARAMS) {
|
|
203
217
|
const value = searchParams.get(key);
|
|
204
218
|
if (value !== null) {
|
|
205
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
219
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
206
220
|
}
|
|
207
221
|
}
|
|
208
222
|
const referer = request.headers.get("referer");
|
|
209
223
|
if (referer) {
|
|
210
|
-
requestHeaders.set(
|
|
224
|
+
requestHeaders.set(
|
|
225
|
+
"Prepr-Context-initial_referral",
|
|
226
|
+
sanitizeHeaderValue(referer)
|
|
227
|
+
);
|
|
211
228
|
}
|
|
212
229
|
const userAgent = request.headers.get("user-agent");
|
|
213
230
|
if (userAgent) {
|
|
214
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
231
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
215
232
|
}
|
|
216
233
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
217
234
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
218
235
|
if (ip) {
|
|
219
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
236
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
220
237
|
}
|
|
221
238
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
222
239
|
if (hutkCookie) {
|
|
223
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
240
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
224
241
|
}
|
|
225
242
|
let uid = requestCookies.get(COOKIE_UID);
|
|
226
243
|
if (!uid) {
|
|
@@ -260,16 +277,16 @@ function processPreprRequest(request, opts) {
|
|
|
260
277
|
if (!isLivePreview) {
|
|
261
278
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
262
279
|
if (segmentCookie) {
|
|
263
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
280
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
264
281
|
}
|
|
265
282
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
266
283
|
if (abCookie) {
|
|
267
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
284
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
268
285
|
}
|
|
269
286
|
}
|
|
270
287
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
271
288
|
if (previewAb !== null) {
|
|
272
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
289
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
273
290
|
if (!isLivePreview) {
|
|
274
291
|
responseCookies.push({
|
|
275
292
|
name: COOKIE_VARIANT,
|
|
@@ -282,7 +299,7 @@ function processPreprRequest(request, opts) {
|
|
|
282
299
|
}
|
|
283
300
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
284
301
|
if (previewSegment !== null) {
|
|
285
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
302
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
286
303
|
if (!isLivePreview) {
|
|
287
304
|
responseCookies.push({
|
|
288
305
|
name: COOKIE_SEGMENT,
|
|
@@ -1394,8 +1394,8 @@ function Panel({
|
|
|
1394
1394
|
"aria-label": t3("common.toolbar"),
|
|
1395
1395
|
children: [
|
|
1396
1396
|
/* @__PURE__ */ u2(Header, { t: t3, onClose: handlers.onClose }),
|
|
1397
|
-
/* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1398
|
-
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children:
|
|
1397
|
+
showAdaptive && /* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1398
|
+
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children: t3("adaptiveContent.adaptiveContent") }),
|
|
1399
1399
|
/* @__PURE__ */ u2("div", { class: "prepr-row", children: [
|
|
1400
1400
|
/* @__PURE__ */ u2("h2", { class: "prepr-row-title", "data-prepr": "preview-label", children: t3("adaptiveContent.enablePreview") }),
|
|
1401
1401
|
/* @__PURE__ */ u2(PreviewSelector, { state, t: t3, handlers })
|
|
@@ -1909,7 +1909,10 @@ function createIframeBridge(store, options = {}) {
|
|
|
1909
1909
|
};
|
|
1910
1910
|
return {
|
|
1911
1911
|
start() {
|
|
1912
|
-
|
|
1912
|
+
const features = store?.get().features;
|
|
1913
|
+
sendPreprEvent("loaded", features ? { features } : void 0, {
|
|
1914
|
+
allowUntrustedTarget: true
|
|
1915
|
+
});
|
|
1913
1916
|
window.addEventListener("keydown", onKeyDown);
|
|
1914
1917
|
window.addEventListener("message", onMessage);
|
|
1915
1918
|
},
|
|
@@ -2026,6 +2029,14 @@ function defaultNavigation() {
|
|
|
2026
2029
|
currentPath: () => window.location.pathname + window.location.search
|
|
2027
2030
|
};
|
|
2028
2031
|
}
|
|
2032
|
+
function safeEditUrl(href) {
|
|
2033
|
+
try {
|
|
2034
|
+
const url = new URL(href, window.location.href);
|
|
2035
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2036
|
+
} catch {
|
|
2037
|
+
return null;
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2029
2040
|
function buildSegments(data) {
|
|
2030
2041
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2031
2042
|
}
|
|
@@ -2089,10 +2100,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2089
2100
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2090
2101
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2091
2102
|
onEdit: ({ href, origin, id, field }) => {
|
|
2103
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2104
|
+
if (href && !safeHref) {
|
|
2105
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2092
2108
|
if (isIframe) {
|
|
2093
|
-
sendPreprEvent("field_edit_requested", {
|
|
2094
|
-
|
|
2095
|
-
|
|
2109
|
+
sendPreprEvent("field_edit_requested", {
|
|
2110
|
+
href: safeHref ?? void 0,
|
|
2111
|
+
origin,
|
|
2112
|
+
id,
|
|
2113
|
+
field
|
|
2114
|
+
});
|
|
2115
|
+
} else if (safeHref) {
|
|
2116
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2096
2117
|
}
|
|
2097
2118
|
}
|
|
2098
2119
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -44,7 +44,7 @@ __export(src_exports, {
|
|
|
44
44
|
module.exports = __toCommonJS(src_exports);
|
|
45
45
|
|
|
46
46
|
// src/version.ts
|
|
47
|
-
var VERSION = "0.2.0-beta.
|
|
47
|
+
var VERSION = "0.2.0-beta.6";
|
|
48
48
|
|
|
49
49
|
// src/core/features.ts
|
|
50
50
|
function isEnabled(config) {
|
|
@@ -355,7 +355,10 @@ function createIframeBridge(store, options = {}) {
|
|
|
355
355
|
};
|
|
356
356
|
return {
|
|
357
357
|
start() {
|
|
358
|
-
|
|
358
|
+
const features = store?.get().features;
|
|
359
|
+
sendPreprEvent("loaded", features ? { features } : void 0, {
|
|
360
|
+
allowUntrustedTarget: true
|
|
361
|
+
});
|
|
359
362
|
window.addEventListener("keydown", onKeyDown);
|
|
360
363
|
window.addEventListener("message", onMessage);
|
|
361
364
|
},
|
|
@@ -1736,8 +1739,8 @@ function Panel({
|
|
|
1736
1739
|
"aria-label": t3("common.toolbar"),
|
|
1737
1740
|
children: [
|
|
1738
1741
|
/* @__PURE__ */ u2(Header, { t: t3, onClose: handlers.onClose }),
|
|
1739
|
-
/* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1740
|
-
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children:
|
|
1742
|
+
showAdaptive && /* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1743
|
+
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children: t3("adaptiveContent.adaptiveContent") }),
|
|
1741
1744
|
/* @__PURE__ */ u2("div", { class: "prepr-row", children: [
|
|
1742
1745
|
/* @__PURE__ */ u2("h2", { class: "prepr-row-title", "data-prepr": "preview-label", children: t3("adaptiveContent.enablePreview") }),
|
|
1743
1746
|
/* @__PURE__ */ u2(PreviewSelector, { state, t: t3, handlers })
|
|
@@ -2074,6 +2077,14 @@ function defaultNavigation() {
|
|
|
2074
2077
|
currentPath: () => window.location.pathname + window.location.search
|
|
2075
2078
|
};
|
|
2076
2079
|
}
|
|
2080
|
+
function safeEditUrl(href) {
|
|
2081
|
+
try {
|
|
2082
|
+
const url = new URL(href, window.location.href);
|
|
2083
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2084
|
+
} catch {
|
|
2085
|
+
return null;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2077
2088
|
function buildSegments(data) {
|
|
2078
2089
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2079
2090
|
}
|
|
@@ -2137,10 +2148,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2137
2148
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2138
2149
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2139
2150
|
onEdit: ({ href, origin, id, field }) => {
|
|
2151
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2152
|
+
if (href && !safeHref) {
|
|
2153
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2154
|
+
return;
|
|
2155
|
+
}
|
|
2140
2156
|
if (isIframe) {
|
|
2141
|
-
sendPreprEvent("field_edit_requested", {
|
|
2142
|
-
|
|
2143
|
-
|
|
2157
|
+
sendPreprEvent("field_edit_requested", {
|
|
2158
|
+
href: safeHref ?? void 0,
|
|
2159
|
+
origin,
|
|
2160
|
+
id,
|
|
2161
|
+
field
|
|
2162
|
+
});
|
|
2163
|
+
} else if (safeHref) {
|
|
2164
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2144
2165
|
}
|
|
2145
2166
|
}
|
|
2146
2167
|
});
|
|
@@ -2358,6 +2379,11 @@ var UTM_PARAMS = [
|
|
|
2358
2379
|
"utm_content",
|
|
2359
2380
|
"utm_campaign"
|
|
2360
2381
|
];
|
|
2382
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
2383
|
+
function sanitizeHeaderValue(value) {
|
|
2384
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
2385
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
2386
|
+
}
|
|
2361
2387
|
function parseCookies(request) {
|
|
2362
2388
|
const cookies = /* @__PURE__ */ new Map();
|
|
2363
2389
|
const header = request.headers.get("cookie");
|
|
@@ -2375,6 +2401,15 @@ function parseCookies(request) {
|
|
|
2375
2401
|
function processPreprRequest(request, opts) {
|
|
2376
2402
|
const requestHeaders = new Headers(request.headers);
|
|
2377
2403
|
const responseCookies = [];
|
|
2404
|
+
const inboundPreprHeaders = [];
|
|
2405
|
+
requestHeaders.forEach((_value, key) => {
|
|
2406
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
2407
|
+
inboundPreprHeaders.push(key);
|
|
2408
|
+
}
|
|
2409
|
+
});
|
|
2410
|
+
for (const key of inboundPreprHeaders) {
|
|
2411
|
+
requestHeaders.delete(key);
|
|
2412
|
+
}
|
|
2378
2413
|
const requestCookies = parseCookies(request);
|
|
2379
2414
|
const url = new URL(request.url);
|
|
2380
2415
|
const searchParams = url.searchParams;
|
|
@@ -2384,25 +2419,28 @@ function processPreprRequest(request, opts) {
|
|
|
2384
2419
|
for (const key of UTM_PARAMS) {
|
|
2385
2420
|
const value = searchParams.get(key);
|
|
2386
2421
|
if (value !== null) {
|
|
2387
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
2422
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
2388
2423
|
}
|
|
2389
2424
|
}
|
|
2390
2425
|
const referer = request.headers.get("referer");
|
|
2391
2426
|
if (referer) {
|
|
2392
|
-
requestHeaders.set(
|
|
2427
|
+
requestHeaders.set(
|
|
2428
|
+
"Prepr-Context-initial_referral",
|
|
2429
|
+
sanitizeHeaderValue(referer)
|
|
2430
|
+
);
|
|
2393
2431
|
}
|
|
2394
2432
|
const userAgent = request.headers.get("user-agent");
|
|
2395
2433
|
if (userAgent) {
|
|
2396
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
2434
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
2397
2435
|
}
|
|
2398
2436
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
2399
2437
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
2400
2438
|
if (ip) {
|
|
2401
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
2439
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
2402
2440
|
}
|
|
2403
2441
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
2404
2442
|
if (hutkCookie) {
|
|
2405
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
2443
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
2406
2444
|
}
|
|
2407
2445
|
let uid = requestCookies.get(COOKIE_UID);
|
|
2408
2446
|
if (!uid) {
|
|
@@ -2442,16 +2480,16 @@ function processPreprRequest(request, opts) {
|
|
|
2442
2480
|
if (!isLivePreview) {
|
|
2443
2481
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
2444
2482
|
if (segmentCookie) {
|
|
2445
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
2483
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
2446
2484
|
}
|
|
2447
2485
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
2448
2486
|
if (abCookie) {
|
|
2449
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
2487
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
2450
2488
|
}
|
|
2451
2489
|
}
|
|
2452
2490
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
2453
2491
|
if (previewAb !== null) {
|
|
2454
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
2492
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
2455
2493
|
if (!isLivePreview) {
|
|
2456
2494
|
responseCookies.push({
|
|
2457
2495
|
name: COOKIE_VARIANT,
|
|
@@ -2464,7 +2502,7 @@ function processPreprRequest(request, opts) {
|
|
|
2464
2502
|
}
|
|
2465
2503
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
2466
2504
|
if (previewSegment !== null) {
|
|
2467
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
2505
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
2468
2506
|
if (!isLivePreview) {
|
|
2469
2507
|
responseCookies.push({
|
|
2470
2508
|
name: COOKIE_SEGMENT,
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j
|
|
|
5
5
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
6
6
|
* core can import it without cycling through the barrel.
|
|
7
7
|
*/
|
|
8
|
-
declare const VERSION = "0.2.0-beta.
|
|
8
|
+
declare const VERSION = "0.2.0-beta.6";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j
|
|
|
5
5
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
6
6
|
* core can import it without cycling through the barrel.
|
|
7
7
|
*/
|
|
8
|
-
declare const VERSION = "0.2.0-beta.
|
|
8
|
+
declare const VERSION = "0.2.0-beta.6";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
|
package/dist/index.js
CHANGED
|
@@ -17,10 +17,10 @@ import {
|
|
|
17
17
|
setTrackingParam,
|
|
18
18
|
stegaClean,
|
|
19
19
|
trackEvent
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-C6YEXA5G.js";
|
|
21
21
|
|
|
22
22
|
// src/version.ts
|
|
23
|
-
var VERSION = "0.2.0-beta.
|
|
23
|
+
var VERSION = "0.2.0-beta.6";
|
|
24
24
|
|
|
25
25
|
// src/core/server.ts
|
|
26
26
|
var PreprError = class extends Error {
|
|
@@ -184,6 +184,11 @@ var UTM_PARAMS = [
|
|
|
184
184
|
"utm_content",
|
|
185
185
|
"utm_campaign"
|
|
186
186
|
];
|
|
187
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
188
|
+
function sanitizeHeaderValue(value) {
|
|
189
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
190
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
191
|
+
}
|
|
187
192
|
function parseCookies(request) {
|
|
188
193
|
const cookies = /* @__PURE__ */ new Map();
|
|
189
194
|
const header = request.headers.get("cookie");
|
|
@@ -201,6 +206,15 @@ function parseCookies(request) {
|
|
|
201
206
|
function processPreprRequest(request, opts) {
|
|
202
207
|
const requestHeaders = new Headers(request.headers);
|
|
203
208
|
const responseCookies = [];
|
|
209
|
+
const inboundPreprHeaders = [];
|
|
210
|
+
requestHeaders.forEach((_value, key) => {
|
|
211
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
212
|
+
inboundPreprHeaders.push(key);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
for (const key of inboundPreprHeaders) {
|
|
216
|
+
requestHeaders.delete(key);
|
|
217
|
+
}
|
|
204
218
|
const requestCookies = parseCookies(request);
|
|
205
219
|
const url = new URL(request.url);
|
|
206
220
|
const searchParams = url.searchParams;
|
|
@@ -210,25 +224,28 @@ function processPreprRequest(request, opts) {
|
|
|
210
224
|
for (const key of UTM_PARAMS) {
|
|
211
225
|
const value = searchParams.get(key);
|
|
212
226
|
if (value !== null) {
|
|
213
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
227
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
214
228
|
}
|
|
215
229
|
}
|
|
216
230
|
const referer = request.headers.get("referer");
|
|
217
231
|
if (referer) {
|
|
218
|
-
requestHeaders.set(
|
|
232
|
+
requestHeaders.set(
|
|
233
|
+
"Prepr-Context-initial_referral",
|
|
234
|
+
sanitizeHeaderValue(referer)
|
|
235
|
+
);
|
|
219
236
|
}
|
|
220
237
|
const userAgent = request.headers.get("user-agent");
|
|
221
238
|
if (userAgent) {
|
|
222
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
239
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
223
240
|
}
|
|
224
241
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
225
242
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
226
243
|
if (ip) {
|
|
227
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
244
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
228
245
|
}
|
|
229
246
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
230
247
|
if (hutkCookie) {
|
|
231
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
248
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
232
249
|
}
|
|
233
250
|
let uid = requestCookies.get(COOKIE_UID);
|
|
234
251
|
if (!uid) {
|
|
@@ -268,16 +285,16 @@ function processPreprRequest(request, opts) {
|
|
|
268
285
|
if (!isLivePreview) {
|
|
269
286
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
270
287
|
if (segmentCookie) {
|
|
271
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
288
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
272
289
|
}
|
|
273
290
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
274
291
|
if (abCookie) {
|
|
275
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
292
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
276
293
|
}
|
|
277
294
|
}
|
|
278
295
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
279
296
|
if (previewAb !== null) {
|
|
280
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
297
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
281
298
|
if (!isLivePreview) {
|
|
282
299
|
responseCookies.push({
|
|
283
300
|
name: COOKIE_VARIANT,
|
|
@@ -290,7 +307,7 @@ function processPreprRequest(request, opts) {
|
|
|
290
307
|
}
|
|
291
308
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
292
309
|
if (previewSegment !== null) {
|
|
293
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
310
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
294
311
|
if (!isLivePreview) {
|
|
295
312
|
responseCookies.push({
|
|
296
313
|
name: COOKIE_SEGMENT,
|
|
@@ -335,7 +335,10 @@ function createIframeBridge(store, options = {}) {
|
|
|
335
335
|
};
|
|
336
336
|
return {
|
|
337
337
|
start() {
|
|
338
|
-
|
|
338
|
+
const features = store?.get().features;
|
|
339
|
+
sendPreprEvent("loaded", features ? { features } : void 0, {
|
|
340
|
+
allowUntrustedTarget: true
|
|
341
|
+
});
|
|
339
342
|
window.addEventListener("keydown", onKeyDown);
|
|
340
343
|
window.addEventListener("message", onMessage);
|
|
341
344
|
},
|
|
@@ -1712,8 +1715,8 @@ function Panel({
|
|
|
1712
1715
|
"aria-label": t3("common.toolbar"),
|
|
1713
1716
|
children: [
|
|
1714
1717
|
/* @__PURE__ */ u2(Header, { t: t3, onClose: handlers.onClose }),
|
|
1715
|
-
/* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1716
|
-
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children:
|
|
1718
|
+
showAdaptive && /* @__PURE__ */ u2("div", { class: "prepr-section", "data-prepr": "section-adaptive", children: [
|
|
1719
|
+
/* @__PURE__ */ u2("span", { class: "prepr-section-label", "data-prepr": "adaptive-label", children: t3("adaptiveContent.adaptiveContent") }),
|
|
1717
1720
|
/* @__PURE__ */ u2("div", { class: "prepr-row", children: [
|
|
1718
1721
|
/* @__PURE__ */ u2("h2", { class: "prepr-row-title", "data-prepr": "preview-label", children: t3("adaptiveContent.enablePreview") }),
|
|
1719
1722
|
/* @__PURE__ */ u2(PreviewSelector, { state, t: t3, handlers })
|
|
@@ -2050,6 +2053,14 @@ function defaultNavigation() {
|
|
|
2050
2053
|
currentPath: () => window.location.pathname + window.location.search
|
|
2051
2054
|
};
|
|
2052
2055
|
}
|
|
2056
|
+
function safeEditUrl(href) {
|
|
2057
|
+
try {
|
|
2058
|
+
const url = new URL(href, window.location.href);
|
|
2059
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2060
|
+
} catch {
|
|
2061
|
+
return null;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2053
2064
|
function buildSegments(data) {
|
|
2054
2065
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2055
2066
|
}
|
|
@@ -2113,10 +2124,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2113
2124
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2114
2125
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2115
2126
|
onEdit: ({ href, origin, id, field }) => {
|
|
2127
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2128
|
+
if (href && !safeHref) {
|
|
2129
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2116
2132
|
if (isIframe) {
|
|
2117
|
-
sendPreprEvent("field_edit_requested", {
|
|
2118
|
-
|
|
2119
|
-
|
|
2133
|
+
sendPreprEvent("field_edit_requested", {
|
|
2134
|
+
href: safeHref ?? void 0,
|
|
2135
|
+
origin,
|
|
2136
|
+
id,
|
|
2137
|
+
field
|
|
2138
|
+
});
|
|
2139
|
+
} else if (safeHref) {
|
|
2140
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2120
2141
|
}
|
|
2121
2142
|
}
|
|
2122
2143
|
});
|