@preprio/toolkit 0.2.0-beta.5 → 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-BYJ2JBGX.js → chunk-C6YEXA5G.js} +25 -4
- package/dist/index.cjs +52 -14
- 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 +25 -4
- 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 +25 -4
- package/dist/react/components.js +25 -4
- 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,
|
|
@@ -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
|
},
|
|
@@ -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
|
},
|
|
@@ -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
|
});
|
package/dist/nextjs/index.cjs
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(nextjs_exports);
|
|
|
38
38
|
var import_server = require("next/server");
|
|
39
39
|
|
|
40
40
|
// src/version.ts
|
|
41
|
-
var VERSION = "0.2.0-beta.
|
|
41
|
+
var VERSION = "0.2.0-beta.6";
|
|
42
42
|
|
|
43
43
|
// src/core/constants.ts
|
|
44
44
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -77,6 +77,11 @@ var UTM_PARAMS = [
|
|
|
77
77
|
"utm_content",
|
|
78
78
|
"utm_campaign"
|
|
79
79
|
];
|
|
80
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
81
|
+
function sanitizeHeaderValue(value) {
|
|
82
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
83
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
84
|
+
}
|
|
80
85
|
function parseCookies(request) {
|
|
81
86
|
const cookies = /* @__PURE__ */ new Map();
|
|
82
87
|
const header = request.headers.get("cookie");
|
|
@@ -94,6 +99,15 @@ function parseCookies(request) {
|
|
|
94
99
|
function processPreprRequest(request, opts) {
|
|
95
100
|
const requestHeaders = new Headers(request.headers);
|
|
96
101
|
const responseCookies = [];
|
|
102
|
+
const inboundPreprHeaders = [];
|
|
103
|
+
requestHeaders.forEach((_value, key) => {
|
|
104
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
105
|
+
inboundPreprHeaders.push(key);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
for (const key of inboundPreprHeaders) {
|
|
109
|
+
requestHeaders.delete(key);
|
|
110
|
+
}
|
|
97
111
|
const requestCookies = parseCookies(request);
|
|
98
112
|
const url = new URL(request.url);
|
|
99
113
|
const searchParams = url.searchParams;
|
|
@@ -103,25 +117,28 @@ function processPreprRequest(request, opts) {
|
|
|
103
117
|
for (const key of UTM_PARAMS) {
|
|
104
118
|
const value = searchParams.get(key);
|
|
105
119
|
if (value !== null) {
|
|
106
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
120
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
const referer = request.headers.get("referer");
|
|
110
124
|
if (referer) {
|
|
111
|
-
requestHeaders.set(
|
|
125
|
+
requestHeaders.set(
|
|
126
|
+
"Prepr-Context-initial_referral",
|
|
127
|
+
sanitizeHeaderValue(referer)
|
|
128
|
+
);
|
|
112
129
|
}
|
|
113
130
|
const userAgent = request.headers.get("user-agent");
|
|
114
131
|
if (userAgent) {
|
|
115
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
132
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
116
133
|
}
|
|
117
134
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
118
135
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
119
136
|
if (ip) {
|
|
120
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
137
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
121
138
|
}
|
|
122
139
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
123
140
|
if (hutkCookie) {
|
|
124
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
141
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
125
142
|
}
|
|
126
143
|
let uid = requestCookies.get(COOKIE_UID);
|
|
127
144
|
if (!uid) {
|
|
@@ -161,16 +178,16 @@ function processPreprRequest(request, opts) {
|
|
|
161
178
|
if (!isLivePreview) {
|
|
162
179
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
163
180
|
if (segmentCookie) {
|
|
164
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
181
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
165
182
|
}
|
|
166
183
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
167
184
|
if (abCookie) {
|
|
168
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
185
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
169
186
|
}
|
|
170
187
|
}
|
|
171
188
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
172
189
|
if (previewAb !== null) {
|
|
173
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
190
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
174
191
|
if (!isLivePreview) {
|
|
175
192
|
responseCookies.push({
|
|
176
193
|
name: COOKIE_VARIANT,
|
|
@@ -183,7 +200,7 @@ function processPreprRequest(request, opts) {
|
|
|
183
200
|
}
|
|
184
201
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
185
202
|
if (previewSegment !== null) {
|
|
186
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
203
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
187
204
|
if (!isLivePreview) {
|
|
188
205
|
responseCookies.push({
|
|
189
206
|
name: COOKIE_SEGMENT,
|
package/dist/nextjs/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
|
|
4
4
|
// src/version.ts
|
|
5
|
-
var VERSION = "0.2.0-beta.
|
|
5
|
+
var VERSION = "0.2.0-beta.6";
|
|
6
6
|
|
|
7
7
|
// src/core/constants.ts
|
|
8
8
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -41,6 +41,11 @@ var UTM_PARAMS = [
|
|
|
41
41
|
"utm_content",
|
|
42
42
|
"utm_campaign"
|
|
43
43
|
];
|
|
44
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
45
|
+
function sanitizeHeaderValue(value) {
|
|
46
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
47
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
48
|
+
}
|
|
44
49
|
function parseCookies(request) {
|
|
45
50
|
const cookies = /* @__PURE__ */ new Map();
|
|
46
51
|
const header = request.headers.get("cookie");
|
|
@@ -58,6 +63,15 @@ function parseCookies(request) {
|
|
|
58
63
|
function processPreprRequest(request, opts) {
|
|
59
64
|
const requestHeaders = new Headers(request.headers);
|
|
60
65
|
const responseCookies = [];
|
|
66
|
+
const inboundPreprHeaders = [];
|
|
67
|
+
requestHeaders.forEach((_value, key) => {
|
|
68
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
69
|
+
inboundPreprHeaders.push(key);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
for (const key of inboundPreprHeaders) {
|
|
73
|
+
requestHeaders.delete(key);
|
|
74
|
+
}
|
|
61
75
|
const requestCookies = parseCookies(request);
|
|
62
76
|
const url = new URL(request.url);
|
|
63
77
|
const searchParams = url.searchParams;
|
|
@@ -67,25 +81,28 @@ function processPreprRequest(request, opts) {
|
|
|
67
81
|
for (const key of UTM_PARAMS) {
|
|
68
82
|
const value = searchParams.get(key);
|
|
69
83
|
if (value !== null) {
|
|
70
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
84
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
71
85
|
}
|
|
72
86
|
}
|
|
73
87
|
const referer = request.headers.get("referer");
|
|
74
88
|
if (referer) {
|
|
75
|
-
requestHeaders.set(
|
|
89
|
+
requestHeaders.set(
|
|
90
|
+
"Prepr-Context-initial_referral",
|
|
91
|
+
sanitizeHeaderValue(referer)
|
|
92
|
+
);
|
|
76
93
|
}
|
|
77
94
|
const userAgent = request.headers.get("user-agent");
|
|
78
95
|
if (userAgent) {
|
|
79
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
96
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
80
97
|
}
|
|
81
98
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
82
99
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
83
100
|
if (ip) {
|
|
84
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
101
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
85
102
|
}
|
|
86
103
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
87
104
|
if (hutkCookie) {
|
|
88
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
105
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
89
106
|
}
|
|
90
107
|
let uid = requestCookies.get(COOKIE_UID);
|
|
91
108
|
if (!uid) {
|
|
@@ -125,16 +142,16 @@ function processPreprRequest(request, opts) {
|
|
|
125
142
|
if (!isLivePreview) {
|
|
126
143
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
127
144
|
if (segmentCookie) {
|
|
128
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
145
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
129
146
|
}
|
|
130
147
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
131
148
|
if (abCookie) {
|
|
132
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
149
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
133
150
|
}
|
|
134
151
|
}
|
|
135
152
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
136
153
|
if (previewAb !== null) {
|
|
137
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
154
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
138
155
|
if (!isLivePreview) {
|
|
139
156
|
responseCookies.push({
|
|
140
157
|
name: COOKIE_VARIANT,
|
|
@@ -147,7 +164,7 @@ function processPreprRequest(request, opts) {
|
|
|
147
164
|
}
|
|
148
165
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
149
166
|
if (previewSegment !== null) {
|
|
150
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
167
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
151
168
|
if (!isLivePreview) {
|
|
152
169
|
responseCookies.push({
|
|
153
170
|
name: COOKIE_SEGMENT,
|
package/dist/nuxt/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(nuxt_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(nuxt_exports);
|
|
36
36
|
|
|
37
37
|
// src/version.ts
|
|
38
|
-
var VERSION = "0.2.0-beta.
|
|
38
|
+
var VERSION = "0.2.0-beta.6";
|
|
39
39
|
|
|
40
40
|
// src/core/constants.ts
|
|
41
41
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -74,6 +74,11 @@ var UTM_PARAMS = [
|
|
|
74
74
|
"utm_content",
|
|
75
75
|
"utm_campaign"
|
|
76
76
|
];
|
|
77
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
78
|
+
function sanitizeHeaderValue(value) {
|
|
79
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
80
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
81
|
+
}
|
|
77
82
|
function serializeCookie(cookie) {
|
|
78
83
|
const parts = [
|
|
79
84
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -105,6 +110,15 @@ function parseCookies(request) {
|
|
|
105
110
|
function processPreprRequest(request, opts) {
|
|
106
111
|
const requestHeaders = new Headers(request.headers);
|
|
107
112
|
const responseCookies = [];
|
|
113
|
+
const inboundPreprHeaders = [];
|
|
114
|
+
requestHeaders.forEach((_value, key) => {
|
|
115
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
116
|
+
inboundPreprHeaders.push(key);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
for (const key of inboundPreprHeaders) {
|
|
120
|
+
requestHeaders.delete(key);
|
|
121
|
+
}
|
|
108
122
|
const requestCookies = parseCookies(request);
|
|
109
123
|
const url = new URL(request.url);
|
|
110
124
|
const searchParams = url.searchParams;
|
|
@@ -114,25 +128,28 @@ function processPreprRequest(request, opts) {
|
|
|
114
128
|
for (const key of UTM_PARAMS) {
|
|
115
129
|
const value = searchParams.get(key);
|
|
116
130
|
if (value !== null) {
|
|
117
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
131
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
118
132
|
}
|
|
119
133
|
}
|
|
120
134
|
const referer = request.headers.get("referer");
|
|
121
135
|
if (referer) {
|
|
122
|
-
requestHeaders.set(
|
|
136
|
+
requestHeaders.set(
|
|
137
|
+
"Prepr-Context-initial_referral",
|
|
138
|
+
sanitizeHeaderValue(referer)
|
|
139
|
+
);
|
|
123
140
|
}
|
|
124
141
|
const userAgent = request.headers.get("user-agent");
|
|
125
142
|
if (userAgent) {
|
|
126
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
143
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
127
144
|
}
|
|
128
145
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
129
146
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
130
147
|
if (ip) {
|
|
131
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
148
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
132
149
|
}
|
|
133
150
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
134
151
|
if (hutkCookie) {
|
|
135
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
152
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
136
153
|
}
|
|
137
154
|
let uid = requestCookies.get(COOKIE_UID);
|
|
138
155
|
if (!uid) {
|
|
@@ -172,16 +189,16 @@ function processPreprRequest(request, opts) {
|
|
|
172
189
|
if (!isLivePreview) {
|
|
173
190
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
174
191
|
if (segmentCookie) {
|
|
175
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
192
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
176
193
|
}
|
|
177
194
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
178
195
|
if (abCookie) {
|
|
179
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
196
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
180
197
|
}
|
|
181
198
|
}
|
|
182
199
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
183
200
|
if (previewAb !== null) {
|
|
184
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
201
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
185
202
|
if (!isLivePreview) {
|
|
186
203
|
responseCookies.push({
|
|
187
204
|
name: COOKIE_VARIANT,
|
|
@@ -194,7 +211,7 @@ function processPreprRequest(request, opts) {
|
|
|
194
211
|
}
|
|
195
212
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
196
213
|
if (previewSegment !== null) {
|
|
197
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
214
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
198
215
|
if (!isLivePreview) {
|
|
199
216
|
responseCookies.push({
|
|
200
217
|
name: COOKIE_SEGMENT,
|
package/dist/nuxt/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/constants.ts
|
|
5
5
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -38,6 +38,11 @@ var UTM_PARAMS = [
|
|
|
38
38
|
"utm_content",
|
|
39
39
|
"utm_campaign"
|
|
40
40
|
];
|
|
41
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
42
|
+
function sanitizeHeaderValue(value) {
|
|
43
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
44
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
45
|
+
}
|
|
41
46
|
function serializeCookie(cookie) {
|
|
42
47
|
const parts = [
|
|
43
48
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -69,6 +74,15 @@ function parseCookies(request) {
|
|
|
69
74
|
function processPreprRequest(request, opts) {
|
|
70
75
|
const requestHeaders = new Headers(request.headers);
|
|
71
76
|
const responseCookies = [];
|
|
77
|
+
const inboundPreprHeaders = [];
|
|
78
|
+
requestHeaders.forEach((_value, key) => {
|
|
79
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
80
|
+
inboundPreprHeaders.push(key);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
for (const key of inboundPreprHeaders) {
|
|
84
|
+
requestHeaders.delete(key);
|
|
85
|
+
}
|
|
72
86
|
const requestCookies = parseCookies(request);
|
|
73
87
|
const url = new URL(request.url);
|
|
74
88
|
const searchParams = url.searchParams;
|
|
@@ -78,25 +92,28 @@ function processPreprRequest(request, opts) {
|
|
|
78
92
|
for (const key of UTM_PARAMS) {
|
|
79
93
|
const value = searchParams.get(key);
|
|
80
94
|
if (value !== null) {
|
|
81
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
95
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
const referer = request.headers.get("referer");
|
|
85
99
|
if (referer) {
|
|
86
|
-
requestHeaders.set(
|
|
100
|
+
requestHeaders.set(
|
|
101
|
+
"Prepr-Context-initial_referral",
|
|
102
|
+
sanitizeHeaderValue(referer)
|
|
103
|
+
);
|
|
87
104
|
}
|
|
88
105
|
const userAgent = request.headers.get("user-agent");
|
|
89
106
|
if (userAgent) {
|
|
90
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
107
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
91
108
|
}
|
|
92
109
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
93
110
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
94
111
|
if (ip) {
|
|
95
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
112
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
96
113
|
}
|
|
97
114
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
98
115
|
if (hutkCookie) {
|
|
99
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
116
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
100
117
|
}
|
|
101
118
|
let uid = requestCookies.get(COOKIE_UID);
|
|
102
119
|
if (!uid) {
|
|
@@ -136,16 +153,16 @@ function processPreprRequest(request, opts) {
|
|
|
136
153
|
if (!isLivePreview) {
|
|
137
154
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
138
155
|
if (segmentCookie) {
|
|
139
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
156
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
140
157
|
}
|
|
141
158
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
142
159
|
if (abCookie) {
|
|
143
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
160
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
144
161
|
}
|
|
145
162
|
}
|
|
146
163
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
147
164
|
if (previewAb !== null) {
|
|
148
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
165
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
149
166
|
if (!isLivePreview) {
|
|
150
167
|
responseCookies.push({
|
|
151
168
|
name: COOKIE_VARIANT,
|
|
@@ -158,7 +175,7 @@ function processPreprRequest(request, opts) {
|
|
|
158
175
|
}
|
|
159
176
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
160
177
|
if (previewSegment !== null) {
|
|
161
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
178
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
162
179
|
if (!isLivePreview) {
|
|
163
180
|
responseCookies.push({
|
|
164
181
|
name: COOKIE_SEGMENT,
|
|
@@ -334,7 +334,10 @@ function createIframeBridge(store, options = {}) {
|
|
|
334
334
|
};
|
|
335
335
|
return {
|
|
336
336
|
start() {
|
|
337
|
-
|
|
337
|
+
const features = store?.get().features;
|
|
338
|
+
sendPreprEvent("loaded", features ? { features } : void 0, {
|
|
339
|
+
allowUntrustedTarget: true
|
|
340
|
+
});
|
|
338
341
|
window.addEventListener("keydown", onKeyDown);
|
|
339
342
|
window.addEventListener("message", onMessage);
|
|
340
343
|
},
|
|
@@ -2049,6 +2052,14 @@ function defaultNavigation() {
|
|
|
2049
2052
|
currentPath: () => window.location.pathname + window.location.search
|
|
2050
2053
|
};
|
|
2051
2054
|
}
|
|
2055
|
+
function safeEditUrl(href) {
|
|
2056
|
+
try {
|
|
2057
|
+
const url = new URL(href, window.location.href);
|
|
2058
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2059
|
+
} catch {
|
|
2060
|
+
return null;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2052
2063
|
function buildSegments(data) {
|
|
2053
2064
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2054
2065
|
}
|
|
@@ -2112,10 +2123,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2112
2123
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2113
2124
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2114
2125
|
onEdit: ({ href, origin, id, field }) => {
|
|
2126
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2127
|
+
if (href && !safeHref) {
|
|
2128
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2115
2131
|
if (isIframe) {
|
|
2116
|
-
sendPreprEvent("field_edit_requested", {
|
|
2117
|
-
|
|
2118
|
-
|
|
2132
|
+
sendPreprEvent("field_edit_requested", {
|
|
2133
|
+
href: safeHref ?? void 0,
|
|
2134
|
+
origin,
|
|
2135
|
+
id,
|
|
2136
|
+
field
|
|
2137
|
+
});
|
|
2138
|
+
} else if (safeHref) {
|
|
2139
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2119
2140
|
}
|
|
2120
2141
|
}
|
|
2121
2142
|
});
|
package/dist/react/components.js
CHANGED
|
@@ -310,7 +310,10 @@ function createIframeBridge(store, options = {}) {
|
|
|
310
310
|
};
|
|
311
311
|
return {
|
|
312
312
|
start() {
|
|
313
|
-
|
|
313
|
+
const features = store?.get().features;
|
|
314
|
+
sendPreprEvent("loaded", features ? { features } : void 0, {
|
|
315
|
+
allowUntrustedTarget: true
|
|
316
|
+
});
|
|
314
317
|
window.addEventListener("keydown", onKeyDown);
|
|
315
318
|
window.addEventListener("message", onMessage);
|
|
316
319
|
},
|
|
@@ -2025,6 +2028,14 @@ function defaultNavigation() {
|
|
|
2025
2028
|
currentPath: () => window.location.pathname + window.location.search
|
|
2026
2029
|
};
|
|
2027
2030
|
}
|
|
2031
|
+
function safeEditUrl(href) {
|
|
2032
|
+
try {
|
|
2033
|
+
const url = new URL(href, window.location.href);
|
|
2034
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2035
|
+
} catch {
|
|
2036
|
+
return null;
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2028
2039
|
function buildSegments(data) {
|
|
2029
2040
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2030
2041
|
}
|
|
@@ -2088,10 +2099,20 @@ function createPreprPreview(opts = {}) {
|
|
|
2088
2099
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2089
2100
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2090
2101
|
onEdit: ({ href, origin, id, field }) => {
|
|
2102
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2103
|
+
if (href && !safeHref) {
|
|
2104
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2091
2107
|
if (isIframe) {
|
|
2092
|
-
sendPreprEvent("field_edit_requested", {
|
|
2093
|
-
|
|
2094
|
-
|
|
2108
|
+
sendPreprEvent("field_edit_requested", {
|
|
2109
|
+
href: safeHref ?? void 0,
|
|
2110
|
+
origin,
|
|
2111
|
+
id,
|
|
2112
|
+
field
|
|
2113
|
+
});
|
|
2114
|
+
} else if (safeHref) {
|
|
2115
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2095
2116
|
}
|
|
2096
2117
|
}
|
|
2097
2118
|
});
|
package/dist/sveltekit/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(sveltekit_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(sveltekit_exports);
|
|
36
36
|
|
|
37
37
|
// src/version.ts
|
|
38
|
-
var VERSION = "0.2.0-beta.
|
|
38
|
+
var VERSION = "0.2.0-beta.6";
|
|
39
39
|
|
|
40
40
|
// src/core/constants.ts
|
|
41
41
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -74,6 +74,11 @@ var UTM_PARAMS = [
|
|
|
74
74
|
"utm_content",
|
|
75
75
|
"utm_campaign"
|
|
76
76
|
];
|
|
77
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
78
|
+
function sanitizeHeaderValue(value) {
|
|
79
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
80
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
81
|
+
}
|
|
77
82
|
function serializeCookie(cookie) {
|
|
78
83
|
const parts = [
|
|
79
84
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -105,6 +110,15 @@ function parseCookies(request) {
|
|
|
105
110
|
function processPreprRequest(request, opts) {
|
|
106
111
|
const requestHeaders = new Headers(request.headers);
|
|
107
112
|
const responseCookies = [];
|
|
113
|
+
const inboundPreprHeaders = [];
|
|
114
|
+
requestHeaders.forEach((_value, key) => {
|
|
115
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
116
|
+
inboundPreprHeaders.push(key);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
for (const key of inboundPreprHeaders) {
|
|
120
|
+
requestHeaders.delete(key);
|
|
121
|
+
}
|
|
108
122
|
const requestCookies = parseCookies(request);
|
|
109
123
|
const url = new URL(request.url);
|
|
110
124
|
const searchParams = url.searchParams;
|
|
@@ -114,25 +128,28 @@ function processPreprRequest(request, opts) {
|
|
|
114
128
|
for (const key of UTM_PARAMS) {
|
|
115
129
|
const value = searchParams.get(key);
|
|
116
130
|
if (value !== null) {
|
|
117
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
131
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
118
132
|
}
|
|
119
133
|
}
|
|
120
134
|
const referer = request.headers.get("referer");
|
|
121
135
|
if (referer) {
|
|
122
|
-
requestHeaders.set(
|
|
136
|
+
requestHeaders.set(
|
|
137
|
+
"Prepr-Context-initial_referral",
|
|
138
|
+
sanitizeHeaderValue(referer)
|
|
139
|
+
);
|
|
123
140
|
}
|
|
124
141
|
const userAgent = request.headers.get("user-agent");
|
|
125
142
|
if (userAgent) {
|
|
126
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
143
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
127
144
|
}
|
|
128
145
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
129
146
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
130
147
|
if (ip) {
|
|
131
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
148
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
132
149
|
}
|
|
133
150
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
134
151
|
if (hutkCookie) {
|
|
135
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
152
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
136
153
|
}
|
|
137
154
|
let uid = requestCookies.get(COOKIE_UID);
|
|
138
155
|
if (!uid) {
|
|
@@ -172,16 +189,16 @@ function processPreprRequest(request, opts) {
|
|
|
172
189
|
if (!isLivePreview) {
|
|
173
190
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
174
191
|
if (segmentCookie) {
|
|
175
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
192
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
176
193
|
}
|
|
177
194
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
178
195
|
if (abCookie) {
|
|
179
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
196
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
180
197
|
}
|
|
181
198
|
}
|
|
182
199
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
183
200
|
if (previewAb !== null) {
|
|
184
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
201
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
185
202
|
if (!isLivePreview) {
|
|
186
203
|
responseCookies.push({
|
|
187
204
|
name: COOKIE_VARIANT,
|
|
@@ -194,7 +211,7 @@ function processPreprRequest(request, opts) {
|
|
|
194
211
|
}
|
|
195
212
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
196
213
|
if (previewSegment !== null) {
|
|
197
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
214
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
198
215
|
if (!isLivePreview) {
|
|
199
216
|
responseCookies.push({
|
|
200
217
|
name: COOKIE_SEGMENT,
|
package/dist/sveltekit/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/constants.ts
|
|
5
5
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -38,6 +38,11 @@ var UTM_PARAMS = [
|
|
|
38
38
|
"utm_content",
|
|
39
39
|
"utm_campaign"
|
|
40
40
|
];
|
|
41
|
+
var MAX_HEADER_VALUE_LENGTH = 2048;
|
|
42
|
+
function sanitizeHeaderValue(value) {
|
|
43
|
+
const stripped = value.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
44
|
+
return stripped.length > MAX_HEADER_VALUE_LENGTH ? stripped.slice(0, MAX_HEADER_VALUE_LENGTH) : stripped;
|
|
45
|
+
}
|
|
41
46
|
function serializeCookie(cookie) {
|
|
42
47
|
const parts = [
|
|
43
48
|
`${cookie.name}=${encodeURIComponent(cookie.value)}`,
|
|
@@ -69,6 +74,15 @@ function parseCookies(request) {
|
|
|
69
74
|
function processPreprRequest(request, opts) {
|
|
70
75
|
const requestHeaders = new Headers(request.headers);
|
|
71
76
|
const responseCookies = [];
|
|
77
|
+
const inboundPreprHeaders = [];
|
|
78
|
+
requestHeaders.forEach((_value, key) => {
|
|
79
|
+
if (key.toLowerCase().startsWith("prepr-")) {
|
|
80
|
+
inboundPreprHeaders.push(key);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
for (const key of inboundPreprHeaders) {
|
|
84
|
+
requestHeaders.delete(key);
|
|
85
|
+
}
|
|
72
86
|
const requestCookies = parseCookies(request);
|
|
73
87
|
const url = new URL(request.url);
|
|
74
88
|
const searchParams = url.searchParams;
|
|
@@ -78,25 +92,28 @@ function processPreprRequest(request, opts) {
|
|
|
78
92
|
for (const key of UTM_PARAMS) {
|
|
79
93
|
const value = searchParams.get(key);
|
|
80
94
|
if (value !== null) {
|
|
81
|
-
requestHeaders.set(`Prepr-Context-${key}`, value);
|
|
95
|
+
requestHeaders.set(`Prepr-Context-${key}`, sanitizeHeaderValue(value));
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
const referer = request.headers.get("referer");
|
|
85
99
|
if (referer) {
|
|
86
|
-
requestHeaders.set(
|
|
100
|
+
requestHeaders.set(
|
|
101
|
+
"Prepr-Context-initial_referral",
|
|
102
|
+
sanitizeHeaderValue(referer)
|
|
103
|
+
);
|
|
87
104
|
}
|
|
88
105
|
const userAgent = request.headers.get("user-agent");
|
|
89
106
|
if (userAgent) {
|
|
90
|
-
requestHeaders.set("Prepr-User-Agent", userAgent);
|
|
107
|
+
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
91
108
|
}
|
|
92
109
|
requestHeaders.set("Prepr-Package", `@preprio/toolkit@${opts?.version ?? VERSION}`);
|
|
93
110
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
94
111
|
if (ip) {
|
|
95
|
-
requestHeaders.set("Prepr-Visitor-IP", ip);
|
|
112
|
+
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
96
113
|
}
|
|
97
114
|
const hutkCookie = requestCookies.get(COOKIE_HUBSPOT);
|
|
98
115
|
if (hutkCookie) {
|
|
99
|
-
requestHeaders.set("Prepr-Hubspot-Id", hutkCookie);
|
|
116
|
+
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
100
117
|
}
|
|
101
118
|
let uid = requestCookies.get(COOKIE_UID);
|
|
102
119
|
if (!uid) {
|
|
@@ -136,16 +153,16 @@ function processPreprRequest(request, opts) {
|
|
|
136
153
|
if (!isLivePreview) {
|
|
137
154
|
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
138
155
|
if (segmentCookie) {
|
|
139
|
-
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
156
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(segmentCookie));
|
|
140
157
|
}
|
|
141
158
|
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
142
159
|
if (abCookie) {
|
|
143
|
-
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
160
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(abCookie));
|
|
144
161
|
}
|
|
145
162
|
}
|
|
146
163
|
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
147
164
|
if (previewAb !== null) {
|
|
148
|
-
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
165
|
+
requestHeaders.set("Prepr-ABtesting", sanitizeHeaderValue(previewAb));
|
|
149
166
|
if (!isLivePreview) {
|
|
150
167
|
responseCookies.push({
|
|
151
168
|
name: COOKIE_VARIANT,
|
|
@@ -158,7 +175,7 @@ function processPreprRequest(request, opts) {
|
|
|
158
175
|
}
|
|
159
176
|
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
160
177
|
if (previewSegment !== null) {
|
|
161
|
-
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
178
|
+
requestHeaders.set("Prepr-Segments", sanitizeHeaderValue(previewSegment));
|
|
162
179
|
if (!isLivePreview) {
|
|
163
180
|
responseCookies.push({
|
|
164
181
|
name: COOKIE_SEGMENT,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@preprio/toolkit",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.6",
|
|
4
4
|
"description": "Prepr personalization, A/B testing and preview toolkit for React, Next.js, Nuxt, Astro, SvelteKit and Express",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Prepr B.V. (https://prepr.io)",
|