@salesforce/commerce-sdk-react 3.4.0-preview.1 → 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 +10 -1
- package/auth/index.d.ts +7 -1
- package/auth/index.js +79 -13
- package/components/StorefrontPreview/utils.js +3 -1
- package/constant.d.ts +12 -0
- package/constant.js +14 -1
- package/package.json +5 -5
- package/provider.d.ts +13 -0
- package/provider.js +25 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
## v3.4.
|
|
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
|
+
|
|
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 :
|
|
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
|
-
|
|
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(
|
|
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 :
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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": "
|
|
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),
|