@salesforce/commerce-sdk-react 5.3.0-preview.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,5 @@
1
- ## v5.3.0-preview.0
1
+ ## v5.3.0 (Jul 13, 2026)
2
+ - [Bugfix] Fix Storefront Preview session loss with HttpOnly session cookies enabled. When the storefront runs inside a trusted Storefront Preview iframe, the client now sends the trusted parent origin as an `x-pwakit-preview-parent` header on the SLAS token request so the BFF sets session cookies with `SameSite=None; Partitioned`. Because the token request is never CDN-cached, this signal reaches the origin reliably even when the cacheable iframe document load is served from cache and bypasses the server-set preview marker cookie; the origin re-validates the value against its allow-list.
2
3
  - [Bugfix] Fix stale `sfdc_dwsid` server-affinity header in `CommerceApiProvider`. The `updatedClients` `useMemo` baked the `dwsid`-derived header into each SCAPI client's config but omitted `dwsid` from its dependency array, so when only the `dwsid` cookie changed (guest-to-login, session bridge, re-auth) the memoized clients kept sending the stale header, risking wrong/expired app-server routing on hybrid storefronts. The `dwsid` primitive is now a dependency so clients rebuild on change without churning on unrelated renders.
3
4
  - [Feature] Add OMS order-action hooks for Shopper Orders: the `cancelOmsOrder` and `returnOmsOrder` mutations and the `getOmsMetaData` query hook (return/cancel reason codes), with cache invalidation on the mutating actions. [#3864](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3864) [#3869](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3869)
4
5
  - Bump `commerce-sdk-isomorphic` to `5.4.0`, the first stable release carrying the OMS Shopper Orders endpoints (`oms-return-order`, `oms-cancel-order`, `oms-meta-data`).
package/auth/index.js CHANGED
@@ -213,6 +213,21 @@ class Auth {
213
213
  credentials: 'same-origin'
214
214
  }, config.fetchOptions)
215
215
  });
216
+
217
+ // When HttpOnly session cookies are enabled and the storefront is
218
+ // running inside a trusted Storefront Preview iframe, signal the parent
219
+ // origin to the BFF so it sets session cookies with SameSite=None;
220
+ // Partitioned (required for the cross-site iframe). This rides on the
221
+ // SLAS token POST — which is never CDN-cached — so it always reaches
222
+ // the origin, unlike the server-set `__Host-pwakit_preview_ctx` marker
223
+ // cookie that depends on the (cacheable) iframe document load hitting
224
+ // the origin. The BFF re-validates the value against its allow-list.
225
+ if (config.enableHttpOnlySessionCookies) {
226
+ const previewParentOrigin = (0, _utils.getTrustedPreviewParentOrigin)();
227
+ if (previewParentOrigin) {
228
+ this.client.clientConfig.headers[_constant.X_PREVIEW_PARENT] = previewParentOrigin;
229
+ }
230
+ }
216
231
  this.shopperCustomersClient = new _commerceSdkIsomorphic.ShopperCustomers({
217
232
  proxy: config.proxy,
218
233
  headers: config.headers || {},
package/constant.d.ts CHANGED
@@ -21,6 +21,7 @@ export declare const EXCLUDE_COOKIE_SUFFIX: string[];
21
21
  */
22
22
  export declare const SERVER_AFFINITY_HEADER_KEY = "sfdc_dwsid";
23
23
  export declare const X_GRANT_TYPE = "x-grant-type";
24
+ export declare const X_PREVIEW_PARENT = "x-pwakit-preview-parent";
24
25
  export declare const CLIENT_KEYS: {
25
26
  readonly SHOPPER_BASKETS: "shopperBaskets";
26
27
  readonly SHOPPER_BASKETS_V2: "shopperBasketsV2";
package/constant.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.X_GRANT_TYPE = exports.SLAS_SECRET_WARNING_MSG = exports.SLAS_SECRET_PLACEHOLDER = exports.SLAS_SECRET_OVERRIDE_MSG = exports.SLAS_REFRESH_TOKEN_COOKIE_TTL_OVERRIDE_MSG = exports.SERVER_AFFINITY_HEADER_KEY = exports.IFRAME_HOST_ALLOW_LIST = exports.EXCLUDE_COOKIE_SUFFIX = exports.DWSID_COOKIE_NAME = exports.DNT_COOKIE_NAME = exports.CLIENT_KEYS = void 0;
6
+ exports.X_PREVIEW_PARENT = exports.X_GRANT_TYPE = exports.SLAS_SECRET_WARNING_MSG = exports.SLAS_SECRET_PLACEHOLDER = exports.SLAS_SECRET_OVERRIDE_MSG = exports.SLAS_REFRESH_TOKEN_COOKIE_TTL_OVERRIDE_MSG = exports.SERVER_AFFINITY_HEADER_KEY = exports.IFRAME_HOST_ALLOW_LIST = exports.EXCLUDE_COOKIE_SUFFIX = exports.DWSID_COOKIE_NAME = exports.DNT_COOKIE_NAME = exports.CLIENT_KEYS = void 0;
7
7
  /*
8
8
  * Copyright (c) 2025, Salesforce, Inc.
9
9
  * All rights reserved.
@@ -39,6 +39,17 @@ const SERVER_AFFINITY_HEADER_KEY = exports.SERVER_AFFINITY_HEADER_KEY = 'sfdc_dw
39
39
 
40
40
  // Custom header sent by the SDK to signal a refresh token request to the proxy.
41
41
  const X_GRANT_TYPE = exports.X_GRANT_TYPE = 'x-grant-type';
42
+
43
+ // Custom header sent by the SDK on SLAS token requests when the storefront is
44
+ // running inside a trusted Storefront Preview iframe. Carries the (trusted)
45
+ // parent origin so the BFF can set session cookies with SameSite=None;
46
+ // Partitioned instead of SameSite=Lax. Sent only when HttpOnly session cookies
47
+ // are enabled. Unlike the server-set `__Host-pwakit_preview_ctx` marker cookie
48
+ // (which relies on the iframe document load reaching the origin, and so is
49
+ // bypassed when that response is served from the CDN cache), this header rides
50
+ // on the non-cacheable token POST and always reaches the origin. The BFF
51
+ // re-validates the value against its own allow-list before honoring it.
52
+ const X_PREVIEW_PARENT = exports.X_PREVIEW_PARENT = 'x-pwakit-preview-parent';
42
53
  const CLIENT_KEYS = exports.CLIENT_KEYS = {
43
54
  SHOPPER_BASKETS: 'shopperBaskets',
44
55
  SHOPPER_BASKETS_V2: 'shopperBasketsV2',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/commerce-sdk-react",
3
- "version": "5.3.0-preview.0",
3
+ "version": "5.3.0",
4
4
  "description": "A library that provides react hooks for fetching data from Commerce Cloud",
5
5
  "homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/ecom-react-hooks#readme",
6
6
  "bugs": {
@@ -46,7 +46,7 @@
46
46
  "jwt-decode": "^4.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@salesforce/pwa-kit-dev": "3.19.0-preview.0",
49
+ "@salesforce/pwa-kit-dev": "3.19.0",
50
50
  "@tanstack/react-query": "^4.28.0",
51
51
  "@testing-library/jest-dom": "^5.16.5",
52
52
  "@testing-library/react": "^14.0.0",
@@ -61,7 +61,7 @@
61
61
  "@types/react-helmet": "~6.1.6",
62
62
  "@types/react-router-dom": "~5.3.3",
63
63
  "cross-env": "^5.2.1",
64
- "internal-lib-build": "3.19.0-preview.0",
64
+ "internal-lib-build": "3.19.0",
65
65
  "jsonwebtoken": "^9.0.0",
66
66
  "nock": "^13.3.0",
67
67
  "nodemon": "^2.0.22",
@@ -98,5 +98,5 @@
98
98
  "publishConfig": {
99
99
  "directory": "dist"
100
100
  },
101
- "gitHead": "f93e393e81306cfc61186f9162324f7ff8ac7b3c"
101
+ "gitHead": "5192e11826187be0dbdacf4754c84ac18af64f67"
102
102
  }
package/utils.d.ts CHANGED
@@ -37,6 +37,19 @@ export declare const isOriginTrusted: (origin: string | undefined) => boolean;
37
37
  * (i.e. Storefront Preview), otherwise `"Lax"`
38
38
  */
39
39
  export declare const getCookieSameSiteAttribute: () => "none" | "Lax" | undefined;
40
+ /**
41
+ * Returns the parent origin when the storefront is running inside a trusted
42
+ * Storefront Preview iframe (i.e. the same condition under which
43
+ * `getCookieSameSiteAttribute` returns `"none"`), otherwise `undefined`.
44
+ *
45
+ * Used to signal the trusted parent origin to the BFF (via the
46
+ * `x-pwakit-preview-parent` header) on SLAS token requests when HttpOnly
47
+ * session cookies are enabled, so the server can set session cookies with
48
+ * SameSite=None; Partitioned. Returns `undefined` on the server and on
49
+ * localhost (the server-side allow-list does not include the local dev
50
+ * origin, and local dev is not fronted by the CDN that motivates this header).
51
+ */
52
+ export declare const getTrustedPreviewParentOrigin: () => string | undefined;
40
53
  /**
41
54
  * Gets the default cookie attributes. Sets the secure flag unless running on localhost in Safari.
42
55
  * Sets the sameSite attribute to `"none"` when running in a trusted iframe.
package/utils.js CHANGED
@@ -7,7 +7,7 @@ exports.DEVELOPMENT_ORIGIN = void 0;
7
7
  exports.detectCookiesAvailable = detectCookiesAvailable;
8
8
  exports.detectInIframe = void 0;
9
9
  exports.detectLocalStorageAvailable = detectLocalStorageAvailable;
10
- exports.getParentOrigin = exports.getDefaultCookieAttributes = exports.getCookieSameSiteAttribute = exports.extractCustomParameters = void 0;
10
+ exports.getTrustedPreviewParentOrigin = exports.getParentOrigin = exports.getDefaultCookieAttributes = exports.getCookieSameSiteAttribute = exports.extractCustomParameters = void 0;
11
11
  exports.isAbsoluteUrl = isAbsoluteUrl;
12
12
  exports.transformSDKClient = exports.stringToBase64 = exports.parseResponseBodyClone = exports.onClient = exports.isOriginTrusted = void 0;
13
13
  var _jsCookie = _interopRequireDefault(require("js-cookie"));
@@ -96,11 +96,31 @@ const getCookieSameSiteAttribute = () => {
96
96
  return !isLocalHost && isOriginTrusted(parentOrigin) ? 'none' : 'Lax';
97
97
  };
98
98
 
99
+ /**
100
+ * Returns the parent origin when the storefront is running inside a trusted
101
+ * Storefront Preview iframe (i.e. the same condition under which
102
+ * `getCookieSameSiteAttribute` returns `"none"`), otherwise `undefined`.
103
+ *
104
+ * Used to signal the trusted parent origin to the BFF (via the
105
+ * `x-pwakit-preview-parent` header) on SLAS token requests when HttpOnly
106
+ * session cookies are enabled, so the server can set session cookies with
107
+ * SameSite=None; Partitioned. Returns `undefined` on the server and on
108
+ * localhost (the server-side allow-list does not include the local dev
109
+ * origin, and local dev is not fronted by the CDN that motivates this header).
110
+ */
111
+ exports.getCookieSameSiteAttribute = getCookieSameSiteAttribute;
112
+ const getTrustedPreviewParentOrigin = () => {
113
+ if (!onClient()) return undefined;
114
+ const isLocalHost = window.location.hostname === 'localhost';
115
+ const parentOrigin = getParentOrigin();
116
+ return !isLocalHost && isOriginTrusted(parentOrigin) ? parentOrigin : undefined;
117
+ };
118
+
99
119
  /**
100
120
  * Gets the default cookie attributes. Sets the secure flag unless running on localhost in Safari.
101
121
  * Sets the sameSite attribute to `"none"` when running in a trusted iframe.
102
122
  */
103
- exports.getCookieSameSiteAttribute = getCookieSameSiteAttribute;
123
+ exports.getTrustedPreviewParentOrigin = getTrustedPreviewParentOrigin;
104
124
  const getDefaultCookieAttributes = () => {
105
125
  return {
106
126
  // Deployed sites will always be HTTPS, but the local dev server is served over HTTP.