@preprio/toolkit 0.2.0-beta.5 → 0.2.0-beta.7
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-P6VTLWM4.js} +44 -38
- package/dist/index.cjs +71 -48
- 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 +44 -38
- 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 +44 -38
- package/dist/react/components.js +44 -38
- package/dist/sveltekit/index.cjs +27 -10
- package/dist/sveltekit/index.js +27 -10
- package/package.json +12 -12
|
@@ -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
|
},
|
|
@@ -436,6 +439,8 @@ function createStegaAutoClean() {
|
|
|
436
439
|
function scanAndClean() {
|
|
437
440
|
processing = true;
|
|
438
441
|
walkTextNodes(document.body, cleanTextNode);
|
|
442
|
+
const title = (0, import_stega2.vercelStegaSplit)(document.title);
|
|
443
|
+
if (title.encoded) document.title = title.cleaned;
|
|
439
444
|
processing = false;
|
|
440
445
|
}
|
|
441
446
|
function collectAffected(mutations) {
|
|
@@ -481,15 +486,8 @@ function createStegaAutoClean() {
|
|
|
481
486
|
}
|
|
482
487
|
function start() {
|
|
483
488
|
if (observer || typeof window === "undefined") return;
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
setupObserver();
|
|
487
|
-
};
|
|
488
|
-
if ("requestIdleCallback" in window) {
|
|
489
|
-
window.requestIdleCallback(run);
|
|
490
|
-
} else {
|
|
491
|
-
setTimeout(run, 0);
|
|
492
|
-
}
|
|
489
|
+
scanAndClean();
|
|
490
|
+
setupObserver();
|
|
493
491
|
debug2.log("stega auto-clean started");
|
|
494
492
|
}
|
|
495
493
|
function stop() {
|
|
@@ -982,7 +980,7 @@ function cookieOpts() {
|
|
|
982
980
|
};
|
|
983
981
|
}
|
|
984
982
|
function createChangeHandler(deps) {
|
|
985
|
-
const { store, stega,
|
|
983
|
+
const { store, stega, features, editingEnabled } = deps;
|
|
986
984
|
function updateParams(patch) {
|
|
987
985
|
const [path, existing] = splitPath(deps.currentPath());
|
|
988
986
|
const params = new URLSearchParams(existing);
|
|
@@ -1045,16 +1043,17 @@ function createChangeHandler(deps) {
|
|
|
1045
1043
|
setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), cookieOpts());
|
|
1046
1044
|
setCookie(COOKIE_TOOLBAR_OPEN, "false", cookieOpts());
|
|
1047
1045
|
sendPreprEvent("preview_mode_toggled", { previewMode: after.previewMode });
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1046
|
+
if (!after.isIframe) {
|
|
1047
|
+
const [path, existing] = splitPath(deps.currentPath());
|
|
1048
|
+
const params = new URLSearchParams(existing);
|
|
1049
|
+
if (params.has(PARAM_SEGMENT) || params.has(PARAM_VARIANT)) {
|
|
1050
|
+
params.delete(PARAM_SEGMENT);
|
|
1051
|
+
params.delete(PARAM_VARIANT);
|
|
1052
|
+
const query = params.toString();
|
|
1053
|
+
deps.navigate(query ? `${path}?${query}` : path);
|
|
1054
|
+
} else {
|
|
1055
|
+
deps.reload();
|
|
1056
|
+
}
|
|
1058
1057
|
}
|
|
1059
1058
|
}
|
|
1060
1059
|
if (before.toolbarOpen !== after.toolbarOpen) {
|
|
@@ -2049,6 +2048,14 @@ function defaultNavigation() {
|
|
|
2049
2048
|
currentPath: () => window.location.pathname + window.location.search
|
|
2050
2049
|
};
|
|
2051
2050
|
}
|
|
2051
|
+
function safeEditUrl(href) {
|
|
2052
|
+
try {
|
|
2053
|
+
const url = new URL(href, window.location.href);
|
|
2054
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2055
|
+
} catch {
|
|
2056
|
+
return null;
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2052
2059
|
function buildSegments(data) {
|
|
2053
2060
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2054
2061
|
}
|
|
@@ -2112,24 +2119,25 @@ function createPreprPreview(opts = {}) {
|
|
|
2112
2119
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2113
2120
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2114
2121
|
onEdit: ({ href, origin, id, field }) => {
|
|
2122
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2123
|
+
if (href && !safeHref) {
|
|
2124
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2115
2127
|
if (isIframe) {
|
|
2116
|
-
sendPreprEvent("field_edit_requested", {
|
|
2117
|
-
|
|
2118
|
-
|
|
2128
|
+
sendPreprEvent("field_edit_requested", {
|
|
2129
|
+
href: safeHref ?? void 0,
|
|
2130
|
+
origin,
|
|
2131
|
+
id,
|
|
2132
|
+
field
|
|
2133
|
+
});
|
|
2134
|
+
} else if (safeHref) {
|
|
2135
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2119
2136
|
}
|
|
2120
2137
|
}
|
|
2121
2138
|
});
|
|
2122
2139
|
const autoClean = createStegaAutoClean();
|
|
2123
|
-
|
|
2124
|
-
function syncAutoClean(active) {
|
|
2125
|
-
if (active && !autoCleanActive) {
|
|
2126
|
-
autoClean.start();
|
|
2127
|
-
autoCleanActive = true;
|
|
2128
|
-
} else if (!active && autoCleanActive) {
|
|
2129
|
-
autoClean.stop();
|
|
2130
|
-
autoCleanActive = false;
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2140
|
+
autoClean.start();
|
|
2133
2141
|
const handleChange = createChangeHandler({
|
|
2134
2142
|
store,
|
|
2135
2143
|
features,
|
|
@@ -2137,8 +2145,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2137
2145
|
navigate: (url) => navigation.navigate(url),
|
|
2138
2146
|
currentPath: () => navigation.currentPath(),
|
|
2139
2147
|
reload: navigation.reload ?? (() => window.location.reload()),
|
|
2140
|
-
stega
|
|
2141
|
-
syncAutoClean
|
|
2148
|
+
stega
|
|
2142
2149
|
});
|
|
2143
2150
|
let prev = store.get();
|
|
2144
2151
|
const unsubscribe = store.subscribe((state) => {
|
|
@@ -2146,7 +2153,6 @@ function createPreprPreview(opts = {}) {
|
|
|
2146
2153
|
prev = state;
|
|
2147
2154
|
handleChange(before, state);
|
|
2148
2155
|
});
|
|
2149
|
-
syncAutoClean(store.get().previewMode);
|
|
2150
2156
|
const bridge = createIframeBridge(store, {
|
|
2151
2157
|
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2152
2158
|
});
|
|
@@ -2159,7 +2165,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2159
2165
|
function destroy() {
|
|
2160
2166
|
unsubscribe();
|
|
2161
2167
|
stega.stop();
|
|
2162
|
-
|
|
2168
|
+
autoClean.stop();
|
|
2163
2169
|
if (isIframe) {
|
|
2164
2170
|
bridge.stop();
|
|
2165
2171
|
}
|
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
|
},
|
|
@@ -412,6 +415,8 @@ function createStegaAutoClean() {
|
|
|
412
415
|
function scanAndClean() {
|
|
413
416
|
processing = true;
|
|
414
417
|
walkTextNodes(document.body, cleanTextNode);
|
|
418
|
+
const title = vercelStegaSplit(document.title);
|
|
419
|
+
if (title.encoded) document.title = title.cleaned;
|
|
415
420
|
processing = false;
|
|
416
421
|
}
|
|
417
422
|
function collectAffected(mutations) {
|
|
@@ -457,15 +462,8 @@ function createStegaAutoClean() {
|
|
|
457
462
|
}
|
|
458
463
|
function start() {
|
|
459
464
|
if (observer || typeof window === "undefined") return;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
setupObserver();
|
|
463
|
-
};
|
|
464
|
-
if ("requestIdleCallback" in window) {
|
|
465
|
-
window.requestIdleCallback(run);
|
|
466
|
-
} else {
|
|
467
|
-
setTimeout(run, 0);
|
|
468
|
-
}
|
|
465
|
+
scanAndClean();
|
|
466
|
+
setupObserver();
|
|
469
467
|
debug2.log("stega auto-clean started");
|
|
470
468
|
}
|
|
471
469
|
function stop() {
|
|
@@ -958,7 +956,7 @@ function cookieOpts() {
|
|
|
958
956
|
};
|
|
959
957
|
}
|
|
960
958
|
function createChangeHandler(deps) {
|
|
961
|
-
const { store, stega,
|
|
959
|
+
const { store, stega, features, editingEnabled } = deps;
|
|
962
960
|
function updateParams(patch) {
|
|
963
961
|
const [path, existing] = splitPath(deps.currentPath());
|
|
964
962
|
const params = new URLSearchParams(existing);
|
|
@@ -1021,16 +1019,17 @@ function createChangeHandler(deps) {
|
|
|
1021
1019
|
setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), cookieOpts());
|
|
1022
1020
|
setCookie(COOKIE_TOOLBAR_OPEN, "false", cookieOpts());
|
|
1023
1021
|
sendPreprEvent("preview_mode_toggled", { previewMode: after.previewMode });
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1022
|
+
if (!after.isIframe) {
|
|
1023
|
+
const [path, existing] = splitPath(deps.currentPath());
|
|
1024
|
+
const params = new URLSearchParams(existing);
|
|
1025
|
+
if (params.has(PARAM_SEGMENT) || params.has(PARAM_VARIANT)) {
|
|
1026
|
+
params.delete(PARAM_SEGMENT);
|
|
1027
|
+
params.delete(PARAM_VARIANT);
|
|
1028
|
+
const query = params.toString();
|
|
1029
|
+
deps.navigate(query ? `${path}?${query}` : path);
|
|
1030
|
+
} else {
|
|
1031
|
+
deps.reload();
|
|
1032
|
+
}
|
|
1034
1033
|
}
|
|
1035
1034
|
}
|
|
1036
1035
|
if (before.toolbarOpen !== after.toolbarOpen) {
|
|
@@ -2025,6 +2024,14 @@ function defaultNavigation() {
|
|
|
2025
2024
|
currentPath: () => window.location.pathname + window.location.search
|
|
2026
2025
|
};
|
|
2027
2026
|
}
|
|
2027
|
+
function safeEditUrl(href) {
|
|
2028
|
+
try {
|
|
2029
|
+
const url = new URL(href, window.location.href);
|
|
2030
|
+
return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
|
|
2031
|
+
} catch {
|
|
2032
|
+
return null;
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2028
2035
|
function buildSegments(data) {
|
|
2029
2036
|
return [{ _id: "all_other_users", name: "All other users" }, ...data];
|
|
2030
2037
|
}
|
|
@@ -2088,24 +2095,25 @@ function createPreprPreview(opts = {}) {
|
|
|
2088
2095
|
// In the editor, ask the parent to focus the field instead of opening a new
|
|
2089
2096
|
// tab. Standalone previews keep the window.open behaviour.
|
|
2090
2097
|
onEdit: ({ href, origin, id, field }) => {
|
|
2098
|
+
const safeHref = href ? safeEditUrl(href) : null;
|
|
2099
|
+
if (href && !safeHref) {
|
|
2100
|
+
debug7.warn("ignored edit request with unsupported href scheme");
|
|
2101
|
+
return;
|
|
2102
|
+
}
|
|
2091
2103
|
if (isIframe) {
|
|
2092
|
-
sendPreprEvent("field_edit_requested", {
|
|
2093
|
-
|
|
2094
|
-
|
|
2104
|
+
sendPreprEvent("field_edit_requested", {
|
|
2105
|
+
href: safeHref ?? void 0,
|
|
2106
|
+
origin,
|
|
2107
|
+
id,
|
|
2108
|
+
field
|
|
2109
|
+
});
|
|
2110
|
+
} else if (safeHref) {
|
|
2111
|
+
window.open(safeHref, "_blank", "noopener,noreferrer");
|
|
2095
2112
|
}
|
|
2096
2113
|
}
|
|
2097
2114
|
});
|
|
2098
2115
|
const autoClean = createStegaAutoClean();
|
|
2099
|
-
|
|
2100
|
-
function syncAutoClean(active) {
|
|
2101
|
-
if (active && !autoCleanActive) {
|
|
2102
|
-
autoClean.start();
|
|
2103
|
-
autoCleanActive = true;
|
|
2104
|
-
} else if (!active && autoCleanActive) {
|
|
2105
|
-
autoClean.stop();
|
|
2106
|
-
autoCleanActive = false;
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2116
|
+
autoClean.start();
|
|
2109
2117
|
const handleChange = createChangeHandler({
|
|
2110
2118
|
store,
|
|
2111
2119
|
features,
|
|
@@ -2113,8 +2121,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2113
2121
|
navigate: (url) => navigation.navigate(url),
|
|
2114
2122
|
currentPath: () => navigation.currentPath(),
|
|
2115
2123
|
reload: navigation.reload ?? (() => window.location.reload()),
|
|
2116
|
-
stega
|
|
2117
|
-
syncAutoClean
|
|
2124
|
+
stega
|
|
2118
2125
|
});
|
|
2119
2126
|
let prev = store.get();
|
|
2120
2127
|
const unsubscribe = store.subscribe((state) => {
|
|
@@ -2122,7 +2129,6 @@ function createPreprPreview(opts = {}) {
|
|
|
2122
2129
|
prev = state;
|
|
2123
2130
|
handleChange(before, state);
|
|
2124
2131
|
});
|
|
2125
|
-
syncAutoClean(store.get().previewMode);
|
|
2126
2132
|
const bridge = createIframeBridge(store, {
|
|
2127
2133
|
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2128
2134
|
});
|
|
@@ -2135,7 +2141,7 @@ function createPreprPreview(opts = {}) {
|
|
|
2135
2141
|
function destroy() {
|
|
2136
2142
|
unsubscribe();
|
|
2137
2143
|
stega.stop();
|
|
2138
|
-
|
|
2144
|
+
autoClean.stop();
|
|
2139
2145
|
if (isIframe) {
|
|
2140
2146
|
bridge.stop();
|
|
2141
2147
|
}
|
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.7";
|
|
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.7";
|
|
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.7",
|
|
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)",
|
|
@@ -94,6 +94,16 @@
|
|
|
94
94
|
"src/sveltekit/*.svelte",
|
|
95
95
|
"src/nuxt/*.vue"
|
|
96
96
|
],
|
|
97
|
+
"scripts": {
|
|
98
|
+
"gen:css": "node scripts/compile-css.mjs",
|
|
99
|
+
"prebuild": "rm -rf dist && pnpm gen:css && node scripts/check-version.mjs",
|
|
100
|
+
"pretest": "pnpm gen:css",
|
|
101
|
+
"pretypecheck": "pnpm gen:css",
|
|
102
|
+
"build": "tsup",
|
|
103
|
+
"postbuild": "node scripts/check-exports.mjs",
|
|
104
|
+
"test": "vitest run",
|
|
105
|
+
"typecheck": "tsc --noEmit"
|
|
106
|
+
},
|
|
97
107
|
"dependencies": {
|
|
98
108
|
"@vercel/stega": "^1.1.0",
|
|
99
109
|
"preact": "^10.29.7"
|
|
@@ -135,15 +145,5 @@
|
|
|
135
145
|
"tsup": "^8.5.1",
|
|
136
146
|
"typescript": "^5.9.3",
|
|
137
147
|
"vitest": "^4.1.10"
|
|
138
|
-
},
|
|
139
|
-
"scripts": {
|
|
140
|
-
"gen:css": "node scripts/compile-css.mjs",
|
|
141
|
-
"prebuild": "rm -rf dist && pnpm gen:css && node scripts/check-version.mjs",
|
|
142
|
-
"pretest": "pnpm gen:css",
|
|
143
|
-
"pretypecheck": "pnpm gen:css",
|
|
144
|
-
"build": "tsup",
|
|
145
|
-
"postbuild": "node scripts/check-exports.mjs",
|
|
146
|
-
"test": "vitest run",
|
|
147
|
-
"typecheck": "tsc --noEmit"
|
|
148
148
|
}
|
|
149
|
-
}
|
|
149
|
+
}
|