@salesforce/commerce-sdk-react 3.4.0 → 3.4.1-preview.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,8 +1,17 @@
1
+ ## v3.4.1-preview.0 (Aug 21, 2025)
2
+
3
+ - Add support for environment level base paths on /mobify routes [#2892](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2892)
4
+ - Update USID expiry to match SLAS refresh token expiry[#2854](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2854)
5
+
6
+ - [Bugfix] Skip deleting dwsid on shopper login if hybrid auth is enabled for current site. [#3151](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/3151)
7
+
1
8
  ## v3.4.0 (Jul 22, 2025)
9
+
2
10
  - Optionally disable auth init in CommerceApiProvider [#2629](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2629)
3
11
  - Now compatible with either React 17 and 18 [#2506](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2506)
4
12
  - Gracefully handle missing SDK Clients in CommerceApiProvider [#2539](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2539)
5
13
  - Refactor commerce-sdk-react to allow injecting ApiClients [#2519](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2519)
14
+ - Upgrade to commerce-sdk-isomorphic v3.4.0 [#2866](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2866)
6
15
 
7
16
 
8
17
  ## v3.3.0 (May 22, 2025)
package/auth/index.d.ts CHANGED
@@ -8,6 +8,7 @@ type Helpers = typeof helpers;
8
8
  interface AuthConfig extends ApiClientConfigParams {
9
9
  redirectURI: string;
10
10
  proxy: string;
11
+ privateClientProxyEndpoint?: string;
11
12
  fetchOptions?: ShopperLoginTypes.FetchOptions;
12
13
  fetchedToken?: string;
13
14
  enablePWAKitPrivateClient?: boolean;
@@ -18,6 +19,7 @@ interface AuthConfig extends ApiClientConfigParams {
18
19
  passwordlessLoginCallbackURI?: string;
19
20
  refreshTokenRegisteredCookieTTL?: number;
20
21
  refreshTokenGuestCookieTTL?: number;
22
+ hybridAuthEnabled?: boolean;
21
23
  }
22
24
  type AuthorizeIDPParams = Parameters<Helpers['authorizeIDP']>[1];
23
25
  type LoginIDPUserParams = Parameters<Helpers['loginIDPUser']>[2];
@@ -75,6 +77,7 @@ declare class Auth {
75
77
  private refreshTokenRegisteredCookieTTL;
76
78
  private refreshTokenGuestCookieTTL;
77
79
  private refreshTrustedAgentHandler;
80
+ private hybridAuthEnabled;
78
81
  constructor(config: AuthConfig);
79
82
  get(name: AuthDataKeys): string;
80
83
  private set;
@@ -149,7 +152,10 @@ declare class Auth {
149
152
  */
150
153
  private convertSecondsToDate;
151
154
  /**
152
- * Retrieves our refresh token cookie ttl value
155
+ * Retrieves our refresh token cookie ttl value from the following sources in order:
156
+ * 1. Override value (if set)
157
+ * 2. SLAS response value (if set)
158
+ * 3. Default value (if no override or SLAS response value is set)
153
159
  */
154
160
  private getRefreshTokenCookieTTLValue;
155
161
  /**
package/auth/index.js CHANGED
@@ -147,11 +147,14 @@ const DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL = exports.DEFAULT_SLAS_REFRESH_TOKEN_
147
147
  */
148
148
  class Auth {
149
149
  constructor(config) {
150
- // Special endpoint for injecting SLAS private client secret.
150
+ // Special proxy endpoint for injecting SLAS private client secret.
151
+ // We prioritize config.privateClientProxyEndpoint since that allows us to use the new envBasePath feature
152
+ // The preexisting hard coded privateClientEndpoint is kept here for now to prevent a breaking change.
153
+ // TODO: We should remove this in the next major release so we do not have a hard coded proxy path inside commerce-sdk-react
151
154
  const baseUrl = config.proxy.split(_constant.MOBIFY_PATH)[0];
152
155
  const privateClientEndpoint = `${baseUrl}${_constant.SLAS_PRIVATE_PROXY_PATH}`;
153
156
  this.client = new _commerceSdkIsomorphic.ShopperLogin({
154
- proxy: config.enablePWAKitPrivateClient ? privateClientEndpoint : config.proxy,
157
+ proxy: config.enablePWAKitPrivateClient ? config.privateClientProxyEndpoint ? config.privateClientProxyEndpoint : privateClientEndpoint : config.proxy,
155
158
  parameters: {
156
159
  clientId: config.clientId,
157
160
  organizationId: config.organizationId,
@@ -224,7 +227,11 @@ class Auth {
224
227
  this.silenceWarnings = config.silenceWarnings || false;
225
228
  this.isPrivate = !!this.clientSecret;
226
229
  const passwordlessLoginCallbackURI = config.passwordlessLoginCallbackURI;
227
- this.passwordlessLoginCallbackURI = passwordlessLoginCallbackURI ? (0, _utils.isAbsoluteUrl)(passwordlessLoginCallbackURI) ? passwordlessLoginCallbackURI : `${baseUrl}${passwordlessLoginCallbackURI}` : '';
230
+ this.passwordlessLoginCallbackURI = passwordlessLoginCallbackURI ? (0, _utils.isAbsoluteUrl)(passwordlessLoginCallbackURI) ? passwordlessLoginCallbackURI :
231
+ // This fallback does not take into account the envBasePath feature
232
+ // To set an env base path, config.passwordlessLoginCallbackURI must be an absolute url
233
+ `${baseUrl}${passwordlessLoginCallbackURI}` : '';
234
+ this.hybridAuthEnabled = config.hybridAuthEnabled || false;
228
235
  }
229
236
  get(name) {
230
237
  const {
@@ -407,9 +414,33 @@ class Auth {
407
414
  customerId,
408
415
  usid
409
416
  } = this.parseSlasJWT(sfraAuthToken);
417
+
418
+ /**
419
+ * This if block is only executed in a hybrid setup when the cc-at cookie is set.
420
+ * If the login state of the shopper changes on SFRA, the "refresh_token_expires_in"
421
+ * will change and the updated value is not propagated back to PWA Kit via cookies or cc-at token.
422
+ * This results in the "refresh_token_expires_in" to be incorrect so we can't read it from localStorage.
423
+ * We must instead read the login state by decoding the cc-at token and rely on the default values for the guest or registered user.
424
+ * This in worst cases will cause the usid cookie to expire a few hours after the refreshToken which should be acceptable given
425
+ * a few hours are insignificant compared tothe overall validty of the refreshToken.
426
+ */
427
+ const refreshTokenExpiresIn = isGuest ? DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL : DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL;
428
+ const refreshTokenTTLValue = this.getRefreshTokenCookieTTLValue(refreshTokenExpiresIn, isGuest);
429
+ const expiresDate = this.convertSecondsToDate(refreshTokenTTLValue);
410
430
  this.set('access_token', sfraAuthToken);
411
431
  this.set('customer_id', customerId);
412
- this.set('usid', usid);
432
+
433
+ /**
434
+ * The usid cookie always set when session bridging in a hybrid setup. This makes resetting the usid
435
+ * cookie here redundant. However, if the usid cookie is not set, we can have a fallback to read the usid from the accesstoken and set it.
436
+ * Setting the usid cookie conditionally ensures the usid is always set and minimizes the discrepancy between usid cookie and refresh_token cookie expiration.
437
+ */
438
+ const usidCookieValue = this.get('usid');
439
+ if (!usidCookieValue || usidCookieValue !== usid) {
440
+ this.set('usid', usid, {
441
+ expires: expiresDate
442
+ });
443
+ }
413
444
  this.set('customer_type', isGuest ? 'guest' : 'registered');
414
445
  accessToken = sfraAuthToken;
415
446
  // SFRA -> PWA access token cookie handoff is successful so we clear the SFRA made cookies.
@@ -448,6 +479,14 @@ class Auth {
448
479
  * registered shopper refresh-token and restores session and basket on SFRA.
449
480
  */
450
481
  clearECOMSession() {
482
+ /**
483
+ * If `hybridAuthEnabled` is true, dwsid cookie must not be cleared.
484
+ * This makes sure the session-bridged dwsid, received from `/oauth2/token` call on shopper login
485
+ * is NOT cleared and can be used to maintain the server affinity.
486
+ */
487
+ if (this.hybridAuthEnabled) {
488
+ return;
489
+ }
451
490
  const {
452
491
  key,
453
492
  storageType
@@ -472,9 +511,14 @@ class Auth {
472
511
  }
473
512
 
474
513
  /**
475
- * Retrieves our refresh token cookie ttl value
514
+ * Retrieves our refresh token cookie ttl value from the following sources in order:
515
+ * 1. Override value (if set)
516
+ * 2. SLAS response value (if set)
517
+ * 3. Default value (if no override or SLAS response value is set)
476
518
  */
477
- getRefreshTokenCookieTTLValue(overrideValue, responseValue, defaultValue) {
519
+ getRefreshTokenCookieTTLValue(refreshTokenExpiresInSLASValue, isGuest) {
520
+ const overrideValue = isGuest ? this.refreshTokenGuestCookieTTL : this.refreshTokenRegisteredCookieTTL;
521
+ const defaultValue = isGuest ? DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL : DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL;
478
522
  // Check if overrideValue is valid
479
523
  // if not, log warning and fall back to responseValue or defaultValue
480
524
  const isOverrideValid = typeof overrideValue === 'number' && overrideValue > 0 && overrideValue <= defaultValue;
@@ -483,7 +527,7 @@ class Auth {
483
527
  }
484
528
 
485
529
  // Return the first valid value: overrideValue (if valid), responseValue, or defaultValue
486
- return isOverrideValid ? overrideValue : responseValue || defaultValue;
530
+ return isOverrideValid ? overrideValue : refreshTokenExpiresInSLASValue || defaultValue;
487
531
  }
488
532
 
489
533
  /**
@@ -500,13 +544,9 @@ class Auth {
500
544
  this.set('id_token', res.id_token);
501
545
  this.set('idp_access_token', res.idp_access_token);
502
546
  this.set('token_type', res.token_type);
503
- this.set('usid', res.usid);
504
547
  this.set('customer_type', isGuest ? 'guest' : 'registered');
505
548
  const refreshTokenKey = isGuest ? 'refresh_token_guest' : 'refresh_token_registered';
506
- const overrideValue = isGuest ? this.refreshTokenGuestCookieTTL : this.refreshTokenRegisteredCookieTTL;
507
- const responseValue = res.refresh_token_expires_in;
508
- const defaultValue = isGuest ? DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL : DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL;
509
- const refreshTokenTTLValue = this.getRefreshTokenCookieTTLValue(overrideValue, responseValue, defaultValue);
549
+ const refreshTokenTTLValue = this.getRefreshTokenCookieTTLValue(res.refresh_token_expires_in, isGuest);
510
550
  if (res.access_token) {
511
551
  const {
512
552
  uido
@@ -518,6 +558,9 @@ class Auth {
518
558
  this.set(refreshTokenKey, res.refresh_token, {
519
559
  expires: expiresDate
520
560
  });
561
+ this.set('usid', res.usid, {
562
+ expires: expiresDate
563
+ });
521
564
  }
522
565
  refreshAccessToken() {
523
566
  var _this2 = this;
@@ -669,9 +712,32 @@ class Auth {
669
712
  customerId,
670
713
  usid
671
714
  } = _this4.parseSlasJWT(_this4.fetchedToken);
715
+
716
+ /**
717
+ * If the login state of the shopper changes on SFRA, the "refresh_token_expires_in"
718
+ * will change and the updated value is not propagated back to PWA Kit via cookies or cc-at token.
719
+ * This results in the "refresh_token_expires_in" to be incorrect so we can't read it from localStorage.
720
+ * We must instead read the login state by decoding the cc-at token and rely on the default values for the guest or registered user.
721
+ * This in worst cases will cause the usid cookie to expire a few hours after the refreshToken which should be acceptable given
722
+ * a few hours are insignificant compared tothe overall validty of the refreshToken.
723
+ */
724
+ const refreshTokenExpiresIn = isGuest ? DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL : DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL;
725
+ const refreshTokenTTLValue = _this4.getRefreshTokenCookieTTLValue(refreshTokenExpiresIn, isGuest);
726
+ const expiresDate = _this4.convertSecondsToDate(refreshTokenTTLValue);
672
727
  _this4.set('access_token', _this4.fetchedToken);
673
728
  _this4.set('customer_id', customerId);
674
- _this4.set('usid', usid);
729
+
730
+ /**
731
+ * The usid cookie always set when setting up auth in pure composable env or session bridging in a hybrid setup. This makes resetting the usid
732
+ * cookie here redundant. However, if the usid cookie is not set, we can have a fallback to read the usid from the accesstoken and set it.
733
+ * Setting the usid cookie conditionally ensures the usid is always set and minimizes the discrepancy between usid cookie and refresh_token cookie expiration.
734
+ */
735
+ const usidCookieValue = _this4.get('usid');
736
+ if (!usidCookieValue || usidCookieValue !== usid) {
737
+ _this4.set('usid', usid, {
738
+ expires: expiresDate
739
+ });
740
+ }
675
741
  _this4.set('customer_type', isGuest ? 'guest' : 'registered');
676
742
  return _this4.data;
677
743
  }
@@ -29,7 +29,9 @@ const detectStorefrontPreview = () => {
29
29
  exports.detectStorefrontPreview = detectStorefrontPreview;
30
30
  const getClientScript = () => {
31
31
  const parentOrigin = (0, _utils.getParentOrigin)() ?? 'https://runtime.commercecloud.com';
32
- return parentOrigin === _utils.DEVELOPMENT_ORIGIN ? `${parentOrigin}${_constant.LOCAL_BUNDLE_PATH}/static/storefront-preview.js` : `${parentOrigin}/cc/b2c/preview/preview.client.js`;
32
+ return parentOrigin === _utils.DEVELOPMENT_ORIGIN
33
+ // TODO: This will need to be updated to support base paths with storefront preview
34
+ ? `${parentOrigin}${_constant.LOCAL_BUNDLE_PATH}/static/storefront-preview.js` : `${parentOrigin}/cc/b2c/preview/preview.client.js`;
33
35
  };
34
36
 
35
37
  // Custom Prop Types.
package/constant.d.ts CHANGED
@@ -2,9 +2,21 @@
2
2
  * This list contains domains that can host code in iframe
3
3
  */
4
4
  export declare const IFRAME_HOST_ALLOW_LIST: readonly string[];
5
+ /**
6
+ * @deprecated
7
+ */
5
8
  export declare const MOBIFY_PATH = "/mobify";
9
+ /**
10
+ * @deprecated
11
+ */
6
12
  export declare const PROXY_PATH: string;
13
+ /**
14
+ * @deprecated
15
+ */
7
16
  export declare const LOCAL_BUNDLE_PATH: string;
17
+ /**
18
+ * @deprecated
19
+ */
8
20
  export declare const SLAS_PRIVATE_PROXY_PATH: string;
9
21
  export declare const SLAS_SECRET_WARNING_MSG = "You are potentially exposing SLAS secret on browser. Make sure to keep it safe and secure!";
10
22
  export declare const SLAS_SECRET_PLACEHOLDER = "_PLACEHOLDER_PROXY-PWA_KIT_SLAS_CLIENT_SECRET";
package/constant.js CHANGED
@@ -16,10 +16,23 @@ exports.SLAS_SECRET_WARNING_MSG = exports.SLAS_SECRET_PLACEHOLDER = exports.SLAS
16
16
  */
17
17
  const IFRAME_HOST_ALLOW_LIST = exports.IFRAME_HOST_ALLOW_LIST = Object.freeze(['https://runtime.commercecloud.com', 'https://runtime-admin-staging.mobify-storefront.com', 'https://runtime-admin-preview.mobify-storefront.com']);
18
18
 
19
- // We hardcode these here since we don't want commerce-sdk-react to have a dependency on pwa-kit-runtime
19
+ /* Deprecating the following path constants since, outside of storefront preview,
20
+ * the paths they are used for can be passed in via the provider. */
21
+ /**
22
+ * @deprecated
23
+ */
20
24
  const MOBIFY_PATH = exports.MOBIFY_PATH = '/mobify';
25
+ /**
26
+ * @deprecated
27
+ */
21
28
  const PROXY_PATH = exports.PROXY_PATH = `${MOBIFY_PATH}/proxy`;
29
+ /**
30
+ * @deprecated
31
+ */
22
32
  const LOCAL_BUNDLE_PATH = exports.LOCAL_BUNDLE_PATH = `${MOBIFY_PATH}/bundle/development`;
33
+ /**
34
+ * @deprecated
35
+ */
23
36
  const SLAS_PRIVATE_PROXY_PATH = exports.SLAS_PRIVATE_PROXY_PATH = `${MOBIFY_PATH}/slas/private`;
24
37
  const SLAS_SECRET_WARNING_MSG = exports.SLAS_SECRET_WARNING_MSG = 'You are potentially exposing SLAS secret on browser. Make sure to keep it safe and secure!';
25
38
  const SLAS_SECRET_PLACEHOLDER = exports.SLAS_SECRET_PLACEHOLDER = '_PLACEHOLDER_PROXY-PWA_KIT_SLAS_CLIENT_SECRET';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/commerce-sdk-react",
3
- "version": "3.4.0",
3
+ "version": "3.4.1-preview.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": {
@@ -40,12 +40,12 @@
40
40
  "version": "node ./scripts/version.js"
41
41
  },
42
42
  "dependencies": {
43
- "commerce-sdk-isomorphic": "^3.3.0",
43
+ "commerce-sdk-isomorphic": "^3.4.0",
44
44
  "js-cookie": "^3.0.1",
45
45
  "jwt-decode": "^4.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@salesforce/pwa-kit-dev": "3.11.0",
48
+ "@salesforce/pwa-kit-dev": "3.12.0-preview.1",
49
49
  "@tanstack/react-query": "^4.28.0",
50
50
  "@testing-library/jest-dom": "^5.16.5",
51
51
  "@testing-library/react": "^14.0.0",
@@ -60,7 +60,7 @@
60
60
  "@types/react-helmet": "~6.1.6",
61
61
  "@types/react-router-dom": "~5.3.3",
62
62
  "cross-env": "^5.2.1",
63
- "internal-lib-build": "3.11.0",
63
+ "internal-lib-build": "3.12.0-preview.1",
64
64
  "jsonwebtoken": "^9.0.0",
65
65
  "nock": "^13.3.0",
66
66
  "nodemon": "^2.0.22",
@@ -90,5 +90,5 @@
90
90
  "publishConfig": {
91
91
  "directory": "dist"
92
92
  },
93
- "gitHead": "ce537dc2e48c980ca78607e03125f9cccf8314c5"
93
+ "gitHead": "dbcfcb7cd10fcea4ee785b47f73b11a44036e7e0"
94
94
  }
package/provider.d.ts CHANGED
@@ -13,6 +13,7 @@ export interface CommerceApiProviderProps extends ApiClientConfigParams {
13
13
  headers?: Record<string, string>;
14
14
  fetchedToken?: string;
15
15
  enablePWAKitPrivateClient?: boolean;
16
+ privateClientProxyEndpoint?: string;
16
17
  clientSecret?: string;
17
18
  silenceWarnings?: boolean;
18
19
  logger?: Logger;
@@ -22,6 +23,7 @@ export interface CommerceApiProviderProps extends ApiClientConfigParams {
22
23
  refreshTokenGuestCookieTTL?: number;
23
24
  apiClients?: ApiClients;
24
25
  disableAuthInit?: boolean;
26
+ hybridAuthEnabled?: boolean;
25
27
  }
26
28
  /**
27
29
  * @internal
@@ -75,6 +77,17 @@ export declare const AuthContext: React.Context<Auth>;
75
77
  * directly to the provider. However, be careful when doing this as you will have
76
78
  * to make sure the secret is not unexpectedly exposed to the client.
77
79
  *
80
+ *
81
+ * `hybridAuthEnabled` is an optional flag that indicates the current Site has Hybrid Auth enabled.
82
+ * This drives the behavior of the `clearECOMSession` method. If `hybridAuthEnabled` is true,
83
+ * the `clearECOMSession` method will not be called. This makes sure the session-bridged dwsid, received from `/oauth2/token` call
84
+ * on shopper login is NOT cleared and can be used to maintain the server affinity.
85
+ *
86
+ * `hybridAuthEnabled` flag can also be used to drive other Hybrid Auth specific behaviors in the future.
87
+ *
88
+ * Note: `hybridAuthEnabled` should NOT be set to true for hybrid storefronts using Plugin SLAS as we need the dwsid to be deleted
89
+ * to force session-bridging on SFRA as in this case, the `oauth2/token` call does not return a dwsid.
90
+ *
78
91
  * @returns Provider to wrap your app with
79
92
  */
80
93
  declare const CommerceApiProvider: (props: CommerceApiProviderProps) => ReactElement;
package/provider.js CHANGED
@@ -79,6 +79,17 @@ const AuthContext = exports.AuthContext = /*#__PURE__*/_react.default.createCont
79
79
  * Non-PWA Kit users can enable private client mode by passing in a client secret
80
80
  * directly to the provider. However, be careful when doing this as you will have
81
81
  * to make sure the secret is not unexpectedly exposed to the client.
82
+ *
83
+ *
84
+ * `hybridAuthEnabled` is an optional flag that indicates the current Site has Hybrid Auth enabled.
85
+ * This drives the behavior of the `clearECOMSession` method. If `hybridAuthEnabled` is true,
86
+ * the `clearECOMSession` method will not be called. This makes sure the session-bridged dwsid, received from `/oauth2/token` call
87
+ * on shopper login is NOT cleared and can be used to maintain the server affinity.
88
+ *
89
+ * `hybridAuthEnabled` flag can also be used to drive other Hybrid Auth specific behaviors in the future.
90
+ *
91
+ * Note: `hybridAuthEnabled` should NOT be set to true for hybrid storefronts using Plugin SLAS as we need the dwsid to be deleted
92
+ * to force session-bridging on SFRA as in this case, the `oauth2/token` call does not return a dwsid.
82
93
  *
83
94
  * @returns Provider to wrap your app with
84
95
  */
@@ -97,6 +108,7 @@ const CommerceApiProvider = props => {
97
108
  currency,
98
109
  fetchedToken,
99
110
  enablePWAKitPrivateClient,
111
+ privateClientProxyEndpoint,
100
112
  clientSecret,
101
113
  silenceWarnings,
102
114
  logger,
@@ -105,7 +117,8 @@ const CommerceApiProvider = props => {
105
117
  refreshTokenRegisteredCookieTTL,
106
118
  refreshTokenGuestCookieTTL,
107
119
  apiClients,
108
- disableAuthInit = false
120
+ disableAuthInit = false,
121
+ hybridAuthEnabled = false
109
122
  } = props;
110
123
 
111
124
  // Set the logger based on provided configuration, or default to the console object if no logger is provided
@@ -121,15 +134,17 @@ const CommerceApiProvider = props => {
121
134
  fetchOptions,
122
135
  fetchedToken,
123
136
  enablePWAKitPrivateClient,
137
+ privateClientProxyEndpoint,
124
138
  clientSecret,
125
139
  silenceWarnings,
126
140
  logger: configLogger,
127
141
  defaultDnt,
128
142
  passwordlessLoginCallbackURI,
129
143
  refreshTokenRegisteredCookieTTL,
130
- refreshTokenGuestCookieTTL
144
+ refreshTokenGuestCookieTTL,
145
+ hybridAuthEnabled
131
146
  });
132
- }, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, enablePWAKitPrivateClient, clientSecret, silenceWarnings, configLogger, defaultDnt, passwordlessLoginCallbackURI, refreshTokenRegisteredCookieTTL, refreshTokenGuestCookieTTL, apiClients]);
147
+ }, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, enablePWAKitPrivateClient, privateClientProxyEndpoint, clientSecret, silenceWarnings, configLogger, defaultDnt, passwordlessLoginCallbackURI, refreshTokenRegisteredCookieTTL, refreshTokenGuestCookieTTL, apiClients, hybridAuthEnabled]);
133
148
  const dwsid = auth.get(_constant.DWSID_COOKIE_NAME);
134
149
  const serverAffinityHeader = {};
135
150
  if (dwsid) {
@@ -176,6 +191,12 @@ const CommerceApiProvider = props => {
176
191
  throwOnBadResponse: true,
177
192
  fetchOptions
178
193
  };
194
+
195
+ // Special proxy endpoint for injecting SLAS private client secret.
196
+ // This is only used by the ShopperLogin API as that is the only one that interacts with SLAS.
197
+ // We prioritize config.privateClientProxyEndpoint since that allows us to use the new envBasePath feature
198
+ // The preexisting hard coded privateClientEndpoint is kept here for now to prevent a breaking change.
199
+ // TODO: We should remove this in the next major release so we do not have a hard coded proxy path inside commerce-sdk-react
179
200
  const baseUrl = config.proxy.split(_constant.MOBIFY_PATH)[0];
180
201
  const privateClientEndpoint = `${baseUrl}${_constant.SLAS_PRIVATE_PROXY_PATH}`;
181
202
  return {
@@ -185,7 +206,7 @@ const CommerceApiProvider = props => {
185
206
  shopperExperience: new _commerceSdkIsomorphic.ShopperExperience(config),
186
207
  shopperGiftCertificates: new _commerceSdkIsomorphic.ShopperGiftCertificates(config),
187
208
  shopperLogin: new _commerceSdkIsomorphic.ShopperLogin(_objectSpread(_objectSpread({}, config), {}, {
188
- proxy: enablePWAKitPrivateClient ? privateClientEndpoint : config.proxy
209
+ proxy: enablePWAKitPrivateClient ? privateClientProxyEndpoint ? privateClientProxyEndpoint : privateClientEndpoint : config.proxy
189
210
  })),
190
211
  shopperOrders: new _commerceSdkIsomorphic.ShopperOrders(config),
191
212
  shopperProducts: new _commerceSdkIsomorphic.ShopperProducts(config),