@salesforce/commerce-sdk-react 1.4.0-dev → 1.4.0-dev.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.
- package/CHANGELOG.md +3 -2
- package/README.md +62 -1
- package/auth/index.d.ts +21 -14
- package/auth/index.js +126 -53
- package/auth/storage/cookie.js +25 -1
- package/components/StorefrontPreview/storefront-preview.js +20 -0
- package/components/StorefrontPreview/utils.d.ts +6 -0
- package/components/StorefrontPreview/utils.js +20 -6
- package/constant.d.ts +3 -0
- package/constant.js +5 -2
- package/package.json +4 -4
- package/provider.d.ts +12 -0
- package/provider.js +23 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
## v1.4.0-dev (Mar 26, 2024)
|
|
2
|
-
## v3.5.0-alpha.0 (Mar 26, 2024)
|
|
3
1
|
## v1.4.0-dev (Jan 22, 2024)
|
|
2
|
+
|
|
3
|
+
- Add Support for SLAS private flow [#1722](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1722)
|
|
4
4
|
- Fix invalid query params warnings and allow custom query [#1655](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1655)
|
|
5
5
|
- Fix cannot read properties of undefined (reading 'unshift') [#1689](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1689)
|
|
6
6
|
- Add Shopper SEO hook [#1688](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1688)
|
|
7
7
|
- Update useLocalStorage implementation to be more responsive [#1703](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1703)
|
|
8
|
+
- Storefront Preview: avoid stale cached Commerce API responses, whenever the Shopper Context is set [#1701](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/1701)
|
|
8
9
|
|
|
9
10
|
## v1.3.0 (Jan 19, 2024)
|
|
10
11
|
|
package/README.md
CHANGED
|
@@ -112,6 +112,67 @@ _💡 This section assumes you have read and completed the [Authorization for Sh
|
|
|
112
112
|
|
|
113
113
|
To help reduce boilerplate code for managing shopper authentication, by default, this library automatically initializes shopper session and manages the tokens for developers. Currently, the library supports the [Public Client login flow](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-public-client.html).
|
|
114
114
|
|
|
115
|
+
Commerce-react-sdk supports both public and private flow of the [Authorization for Shopper APIs](https://developer.salesforce.com/docs/commerce/commerce-api/guide/authorization-for-shopper-apis.html) guide._
|
|
116
|
+
You can choose to use either public or private slas to login. By default, public flow is enabled.
|
|
117
|
+
|
|
118
|
+
#### How private SLAS works
|
|
119
|
+
This section assumes you read and understand how [private SLAS](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-private-client.html) flow works
|
|
120
|
+
|
|
121
|
+
To enable private slas flow, you need to pass your secret into the CommercerProvider via clientSecret prop.
|
|
122
|
+
**Note** You should only use private slas if you know you can secure your secret since commercer-sdk-react runs isomorphically.
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
// app/components/_app-config/index.jsx
|
|
126
|
+
|
|
127
|
+
import {CommerceApiProvider} from '@salesforce/commerce-sdk-react'
|
|
128
|
+
import {withReactQuery} from '@salesforce/pwa-kit-react-sdk/ssr/universal/components/with-react-query'
|
|
129
|
+
|
|
130
|
+
const AppConfig = ({children}) => {
|
|
131
|
+
return (
|
|
132
|
+
<CommerceApiProvider
|
|
133
|
+
clientId="12345678-1234-1234-1234-123412341234"
|
|
134
|
+
organizationId="f_ecom_aaaa_001"
|
|
135
|
+
proxy="localhost:3000/mobify/proxy/api"
|
|
136
|
+
redirectURI="localhost:3000/callback"
|
|
137
|
+
siteId="RefArch"
|
|
138
|
+
shortCode="12345678"
|
|
139
|
+
locale="en-US"
|
|
140
|
+
currency="USD"
|
|
141
|
+
clientSecret="<your-slas-private-secret>"
|
|
142
|
+
>
|
|
143
|
+
{children}
|
|
144
|
+
</CommerceApiProvider>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
#### Disable slas private warnings
|
|
149
|
+
By default, a warning as below will be displayed on client side to remind developers to always keep their secret safe and secured.
|
|
150
|
+
```js
|
|
151
|
+
'You are potentially exposing SLAS secret on browser. Make sure to keep it safe and secure!'
|
|
152
|
+
```
|
|
153
|
+
You can disable this warning by using CommerceProvider prop `silenceWarnings`
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
const AppConfig = ({children}) => {
|
|
157
|
+
return (
|
|
158
|
+
<CommerceApiProvider
|
|
159
|
+
clientId="12345678-1234-1234-1234-123412341234"
|
|
160
|
+
organizationId="f_ecom_aaaa_001"
|
|
161
|
+
proxy="localhost:3000/mobify/proxy/api"
|
|
162
|
+
redirectURI="localhost:3000/callback"
|
|
163
|
+
siteId="RefArch"
|
|
164
|
+
shortCode="12345678"
|
|
165
|
+
locale="en-US"
|
|
166
|
+
currency="USD"
|
|
167
|
+
clientSecret="<your-slas-private-secret>"
|
|
168
|
+
silenceWarnings={true}
|
|
169
|
+
>
|
|
170
|
+
{children}
|
|
171
|
+
</CommerceApiProvider>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
115
176
|
### Shopper Session Initialization
|
|
116
177
|
|
|
117
178
|
On `CommerceApiProvider` mount, the provider initializes shopper session by initiating the SLAS **Public Client** login flow. The tokens are stored/managed/refreshed by the library.
|
|
@@ -121,7 +182,6 @@ On `CommerceApiProvider` mount, the provider initializes shopper session by init
|
|
|
121
182
|
While the library is fetching/refreshing the access token, the network requests will queue up until there is a valid access token.
|
|
122
183
|
|
|
123
184
|
### Login helpers
|
|
124
|
-
|
|
125
185
|
To leverage the managed shopper authentication feature, use the `useAuthHelper` hook for shopper login.
|
|
126
186
|
|
|
127
187
|
Example:
|
|
@@ -144,6 +204,7 @@ const Example = () => {
|
|
|
144
204
|
|
|
145
205
|
You have the option of handling shopper authentication externally, by providing a SLAS access token. This is useful if you plan on using this library in an application where the authentication mechanism is different.
|
|
146
206
|
|
|
207
|
+
|
|
147
208
|
```jsx
|
|
148
209
|
const MyComponent = ({children}) => {
|
|
149
210
|
return <CommerceApiProvider fetchedToken="xxxxxxxxxxxx">{children}</CommerceApiProvider>
|
package/auth/index.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ interface AuthConfig extends ApiClientConfigParams {
|
|
|
9
9
|
fetchOptions?: ShopperLoginTypes.FetchOptions;
|
|
10
10
|
fetchedToken?: string;
|
|
11
11
|
OCAPISessionsURL?: string;
|
|
12
|
+
enablePWAKitPrivateClient?: boolean;
|
|
13
|
+
clientSecret?: string;
|
|
14
|
+
silenceWarnings?: boolean;
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
17
|
* The extended field is not from api response, we manually store the auth type,
|
|
@@ -21,7 +24,7 @@ export type AuthData = Prettify<RemoveStringIndex<TokenResponse> & {
|
|
|
21
24
|
idp_access_token: string;
|
|
22
25
|
}>;
|
|
23
26
|
/** A shopper could be guest or registered, so we store the refresh tokens individually. */
|
|
24
|
-
type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered' | '
|
|
27
|
+
type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered' | 'access_token_sfra';
|
|
25
28
|
/**
|
|
26
29
|
* This class is used to handle shopper authentication.
|
|
27
30
|
* It is responsible for initializing shopper session, manage access
|
|
@@ -38,6 +41,8 @@ declare class Auth {
|
|
|
38
41
|
private stores;
|
|
39
42
|
private fetchedToken;
|
|
40
43
|
private OCAPISessionsURL;
|
|
44
|
+
private clientSecret;
|
|
45
|
+
private silenceWarnings;
|
|
41
46
|
constructor(config: AuthConfig);
|
|
42
47
|
get(name: AuthDataKeys): string;
|
|
43
48
|
private set;
|
|
@@ -51,20 +56,21 @@ declare class Auth {
|
|
|
51
56
|
*/
|
|
52
57
|
private isTokenExpired;
|
|
53
58
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* @returns {
|
|
59
|
+
* Returns the SLAS access token or an empty string if the access token
|
|
60
|
+
* is not found in local store or if SFRA wants PWA to trigger refresh token login.
|
|
61
|
+
*
|
|
62
|
+
* On PWA-only sites, this returns the access token from local storage.
|
|
63
|
+
* On Hybrid sites, this checks whether SFRA has sent an auth token via cookies.
|
|
64
|
+
* Returns an access token from SFRA if it exist.
|
|
65
|
+
* If not, the access token from local store is returned.
|
|
66
|
+
*
|
|
67
|
+
* This is only used within this Auth module since other modules consider the access
|
|
68
|
+
* token from this.get('access_token') to be the source of truth.
|
|
69
|
+
*
|
|
70
|
+
* @returns {string} access token
|
|
66
71
|
*/
|
|
67
|
-
private
|
|
72
|
+
private getAccessToken;
|
|
73
|
+
private clearSFRAAuthToken;
|
|
68
74
|
/**
|
|
69
75
|
* This method stores the TokenResponse object retrived from SLAS, and
|
|
70
76
|
* store the data in storage.
|
|
@@ -78,6 +84,7 @@ declare class Auth {
|
|
|
78
84
|
* @Internal
|
|
79
85
|
*/
|
|
80
86
|
queueRequest(fn: () => Promise<TokenResponse>, isGuest: boolean): Promise<ShopperLoginTypes.TokenResponse>;
|
|
87
|
+
logWarning: (msg: string) => void;
|
|
81
88
|
/**
|
|
82
89
|
* The ready function returns a promise that resolves with valid ShopperLogin
|
|
83
90
|
* token response.
|
package/auth/index.js
CHANGED
|
@@ -8,6 +8,7 @@ var _commerceSdkIsomorphic = require("commerce-sdk-isomorphic");
|
|
|
8
8
|
var _jwtDecode = require("jwt-decode");
|
|
9
9
|
var _storage = require("./storage");
|
|
10
10
|
var _utils = require("../utils");
|
|
11
|
+
var _constant = require("../constant");
|
|
11
12
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
13
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
14
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -87,27 +88,25 @@ const DATA_MAP = {
|
|
|
87
88
|
storageType: 'local',
|
|
88
89
|
key: 'refresh_token_expires_in'
|
|
89
90
|
},
|
|
90
|
-
// For Hybrid setups, we need a mechanism to inform PWA Kit whenever customer login state changes on SFRA.
|
|
91
|
-
// So we maintain a copy of the refersh_tokens in the local storage which is compared to the actual refresh_token stored in cookie storage.
|
|
92
|
-
// If the key or value of the refresh_token in local storage is different from the one in cookie storage, this indicates a change in customer auth state and we invalidate the access_token in PWA Kit.
|
|
93
|
-
// This triggers a new fetch for access_token using the current refresh_token from cookie storage and makes sure customer auth state is always in sync between SFRA and PWA sites in a hybrid setup.
|
|
94
|
-
refresh_token_guest_copy: {
|
|
95
|
-
storageType: 'local',
|
|
96
|
-
key: isParentTrusted ? 'cc-nx-g-iframe' : 'cc-nx-g',
|
|
97
|
-
callback: store => {
|
|
98
|
-
store.delete(isParentTrusted ? 'cc-nx-iframe' : 'cc-nx');
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
refresh_token_registered_copy: {
|
|
102
|
-
storageType: 'local',
|
|
103
|
-
key: isParentTrusted ? 'cc-nx-iframe' : 'cc-nx',
|
|
104
|
-
callback: store => {
|
|
105
|
-
store.delete(isParentTrusted ? 'cc-nx-g-iframe' : 'cc-nx-g');
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
91
|
customer_type: {
|
|
109
92
|
storageType: 'local',
|
|
110
93
|
key: 'customer_type'
|
|
94
|
+
},
|
|
95
|
+
/*
|
|
96
|
+
* For Hybrid setups, we need a mechanism to inform PWA Kit whenever customer login state changes on SFRA.
|
|
97
|
+
* We do this by having SFRA store the access token in cookies. If these cookies are present, PWA
|
|
98
|
+
* compares the access token from the cookie with the one in local store. If the tokens are different,
|
|
99
|
+
* discard the access token in local store and replace it with the access token from the cookie.
|
|
100
|
+
*
|
|
101
|
+
* ECOM has a 1200 character limit on the values of cookies. The access token easily exceeds this amount
|
|
102
|
+
* so it sends the access token in chunks across several cookies.
|
|
103
|
+
*
|
|
104
|
+
* The JWT tends to come in at around 2250 characters so there's usually
|
|
105
|
+
* both a cc-at and cc-at_2.
|
|
106
|
+
*/
|
|
107
|
+
access_token_sfra: {
|
|
108
|
+
storageType: 'cookie',
|
|
109
|
+
key: 'cc-at'
|
|
111
110
|
}
|
|
112
111
|
};
|
|
113
112
|
|
|
@@ -121,8 +120,11 @@ const DATA_MAP = {
|
|
|
121
120
|
*/
|
|
122
121
|
class Auth {
|
|
123
122
|
constructor(config) {
|
|
123
|
+
// Special endpoint for injecting SLAS private client secret
|
|
124
|
+
const baseUrl = config.proxy.split(`/mobify/proxy/api`)[0];
|
|
125
|
+
const privateClientEndpoint = `${baseUrl}/mobify/scapi/shopper/auth`;
|
|
124
126
|
this.client = new _commerceSdkIsomorphic.ShopperLogin({
|
|
125
|
-
proxy: config.proxy,
|
|
127
|
+
proxy: config.enablePWAKitPrivateClient ? privateClientEndpoint : config.proxy,
|
|
126
128
|
parameters: {
|
|
127
129
|
clientId: config.clientId,
|
|
128
130
|
organizationId: config.organizationId,
|
|
@@ -156,6 +158,35 @@ class Auth {
|
|
|
156
158
|
this.redirectURI = config.redirectURI;
|
|
157
159
|
this.fetchedToken = config.fetchedToken || '';
|
|
158
160
|
this.OCAPISessionsURL = config.OCAPISessionsURL || '';
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* There are 2 ways to enable SLAS private client mode.
|
|
164
|
+
* If enablePWAKitPrivateClient=true, we route SLAS calls to /mobify/scapi/shopper/auth
|
|
165
|
+
* and set an internal placeholder as the client secret. The proxy will override the placeholder
|
|
166
|
+
* with the actual client secret so any truthy value as the placeholder works here.
|
|
167
|
+
*
|
|
168
|
+
* If enablePWAKitPrivateClient=false and clientSecret is provided as a non-empty string,
|
|
169
|
+
* private client mode is enabled but we don't route calls to /mobify/scapi/shopper/auth
|
|
170
|
+
* This is how non-PWA Kit consumers of commerce-sdk-react can enable private client and set a secret
|
|
171
|
+
*
|
|
172
|
+
* If both enablePWAKitPrivateClient and clientSecret are truthy, enablePWAKitPrivateClient takes
|
|
173
|
+
* priority and we ignore whatever was set for clientSecret. This prints a warning about the clientSecret
|
|
174
|
+
* being ignored.
|
|
175
|
+
*
|
|
176
|
+
* If both enablePWAKitPrivateClient and clientSecret are falsey, we are in SLAS public client mode.
|
|
177
|
+
*/
|
|
178
|
+
if (config.enablePWAKitPrivateClient && config.clientSecret) {
|
|
179
|
+
this.logWarning(_constant.SLAS_SECRET_OVERRIDE_MSG);
|
|
180
|
+
}
|
|
181
|
+
this.clientSecret = config.enablePWAKitPrivateClient ?
|
|
182
|
+
// PWA proxy is enabled, assume project is PWA and that the proxy will handle setting the secret
|
|
183
|
+
// We can pass any truthy value here to satisfy commerce-sdk-isomorphic requirements
|
|
184
|
+
_constant.SLAS_SECRET_PLACEHOLDER :
|
|
185
|
+
// We think there are users of Commerce SDK React and Commerce SDK isomorphic outside of PWA
|
|
186
|
+
// For these users to use a private client, they must have some way to set a client secret
|
|
187
|
+
// PWA users should not need to touch this.
|
|
188
|
+
config.clientSecret || '';
|
|
189
|
+
this.silenceWarnings = config.silenceWarnings || false;
|
|
159
190
|
}
|
|
160
191
|
get(name) {
|
|
161
192
|
const {
|
|
@@ -221,29 +252,56 @@ class Auth {
|
|
|
221
252
|
}
|
|
222
253
|
|
|
223
254
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
255
|
+
* Returns the SLAS access token or an empty string if the access token
|
|
256
|
+
* is not found in local store or if SFRA wants PWA to trigger refresh token login.
|
|
257
|
+
*
|
|
258
|
+
* On PWA-only sites, this returns the access token from local storage.
|
|
259
|
+
* On Hybrid sites, this checks whether SFRA has sent an auth token via cookies.
|
|
260
|
+
* Returns an access token from SFRA if it exist.
|
|
261
|
+
* If not, the access token from local store is returned.
|
|
262
|
+
*
|
|
263
|
+
* This is only used within this Auth module since other modules consider the access
|
|
264
|
+
* token from this.get('access_token') to be the source of truth.
|
|
265
|
+
*
|
|
266
|
+
* @returns {string} access token
|
|
230
267
|
*/
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
if (
|
|
235
|
-
|
|
268
|
+
getAccessToken() {
|
|
269
|
+
let accessToken = this.get('access_token');
|
|
270
|
+
const sfraAuthToken = this.get('access_token_sfra');
|
|
271
|
+
if (sfraAuthToken) {
|
|
272
|
+
/*
|
|
273
|
+
* If SFRA sends 'refresh', we return an empty token here so PWA can trigger a login refresh
|
|
274
|
+
* This key is used when logout is triggered in SFRA but the redirect after logout
|
|
275
|
+
* sends the user to PWA.
|
|
276
|
+
*/
|
|
277
|
+
if (sfraAuthToken === 'refresh') {
|
|
278
|
+
this.set('access_token', '');
|
|
279
|
+
this.clearSFRAAuthToken();
|
|
280
|
+
return '';
|
|
281
|
+
}
|
|
282
|
+
const {
|
|
283
|
+
isGuest,
|
|
284
|
+
customerId,
|
|
285
|
+
usid
|
|
286
|
+
} = this.parseSlasJWT(sfraAuthToken);
|
|
287
|
+
this.set('access_token', sfraAuthToken);
|
|
288
|
+
this.set('customer_id', customerId);
|
|
289
|
+
this.set('usid', usid);
|
|
290
|
+
this.set('customer_type', isGuest ? 'guest' : 'registered');
|
|
291
|
+
accessToken = sfraAuthToken;
|
|
292
|
+
// SFRA -> PWA access token cookie handoff is succesful so we clear the SFRA made cookies.
|
|
293
|
+
// We don't want these cookies to persist and continue overriding what is in local store.
|
|
294
|
+
this.clearSFRAAuthToken();
|
|
236
295
|
}
|
|
237
|
-
return
|
|
296
|
+
return accessToken;
|
|
238
297
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return !this.isTokenExpired(token) && !this.hasSFRAAuthStateChanged();
|
|
298
|
+
clearSFRAAuthToken() {
|
|
299
|
+
const {
|
|
300
|
+
key,
|
|
301
|
+
storageType
|
|
302
|
+
} = DATA_MAP['access_token_sfra'];
|
|
303
|
+
const store = this.stores[storageType];
|
|
304
|
+
store.delete(key);
|
|
247
305
|
}
|
|
248
306
|
|
|
249
307
|
/**
|
|
@@ -261,13 +319,9 @@ class Auth {
|
|
|
261
319
|
this.set('usid', res.usid);
|
|
262
320
|
this.set('customer_type', isGuest ? 'guest' : 'registered');
|
|
263
321
|
const refreshTokenKey = isGuest ? 'refresh_token_guest' : 'refresh_token_registered';
|
|
264
|
-
const refreshTokenCopyKey = isGuest ? 'refresh_token_guest_copy' : 'refresh_token_registered_copy';
|
|
265
322
|
this.set(refreshTokenKey, res.refresh_token, {
|
|
266
323
|
expires: res.refresh_token_expires_in
|
|
267
324
|
});
|
|
268
|
-
this.set(refreshTokenCopyKey, res.refresh_token, {
|
|
269
|
-
expires: res.refresh_token_expires_in
|
|
270
|
-
});
|
|
271
325
|
}
|
|
272
326
|
|
|
273
327
|
/**
|
|
@@ -297,6 +351,11 @@ class Auth {
|
|
|
297
351
|
return yield _this.pendingToken;
|
|
298
352
|
})();
|
|
299
353
|
}
|
|
354
|
+
logWarning = msg => {
|
|
355
|
+
if (!this.silenceWarnings) {
|
|
356
|
+
console.warn(msg);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
300
359
|
|
|
301
360
|
/**
|
|
302
361
|
* The ready function returns a promise that resolves with valid ShopperLogin
|
|
@@ -327,8 +386,8 @@ class Auth {
|
|
|
327
386
|
if (_this2.pendingToken) {
|
|
328
387
|
return yield _this2.pendingToken;
|
|
329
388
|
}
|
|
330
|
-
const accessToken = _this2.
|
|
331
|
-
if (accessToken && _this2.
|
|
389
|
+
const accessToken = _this2.getAccessToken();
|
|
390
|
+
if (accessToken && !_this2.isTokenExpired(accessToken)) {
|
|
332
391
|
return _this2.data;
|
|
333
392
|
}
|
|
334
393
|
const refreshTokenRegistered = _this2.get('refresh_token_registered');
|
|
@@ -338,6 +397,8 @@ class Auth {
|
|
|
338
397
|
try {
|
|
339
398
|
return yield _this2.queueRequest(() => _commerceSdkIsomorphic.helpers.refreshAccessToken(_this2.client, {
|
|
340
399
|
refreshToken
|
|
400
|
+
}, {
|
|
401
|
+
clientSecret: _this2.clientSecret
|
|
341
402
|
}), !!refreshTokenGuest);
|
|
342
403
|
} catch (error) {
|
|
343
404
|
// If the refresh token is invalid, we need to re-login the user
|
|
@@ -353,9 +414,7 @@ class Auth {
|
|
|
353
414
|
}
|
|
354
415
|
}
|
|
355
416
|
}
|
|
356
|
-
return
|
|
357
|
-
redirectURI: _this2.redirectURI
|
|
358
|
-
}), true);
|
|
417
|
+
return _this2.loginGuestUser();
|
|
359
418
|
})();
|
|
360
419
|
}
|
|
361
420
|
|
|
@@ -379,14 +438,23 @@ class Auth {
|
|
|
379
438
|
loginGuestUser() {
|
|
380
439
|
var _this4 = this;
|
|
381
440
|
return _asyncToGenerator(function* () {
|
|
382
|
-
|
|
441
|
+
if (_this4.clientSecret && (0, _utils.onClient)() && _this4.clientSecret !== _constant.SLAS_SECRET_PLACEHOLDER) {
|
|
442
|
+
_this4.logWarning(_constant.SLAS_SECRET_WARNING_MSG);
|
|
443
|
+
}
|
|
383
444
|
const usid = _this4.get('usid');
|
|
384
445
|
const isGuest = true;
|
|
385
|
-
|
|
386
|
-
|
|
446
|
+
const guestPrivateArgs = [_this4.client, _objectSpread({}, usid && {
|
|
447
|
+
usid
|
|
448
|
+
}), {
|
|
449
|
+
clientSecret: _this4.clientSecret
|
|
450
|
+
}];
|
|
451
|
+
const guestPublicArgs = [_this4.client, _objectSpread({
|
|
452
|
+
redirectURI: _this4.redirectURI
|
|
387
453
|
}, usid && {
|
|
388
454
|
usid
|
|
389
|
-
})
|
|
455
|
+
})];
|
|
456
|
+
const callback = _this4.clientSecret ? () => _commerceSdkIsomorphic.helpers.loginGuestUserPrivate(...guestPrivateArgs) : () => _commerceSdkIsomorphic.helpers.loginGuestUser(...guestPublicArgs);
|
|
457
|
+
return yield _this4.queueRequest(callback, isGuest);
|
|
390
458
|
})();
|
|
391
459
|
}
|
|
392
460
|
|
|
@@ -431,10 +499,15 @@ class Auth {
|
|
|
431
499
|
loginRegisteredUserB2C(credentials) {
|
|
432
500
|
var _this6 = this;
|
|
433
501
|
return _asyncToGenerator(function* () {
|
|
502
|
+
if (_this6.clientSecret && (0, _utils.onClient)() && _this6.clientSecret !== _constant.SLAS_SECRET_PLACEHOLDER) {
|
|
503
|
+
_this6.logWarning(_constant.SLAS_SECRET_WARNING_MSG);
|
|
504
|
+
}
|
|
434
505
|
const redirectURI = _this6.redirectURI;
|
|
435
506
|
const usid = _this6.get('usid');
|
|
436
507
|
const isGuest = false;
|
|
437
|
-
const token = yield _commerceSdkIsomorphic.helpers.loginRegisteredUserB2C(_this6.client, credentials,
|
|
508
|
+
const token = yield _commerceSdkIsomorphic.helpers.loginRegisteredUserB2C(_this6.client, _objectSpread(_objectSpread({}, credentials), {}, {
|
|
509
|
+
clientSecret: _this6.clientSecret
|
|
510
|
+
}), _objectSpread({
|
|
438
511
|
redirectURI
|
|
439
512
|
}, usid && {
|
|
440
513
|
usid
|
package/auth/storage/cookie.js
CHANGED
|
@@ -38,11 +38,35 @@ class CookieStorage extends _base.BaseStorage {
|
|
|
38
38
|
}
|
|
39
39
|
get(key) {
|
|
40
40
|
const suffixedKey = this.getSuffixedKey(key);
|
|
41
|
-
|
|
41
|
+
let value = _jsCookie.default.get(suffixedKey) || '';
|
|
42
|
+
if (value) {
|
|
43
|
+
// Some values, like the access token, may be split
|
|
44
|
+
// across multiple keys to fit under ECOM cookie size
|
|
45
|
+
// thresholds. We check for and append additional chunks here.
|
|
46
|
+
let chunk = 2;
|
|
47
|
+
let additionalPart = _jsCookie.default.get(`${suffixedKey}_${chunk}`);
|
|
48
|
+
while (additionalPart) {
|
|
49
|
+
value = value.concat(additionalPart);
|
|
50
|
+
chunk++;
|
|
51
|
+
additionalPart = _jsCookie.default.get(`${suffixedKey}_${chunk}`) || '';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
42
55
|
}
|
|
43
56
|
delete(key, options) {
|
|
44
57
|
const suffixedKey = this.getSuffixedKey(key);
|
|
45
58
|
_jsCookie.default.remove(suffixedKey, _objectSpread(_objectSpread({}, (0, _utils.getDefaultCookieAttributes)()), options));
|
|
59
|
+
|
|
60
|
+
// Some values, like the access token, may be split
|
|
61
|
+
// across multiple keys to fit under ECOM cookie size
|
|
62
|
+
// thresholds. We check for and delete additional chunks here.
|
|
63
|
+
let chunk = 2;
|
|
64
|
+
let additionalPart = _jsCookie.default.get(`${suffixedKey}_${chunk}`);
|
|
65
|
+
while (additionalPart) {
|
|
66
|
+
_jsCookie.default.remove(`${suffixedKey}_${chunk}`, _objectSpread(_objectSpread({}, (0, _utils.getDefaultCookieAttributes)()), options));
|
|
67
|
+
chunk++;
|
|
68
|
+
additionalPart = _jsCookie.default.get(`${suffixedKey}_${chunk}`) || '';
|
|
69
|
+
}
|
|
46
70
|
}
|
|
47
71
|
}
|
|
48
72
|
exports.CookieStorage = CookieStorage;
|
|
@@ -9,6 +9,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
9
9
|
var _reactHelmet = require("react-helmet");
|
|
10
10
|
var _utils = require("./utils");
|
|
11
11
|
var _reactRouterDom = require("react-router-dom");
|
|
12
|
+
var _hooks = require("../../hooks");
|
|
12
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
14
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
14
15
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
@@ -36,6 +37,7 @@ const StorefrontPreview = ({
|
|
|
36
37
|
}) => {
|
|
37
38
|
const history = (0, _reactRouterDom.useHistory)();
|
|
38
39
|
const isHostTrusted = (0, _utils.detectStorefrontPreview)();
|
|
40
|
+
const apiClients = (0, _hooks.useCommerceApi)();
|
|
39
41
|
(0, _react.useEffect)(() => {
|
|
40
42
|
if (enabled && isHostTrusted) {
|
|
41
43
|
window.STOREFRONT_PREVIEW = _objectSpread(_objectSpread({}, window.STOREFRONT_PREVIEW), {}, {
|
|
@@ -47,6 +49,24 @@ const StorefrontPreview = ({
|
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
51
|
}, [enabled, getToken, onContextChange]);
|
|
52
|
+
(0, _react.useEffect)(() => {
|
|
53
|
+
if (enabled && isHostTrusted) {
|
|
54
|
+
// In Storefront Preview mode, add cache breaker for all SCAPI's requests.
|
|
55
|
+
// Otherwise, it's possible to get stale responses after the Shopper Context is set.
|
|
56
|
+
// (i.e. in this case, we optimize for accurate data, rather than performance/caching)
|
|
57
|
+
(0, _utils.proxyRequests)(apiClients, {
|
|
58
|
+
apply(target, thisArg, argumentsList) {
|
|
59
|
+
var _argumentsList$;
|
|
60
|
+
argumentsList[0] = _objectSpread(_objectSpread({}, argumentsList[0]), {}, {
|
|
61
|
+
parameters: _objectSpread(_objectSpread({}, (_argumentsList$ = argumentsList[0]) === null || _argumentsList$ === void 0 ? void 0 : _argumentsList$.parameters), {}, {
|
|
62
|
+
c_cache_breaker: Date.now()
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
return target.call(thisArg, ...argumentsList);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}, [apiClients, enabled]);
|
|
50
70
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, enabled && isHostTrusted && /*#__PURE__*/_react.default.createElement(_reactHelmet.Helmet, null, /*#__PURE__*/_react.default.createElement("script", {
|
|
51
71
|
id: "storefront_preview",
|
|
52
72
|
src: (0, _utils.getClientScript)(),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ApiClients } from '../../hooks/types';
|
|
1
2
|
/** Detects whether the storefront is running in an iframe as part of Storefront Preview.
|
|
2
3
|
* @private
|
|
3
4
|
*/
|
|
@@ -18,4 +19,9 @@ export declare const CustomPropTypes: {
|
|
|
18
19
|
*/
|
|
19
20
|
requiredFunctionWhenEnabled: (props: any, propName: any, componentName: any) => Error | undefined;
|
|
20
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Via the built-in Proxy object, modify the behaviour of each request for the given SCAPI clients
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
export declare const proxyRequests: (clients: ApiClients, handlers: ProxyHandler<any>) => void;
|
|
21
27
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getClientScript = exports.detectStorefrontPreview = exports.CustomPropTypes = void 0;
|
|
6
|
+
exports.proxyRequests = exports.getClientScript = exports.detectStorefrontPreview = exports.CustomPropTypes = void 0;
|
|
7
7
|
var _utils = require("../../utils");
|
|
8
8
|
/*
|
|
9
9
|
* Copyright (c) 2023, Salesforce, Inc.
|
|
@@ -35,10 +35,10 @@ const CustomPropTypes = exports.CustomPropTypes = {
|
|
|
35
35
|
/**
|
|
36
36
|
* This custom PropType ensures that the prop is only required when the known prop
|
|
37
37
|
* "enabled" is set to "true".
|
|
38
|
-
*
|
|
39
|
-
* @param props
|
|
40
|
-
* @param propName
|
|
41
|
-
* @param componentName
|
|
38
|
+
*
|
|
39
|
+
* @param props
|
|
40
|
+
* @param propName
|
|
41
|
+
* @param componentName
|
|
42
42
|
* @returns
|
|
43
43
|
*/
|
|
44
44
|
requiredFunctionWhenEnabled: (props, propName, componentName) => {
|
|
@@ -46,4 +46,18 @@ const CustomPropTypes = exports.CustomPropTypes = {
|
|
|
46
46
|
return new Error(`${String(propName)} is a required function for ${String(componentName)} when enabled is true`);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Via the built-in Proxy object, modify the behaviour of each request for the given SCAPI clients
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
const proxyRequests = (clients, handlers) => {
|
|
56
|
+
Object.values(clients).forEach(client => {
|
|
57
|
+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(client));
|
|
58
|
+
methods.forEach(method => {
|
|
59
|
+
client[method] = new Proxy(client[method], handlers);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
exports.proxyRequests = proxyRequests;
|
package/constant.d.ts
CHANGED
|
@@ -2,4 +2,7 @@
|
|
|
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
|
+
export declare const SLAS_SECRET_WARNING_MSG = "You are potentially exposing SLAS secret on browser. Make sure to keep it safe and secure!";
|
|
6
|
+
export declare const SLAS_SECRET_PLACEHOLDER = "_PLACEHOLDER_PROXY-PWA_KIT_SLAS_CLIENT_SECRET";
|
|
7
|
+
export declare const SLAS_SECRET_OVERRIDE_MSG = "You have enabled PWA Kit Private Client mode which gets the SLAS secret from your environment variable. The SLAS secret you have set in the Auth provider will be ignored.";
|
|
5
8
|
//# sourceMappingURL=constant.d.ts.map
|
package/constant.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.IFRAME_HOST_ALLOW_LIST = void 0;
|
|
6
|
+
exports.SLAS_SECRET_WARNING_MSG = exports.SLAS_SECRET_PLACEHOLDER = exports.SLAS_SECRET_OVERRIDE_MSG = exports.IFRAME_HOST_ALLOW_LIST = void 0;
|
|
7
7
|
/*
|
|
8
8
|
* Copyright (c) 2023, Salesforce, Inc.
|
|
9
9
|
* All rights reserved.
|
|
@@ -14,4 +14,7 @@ exports.IFRAME_HOST_ALLOW_LIST = void 0;
|
|
|
14
14
|
/**
|
|
15
15
|
* This list contains domains that can host code in iframe
|
|
16
16
|
*/
|
|
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']);
|
|
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
|
+
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!';
|
|
19
|
+
const SLAS_SECRET_PLACEHOLDER = exports.SLAS_SECRET_PLACEHOLDER = '_PLACEHOLDER_PROXY-PWA_KIT_SLAS_CLIENT_SECRET';
|
|
20
|
+
const SLAS_SECRET_OVERRIDE_MSG = exports.SLAS_SECRET_OVERRIDE_MSG = 'You have enabled PWA Kit Private Client mode which gets the SLAS secret from your environment variable. The SLAS secret you have set in the Auth provider will be ignored.';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/commerce-sdk-react",
|
|
3
|
-
"version": "1.4.0-dev",
|
|
3
|
+
"version": "1.4.0-dev.1",
|
|
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": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"jwt-decode": "^4.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@salesforce/pwa-kit-dev": "3.5.0-alpha.
|
|
48
|
+
"@salesforce/pwa-kit-dev": "3.5.0-alpha.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",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@types/react-helmet": "~6.1.6",
|
|
60
60
|
"@types/react-router-dom": "~5.3.3",
|
|
61
61
|
"cross-env": "^5.2.1",
|
|
62
|
-
"internal-lib-build": "3.5.0-alpha.
|
|
62
|
+
"internal-lib-build": "3.5.0-alpha.1",
|
|
63
63
|
"jsonwebtoken": "^9.0.0",
|
|
64
64
|
"nock": "^13.3.0",
|
|
65
65
|
"nodemon": "^2.0.22",
|
|
@@ -89,5 +89,5 @@
|
|
|
89
89
|
"publishConfig": {
|
|
90
90
|
"directory": "dist"
|
|
91
91
|
},
|
|
92
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "2df9f520e6de6585926743fb72bf8e77d515dcf1"
|
|
93
93
|
}
|
package/provider.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export interface CommerceApiProviderProps extends ApiClientConfigParams {
|
|
|
12
12
|
headers?: Record<string, string>;
|
|
13
13
|
fetchedToken?: string;
|
|
14
14
|
OCAPISessionsURL?: string;
|
|
15
|
+
enablePWAKitPrivateClient?: boolean;
|
|
16
|
+
clientSecret?: string;
|
|
17
|
+
silenceWarnings?: boolean;
|
|
15
18
|
}
|
|
16
19
|
/**
|
|
17
20
|
* @internal
|
|
@@ -45,6 +48,7 @@ export declare const AuthContext: React.Context<Auth>;
|
|
|
45
48
|
siteId="RefArch"
|
|
46
49
|
shortCode="12345678"
|
|
47
50
|
locale="en-US"
|
|
51
|
+
enablePWAKitPrivateClient={true}
|
|
48
52
|
currency="USD"
|
|
49
53
|
>
|
|
50
54
|
{children}
|
|
@@ -54,6 +58,14 @@ export declare const AuthContext: React.Context<Auth>;
|
|
|
54
58
|
|
|
55
59
|
export default App
|
|
56
60
|
* ```
|
|
61
|
+
* Note: The provider can enable SLAS Private Client mode in 2 ways.
|
|
62
|
+
* `enablePWAKitPrivateClient` sets commerce-sdk-react to work with the PWA proxy
|
|
63
|
+
* `/mobify/scapi/api/auth` to set the private client secret. PWA users should use
|
|
64
|
+
* this option.
|
|
65
|
+
*
|
|
66
|
+
* Non-PWA Kit users can enable private client mode by passing in a client secret
|
|
67
|
+
* directly to the provider. However, be careful when doing this as you will have
|
|
68
|
+
* to make sure the secret is not unexpectedly exposed to the client.
|
|
57
69
|
*
|
|
58
70
|
* @returns Provider to wrap your app with
|
|
59
71
|
*/
|
package/provider.js
CHANGED
|
@@ -36,7 +36,7 @@ const AuthContext = exports.AuthContext = /*#__PURE__*/_react.default.createCont
|
|
|
36
36
|
* Initialize a set of Commerce API clients and make it available to all of descendant components
|
|
37
37
|
*
|
|
38
38
|
* @group Components
|
|
39
|
-
*
|
|
39
|
+
*
|
|
40
40
|
* @example
|
|
41
41
|
* ```js
|
|
42
42
|
import {CommerceApiProvider} from '@salesforce/commerce-sdk-react'
|
|
@@ -52,16 +52,25 @@ const AuthContext = exports.AuthContext = /*#__PURE__*/_react.default.createCont
|
|
|
52
52
|
siteId="RefArch"
|
|
53
53
|
shortCode="12345678"
|
|
54
54
|
locale="en-US"
|
|
55
|
+
enablePWAKitPrivateClient={true}
|
|
55
56
|
currency="USD"
|
|
56
57
|
>
|
|
57
58
|
{children}
|
|
58
59
|
</CommerceApiProvider>
|
|
59
60
|
)
|
|
60
|
-
}
|
|
61
|
+
}
|
|
61
62
|
|
|
62
63
|
export default App
|
|
63
64
|
* ```
|
|
64
|
-
*
|
|
65
|
+
* Note: The provider can enable SLAS Private Client mode in 2 ways.
|
|
66
|
+
* `enablePWAKitPrivateClient` sets commerce-sdk-react to work with the PWA proxy
|
|
67
|
+
* `/mobify/scapi/api/auth` to set the private client secret. PWA users should use
|
|
68
|
+
* this option.
|
|
69
|
+
*
|
|
70
|
+
* Non-PWA Kit users can enable private client mode by passing in a client secret
|
|
71
|
+
* directly to the provider. However, be careful when doing this as you will have
|
|
72
|
+
* to make sure the secret is not unexpectedly exposed to the client.
|
|
73
|
+
*
|
|
65
74
|
* @returns Provider to wrap your app with
|
|
66
75
|
*/
|
|
67
76
|
const CommerceApiProvider = props => {
|
|
@@ -78,7 +87,10 @@ const CommerceApiProvider = props => {
|
|
|
78
87
|
locale,
|
|
79
88
|
currency,
|
|
80
89
|
fetchedToken,
|
|
81
|
-
OCAPISessionsURL
|
|
90
|
+
OCAPISessionsURL,
|
|
91
|
+
enablePWAKitPrivateClient,
|
|
92
|
+
clientSecret,
|
|
93
|
+
silenceWarnings
|
|
82
94
|
} = props;
|
|
83
95
|
const config = {
|
|
84
96
|
proxy,
|
|
@@ -119,9 +131,12 @@ const CommerceApiProvider = props => {
|
|
|
119
131
|
redirectURI,
|
|
120
132
|
fetchOptions,
|
|
121
133
|
fetchedToken,
|
|
122
|
-
OCAPISessionsURL
|
|
134
|
+
OCAPISessionsURL,
|
|
135
|
+
enablePWAKitPrivateClient,
|
|
136
|
+
clientSecret,
|
|
137
|
+
silenceWarnings
|
|
123
138
|
});
|
|
124
|
-
}, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, OCAPISessionsURL]);
|
|
139
|
+
}, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, OCAPISessionsURL, enablePWAKitPrivateClient, clientSecret, silenceWarnings]);
|
|
125
140
|
|
|
126
141
|
// Initialize the session
|
|
127
142
|
(0, _react.useEffect)(() => void auth.ready(), [auth]);
|
|
@@ -136,7 +151,8 @@ const CommerceApiProvider = props => {
|
|
|
136
151
|
siteId,
|
|
137
152
|
shortCode,
|
|
138
153
|
locale,
|
|
139
|
-
currency
|
|
154
|
+
currency,
|
|
155
|
+
silenceWarnings
|
|
140
156
|
}
|
|
141
157
|
}, /*#__PURE__*/_react.default.createElement(CommerceApiContext.Provider, {
|
|
142
158
|
value: apiClients
|