@tokenoftrust/storefront-runner 4.0.1 → 4.1.1
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.
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
withShippingPolicy,
|
|
33
33
|
withReturnUrl,
|
|
34
34
|
trustedCartReturnUrl,
|
|
35
|
+
CHECKOUT_NAVIGATION_REFERRER_POLICY,
|
|
35
36
|
SHIPPING_UNAVAILABLE_CART_MESSAGE,
|
|
36
37
|
ShippingPolicyUnavailableError,
|
|
37
38
|
type CartDenialCode,
|
|
@@ -183,6 +184,7 @@ async function cartFormPost(context: APIContext): Promise<Response> {
|
|
|
183
184
|
headers: {
|
|
184
185
|
location,
|
|
185
186
|
"cache-control": "no-store",
|
|
187
|
+
"referrer-policy": CHECKOUT_NAVIGATION_REFERRER_POLICY,
|
|
186
188
|
"x-tot-payment-authorized": "false",
|
|
187
189
|
},
|
|
188
190
|
});
|
|
@@ -233,7 +235,7 @@ function sampleResponse(body: string | null, status: number, location?: string):
|
|
|
233
235
|
return new Response(body, { status, headers: {
|
|
234
236
|
"content-type": "application/json; charset=utf-8",
|
|
235
237
|
"cache-control": "private, no-store",
|
|
236
|
-
"referrer-policy": "no-referrer",
|
|
238
|
+
"referrer-policy": location ? CHECKOUT_NAVIGATION_REFERRER_POLICY : "no-referrer",
|
|
237
239
|
"x-robots-tag": "noindex, nofollow",
|
|
238
240
|
"x-tot-payment-authorized": "false",
|
|
239
241
|
...(location ? { location } : {}),
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
* published (CloudFront/S3) output — both render Layout.astro. The session id
|
|
39
39
|
* is not part of that HTML.
|
|
40
40
|
*/
|
|
41
|
+
import { CHECKOUT_NAVIGATION_REFERRER_POLICY } from "@tot/public-runtime";
|
|
41
42
|
import { CART_UNAVAILABLE_MESSAGE } from "@/lib/checkout/commerce/cartSession";
|
|
42
43
|
|
|
43
44
|
export const LAZY_CHECKOUT_LOADER_IDLE_MS = 8000;
|
|
@@ -77,6 +78,7 @@ export function lazyCheckoutLoaderJs(options: LazyCheckoutLoaderOptions): string
|
|
|
77
78
|
var cartOrigin = ${literal(options.cartOrigin)};
|
|
78
79
|
var sessionHref = ${literal(options.sessionHref)};
|
|
79
80
|
var cookiePath = ${literal(options.cookiePath)};
|
|
81
|
+
var referrerPolicy = ${literal(CHECKOUT_NAVIGATION_REFERRER_POLICY)};
|
|
80
82
|
var storeNotPublic = ${options.storeNotPublic ? "true" : "false"};
|
|
81
83
|
var events = ${literal(LAZY_CHECKOUT_LOADER_EVENTS)};
|
|
82
84
|
var state = 'idle';
|
|
@@ -87,6 +89,46 @@ export function lazyCheckoutLoaderJs(options: LazyCheckoutLoaderOptions): string
|
|
|
87
89
|
if (!url) return false;
|
|
88
90
|
try { return new URL(url, document.baseURI).origin === cartOrigin; } catch (e) { return false; }
|
|
89
91
|
}
|
|
92
|
+
// Foxy copies the Referer onto cart_cancel_and_continue_link and ignores a
|
|
93
|
+
// continue parameter. The document policy stays strict-origin. A cart script
|
|
94
|
+
// snapshots the Referer while its src is assigned, so that assignment uses the
|
|
95
|
+
// store-home URL and restores the page before the turn ends. A cart navigation
|
|
96
|
+
// sends the full document URL through the element's referrerPolicy. That URL
|
|
97
|
+
// already includes the store origin and tenant path, and the history entry
|
|
98
|
+
// stays the page that opened the cart.
|
|
99
|
+
function storeHome() {
|
|
100
|
+
return location.origin + cookiePath;
|
|
101
|
+
}
|
|
102
|
+
function revealStoreHome() {
|
|
103
|
+
var home = storeHome();
|
|
104
|
+
if (location.href === home) return;
|
|
105
|
+
window.history.replaceState(window.history.state, "", home);
|
|
106
|
+
}
|
|
107
|
+
function restoreHref(current) {
|
|
108
|
+
if (location.href !== current) window.history.replaceState(window.history.state, "", current);
|
|
109
|
+
}
|
|
110
|
+
var origCreate = document.createElement;
|
|
111
|
+
document.createElement = function (name) {
|
|
112
|
+
var el = origCreate.apply(document, arguments);
|
|
113
|
+
if (String(name).toLowerCase() !== "script") return el;
|
|
114
|
+
var proto = window.HTMLScriptElement && window.HTMLScriptElement.prototype;
|
|
115
|
+
var srcDesc = proto && Object.getOwnPropertyDescriptor(proto, "src");
|
|
116
|
+
if (!srcDesc || !srcDesc.get || !srcDesc.set) return el;
|
|
117
|
+
Object.defineProperty(el, "src", {
|
|
118
|
+
configurable: true,
|
|
119
|
+
enumerable: true,
|
|
120
|
+
get: function () { return srcDesc.get.call(this); },
|
|
121
|
+
set: function (value) {
|
|
122
|
+
if (!targetsCart(value)) return srcDesc.set.call(this, value);
|
|
123
|
+
this.referrerPolicy = referrerPolicy;
|
|
124
|
+
var current = location.href;
|
|
125
|
+
revealStoreHome();
|
|
126
|
+
try { return srcDesc.set.call(this, value); }
|
|
127
|
+
finally { restoreHref(current); }
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
return el;
|
|
131
|
+
};
|
|
90
132
|
function commerceReachable() {
|
|
91
133
|
var nodes = document.querySelectorAll(${managedCart} + ', a[href], form[action]');
|
|
92
134
|
for (var i = 0; i < nodes.length; i++) {
|
|
@@ -209,6 +251,7 @@ export function lazyCheckoutLoaderJs(options: LazyCheckoutLoaderOptions): string
|
|
|
209
251
|
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
210
252
|
var anchor = event.target && event.target.closest ? event.target.closest('a[href]') : null;
|
|
211
253
|
if (!anchor || anchor.target === '_blank' || !targetsCart(anchor.href)) return;
|
|
254
|
+
anchor.referrerPolicy = referrerPolicy;
|
|
212
255
|
if (state === 'ready') {
|
|
213
256
|
stampAnchor(anchor);
|
|
214
257
|
return;
|
|
@@ -268,7 +311,12 @@ export function lazyCheckoutLoaderJs(options: LazyCheckoutLoaderOptions): string
|
|
|
268
311
|
var cartForm = targetsCart(form.getAttribute('action'));
|
|
269
312
|
if (!managed && !cartForm) return;
|
|
270
313
|
if (form.dataset.cartSession === '1') {
|
|
271
|
-
if (!cartForm || state === 'ready')
|
|
314
|
+
if (!cartForm || state === 'ready') {
|
|
315
|
+
if (!event.defaultPrevented && state === 'ready') {
|
|
316
|
+
form.referrerPolicy = referrerPolicy;
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
272
320
|
event.preventDefault();
|
|
273
321
|
whenReady(function () { stampForm(form); resubmit(form); });
|
|
274
322
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -212,6 +212,22 @@ export const INTERNAL_CART_FIELDS = ["currency", "tenant", "verification", "ship
|
|
|
212
212
|
/** The signed cart option the checkout store's Continue Shopping link reads (`withReturnUrl`). */
|
|
213
213
|
export const RETURN_URL_CART_FIELD = "return_url";
|
|
214
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Referrer policy for a request the browser makes to the managed checkout (a cart
|
|
217
|
+
* script, a cart navigation, or the hop that follows a 303 onto the cart).
|
|
218
|
+
*
|
|
219
|
+
* Measured 2026-10-24 against tot-preview: Foxy sets `cart_cancel_and_continue_link`
|
|
220
|
+
* from the Referer and ignores a `continue` parameter. An origin-only Referer
|
|
221
|
+
* overwrites a fuller one; the first request with no Referer falls back to the
|
|
222
|
+
* store's configured store URL (the host root). `strict-origin-when-cross-origin`
|
|
223
|
+
* sends only that origin on a cross-origin checkout request, so empty-cart and
|
|
224
|
+
* receipt links drop the tenant path. This value sends the full URL on https and
|
|
225
|
+
* nothing on a downgrade. It is not the document policy: a redirect response's
|
|
226
|
+
* Referrer-Policy replaces the element's, and `no-referrer` on that response
|
|
227
|
+
* clears the path. The site-wide header stays strict-origin.
|
|
228
|
+
*/
|
|
229
|
+
export const CHECKOUT_NAVIGATION_REFERRER_POLICY = "no-referrer-when-downgrade";
|
|
230
|
+
|
|
215
231
|
/** The signed cart option the checkout store reads the shipping charge from. */
|
|
216
232
|
export const SHIPPING_POLICY_CART_FIELD = "shipping_policy";
|
|
217
233
|
|