@salesforce/commerce-sdk-react 3.2.0-preview.0 → 3.2.0-preview.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 +2 -2
- package/auth/index.d.ts +40 -2
- package/auth/index.js +200 -1
- package/hooks/useAuthHelper.d.ts +8 -0
- package/hooks/useAuthHelper.js +8 -0
- package/hooks/useCustomerType.d.ts +1 -0
- package/hooks/useCustomerType.js +9 -1
- package/package.json +5 -5
- package/provider.d.ts +1 -0
- package/provider.js +4 -1
- package/utils.d.ts +25 -0
- package/utils.js +33 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
## v3.2.0-preview.1 (Feb 12, 2025)
|
|
1
2
|
## v3.2.0-preview.0 (Feb 03, 2025)
|
|
2
|
-
## v3.2.0-dev (Feb 03, 2025)
|
|
3
|
-
## v3.9.0-preview.0 (Feb 03, 2025)
|
|
4
3
|
## v3.2.0-dev (Oct 29, 2024)
|
|
5
4
|
- Allow cookies for ShopperLogin API [#2190](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2190
|
|
6
5
|
- Fix refresh token TTL warning from firing when override is not provided [#2114](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2114)
|
|
@@ -9,6 +8,7 @@
|
|
|
9
8
|
- Clear auth state if session has been invalidated by a password change [#2092](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2092)
|
|
10
9
|
- DNT interface improvement [#2203](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2203)
|
|
11
10
|
- Support Node 22 [#2218](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2218)
|
|
11
|
+
- Add `authorizeIDP`, `loginIDPUser`, `authorizePasswordless`, `getPasswordLessAccessToken`, `getPasswordResetToken`, and `resetPassword` wrapper functions to support Social Login, Passwordless Login, and Password Reset [#2079] (https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2079)
|
|
12
12
|
|
|
13
13
|
## v3.1.0 (Oct 28, 2024)
|
|
14
14
|
|
package/auth/index.d.ts
CHANGED
|
@@ -15,9 +15,15 @@ interface AuthConfig extends ApiClientConfigParams {
|
|
|
15
15
|
silenceWarnings?: boolean;
|
|
16
16
|
logger: Logger;
|
|
17
17
|
defaultDnt?: boolean;
|
|
18
|
+
passwordlessLoginCallbackURI?: string;
|
|
18
19
|
refreshTokenRegisteredCookieTTL?: number;
|
|
19
20
|
refreshTokenGuestCookieTTL?: number;
|
|
20
21
|
}
|
|
22
|
+
type AuthorizeIDPParams = Parameters<Helpers['authorizeIDP']>[1];
|
|
23
|
+
type LoginIDPUserParams = Parameters<Helpers['loginIDPUser']>[2];
|
|
24
|
+
type AuthorizePasswordlessParams = Parameters<Helpers['authorizePasswordless']>[2];
|
|
25
|
+
type LoginPasswordlessParams = Parameters<Helpers['getPasswordLessAccessToken']>[2];
|
|
26
|
+
type LoginRegisteredUserB2CCredentials = Parameters<Helpers['loginRegisteredUserB2C']>[1];
|
|
21
27
|
/**
|
|
22
28
|
* The extended field is not from api response, we manually store the auth type,
|
|
23
29
|
* so we don't need to make another API call when we already have the data.
|
|
@@ -29,7 +35,7 @@ export type AuthData = Prettify<RemoveStringIndex<TokenResponse> & {
|
|
|
29
35
|
idp_access_token: string;
|
|
30
36
|
}>;
|
|
31
37
|
/** A shopper could be guest or registered, so we store the refresh tokens individually. */
|
|
32
|
-
type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered' | 'access_token_sfra' | typeof DNT_COOKIE_NAME | typeof DWSID_COOKIE_NAME;
|
|
38
|
+
type AuthDataKeys = Exclude<keyof AuthData, 'refresh_token'> | 'refresh_token_guest' | 'refresh_token_registered' | 'access_token_sfra' | typeof DNT_COOKIE_NAME | typeof DWSID_COOKIE_NAME | 'code_verifier' | 'uido';
|
|
33
39
|
type DntOptions = {
|
|
34
40
|
includeDefaults: boolean;
|
|
35
41
|
};
|
|
@@ -54,6 +60,8 @@ declare class Auth {
|
|
|
54
60
|
private silenceWarnings;
|
|
55
61
|
private logger;
|
|
56
62
|
private defaultDnt;
|
|
63
|
+
private isPrivate;
|
|
64
|
+
private passwordlessLoginCallbackURI;
|
|
57
65
|
private refreshTokenRegisteredCookieTTL;
|
|
58
66
|
private refreshTokenGuestCookieTTL;
|
|
59
67
|
private refreshTrustedAgentHandler;
|
|
@@ -235,6 +243,7 @@ declare class Auth {
|
|
|
235
243
|
fax?: string | undefined;
|
|
236
244
|
firstName?: string | undefined;
|
|
237
245
|
gender?: number | undefined;
|
|
246
|
+
hashedLogin?: string | undefined;
|
|
238
247
|
jobTitle?: string | undefined;
|
|
239
248
|
lastLoginTime?: any;
|
|
240
249
|
lastModified?: any;
|
|
@@ -294,7 +303,7 @@ declare class Auth {
|
|
|
294
303
|
* A wrapper method for commerce-sdk-isomorphic helper: loginRegisteredUserB2C.
|
|
295
304
|
*
|
|
296
305
|
*/
|
|
297
|
-
loginRegisteredUserB2C(credentials:
|
|
306
|
+
loginRegisteredUserB2C(credentials: LoginRegisteredUserB2CCredentials): Promise<helpers.TokenResponse>;
|
|
298
307
|
/**
|
|
299
308
|
* Trusted agent authorization
|
|
300
309
|
*
|
|
@@ -354,6 +363,34 @@ declare class Auth {
|
|
|
354
363
|
currentPassword: string;
|
|
355
364
|
shouldReloginCurrentSession?: boolean;
|
|
356
365
|
}): Promise<void>;
|
|
366
|
+
/**
|
|
367
|
+
* A wrapper method for commerce-sdk-isomorphic helper: authorizeIDP.
|
|
368
|
+
*
|
|
369
|
+
*/
|
|
370
|
+
authorizeIDP(parameters: AuthorizeIDPParams): Promise<void>;
|
|
371
|
+
/**
|
|
372
|
+
* A wrapper method for commerce-sdk-isomorphic helper: loginIDPUser.
|
|
373
|
+
*
|
|
374
|
+
*/
|
|
375
|
+
loginIDPUser(parameters: LoginIDPUserParams): Promise<helpers.TokenResponse>;
|
|
376
|
+
/**
|
|
377
|
+
* A wrapper method for commerce-sdk-isomorphic helper: authorizePasswordless.
|
|
378
|
+
*/
|
|
379
|
+
authorizePasswordless(parameters: AuthorizePasswordlessParams): Promise<Response>;
|
|
380
|
+
/**
|
|
381
|
+
* A wrapper method for commerce-sdk-isomorphic helper: getPasswordLessAccessToken.
|
|
382
|
+
*/
|
|
383
|
+
getPasswordLessAccessToken(parameters: LoginPasswordlessParams): Promise<helpers.TokenResponse>;
|
|
384
|
+
/**
|
|
385
|
+
* A wrapper method for the SLAS endpoint: getPasswordResetToken.
|
|
386
|
+
*
|
|
387
|
+
*/
|
|
388
|
+
getPasswordResetToken(parameters: ShopperLoginTypes.PasswordActionRequest): Promise<void>;
|
|
389
|
+
/**
|
|
390
|
+
* A wrapper method for the SLAS endpoint: resetPassword.
|
|
391
|
+
*
|
|
392
|
+
*/
|
|
393
|
+
resetPassword(parameters: ShopperLoginTypes.PasswordActionVerifyRequest): Promise<void>;
|
|
357
394
|
/**
|
|
358
395
|
* Decode SLAS JWT and extract information such as customer id, usid, etc.
|
|
359
396
|
*
|
|
@@ -366,6 +403,7 @@ declare class Auth {
|
|
|
366
403
|
loginId: string;
|
|
367
404
|
isAgent: boolean;
|
|
368
405
|
agentId: string | null;
|
|
406
|
+
uido: string;
|
|
369
407
|
};
|
|
370
408
|
}
|
|
371
409
|
export default Auth;
|
package/auth/index.js
CHANGED
|
@@ -115,6 +115,14 @@ const DATA_MAP = {
|
|
|
115
115
|
dwsid: {
|
|
116
116
|
storageType: 'cookie',
|
|
117
117
|
key: _constant.DWSID_COOKIE_NAME
|
|
118
|
+
},
|
|
119
|
+
code_verifier: {
|
|
120
|
+
storageType: 'local',
|
|
121
|
+
key: 'code_verifier'
|
|
122
|
+
},
|
|
123
|
+
uido: {
|
|
124
|
+
storageType: 'local',
|
|
125
|
+
key: 'uido'
|
|
118
126
|
}
|
|
119
127
|
};
|
|
120
128
|
const DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL = exports.DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL = 90 * 24 * 60 * 60;
|
|
@@ -205,6 +213,9 @@ class Auth {
|
|
|
205
213
|
// PWA users should not need to touch this.
|
|
206
214
|
config.clientSecret || '';
|
|
207
215
|
this.silenceWarnings = config.silenceWarnings || false;
|
|
216
|
+
this.isPrivate = !!this.clientSecret;
|
|
217
|
+
const passwordlessLoginCallbackURI = config.passwordlessLoginCallbackURI;
|
|
218
|
+
this.passwordlessLoginCallbackURI = passwordlessLoginCallbackURI ? (0, _utils.isAbsoluteUrl)(passwordlessLoginCallbackURI) ? passwordlessLoginCallbackURI : `${baseUrl}${passwordlessLoginCallbackURI}` : '';
|
|
208
219
|
}
|
|
209
220
|
get(name) {
|
|
210
221
|
const {
|
|
@@ -485,6 +496,12 @@ class Auth {
|
|
|
485
496
|
const responseValue = res.refresh_token_expires_in;
|
|
486
497
|
const defaultValue = isGuest ? DEFAULT_SLAS_REFRESH_TOKEN_GUEST_TTL : DEFAULT_SLAS_REFRESH_TOKEN_REGISTERED_TTL;
|
|
487
498
|
const refreshTokenTTLValue = this.getRefreshTokenCookieTTLValue(overrideValue, responseValue, defaultValue);
|
|
499
|
+
if (res.access_token) {
|
|
500
|
+
const {
|
|
501
|
+
uido
|
|
502
|
+
} = this.parseSlasJWT(res.access_token);
|
|
503
|
+
this.set('uido', uido);
|
|
504
|
+
}
|
|
488
505
|
const expiresDate = this.convertSecondsToDate(refreshTokenTTLValue);
|
|
489
506
|
this.set('refresh_token_expires_in', refreshTokenTTLValue.toString());
|
|
490
507
|
this.set(refreshTokenKey, res.refresh_token, {
|
|
@@ -930,6 +947,186 @@ class Auth {
|
|
|
930
947
|
})();
|
|
931
948
|
}
|
|
932
949
|
|
|
950
|
+
/**
|
|
951
|
+
* A wrapper method for commerce-sdk-isomorphic helper: authorizeIDP.
|
|
952
|
+
*
|
|
953
|
+
*/
|
|
954
|
+
authorizeIDP(parameters) {
|
|
955
|
+
var _this14 = this;
|
|
956
|
+
return _asyncToGenerator(function* () {
|
|
957
|
+
const redirectURI = parameters.redirectURI || _this14.redirectURI;
|
|
958
|
+
const usid = _this14.get('usid');
|
|
959
|
+
const {
|
|
960
|
+
url,
|
|
961
|
+
codeVerifier
|
|
962
|
+
} = yield _commerceSdkIsomorphic.helpers.authorizeIDP(_this14.client, _objectSpread({
|
|
963
|
+
redirectURI,
|
|
964
|
+
hint: parameters.hint
|
|
965
|
+
}, usid && {
|
|
966
|
+
usid
|
|
967
|
+
}), _this14.isPrivate);
|
|
968
|
+
if ((0, _utils.onClient)()) {
|
|
969
|
+
window.location.assign(url);
|
|
970
|
+
} else {
|
|
971
|
+
console.warn('Something went wrong, this client side method is invoked on the server.');
|
|
972
|
+
}
|
|
973
|
+
_this14.set('code_verifier', codeVerifier);
|
|
974
|
+
})();
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* A wrapper method for commerce-sdk-isomorphic helper: loginIDPUser.
|
|
979
|
+
*
|
|
980
|
+
*/
|
|
981
|
+
loginIDPUser(parameters) {
|
|
982
|
+
var _this15 = this;
|
|
983
|
+
return _asyncToGenerator(function* () {
|
|
984
|
+
const codeVerifier = _this15.get('code_verifier');
|
|
985
|
+
const code = parameters.code;
|
|
986
|
+
const usid = parameters.usid || _this15.get('usid');
|
|
987
|
+
const redirectURI = parameters.redirectURI || _this15.redirectURI;
|
|
988
|
+
const dntPref = _this15.getDnt({
|
|
989
|
+
includeDefaults: true
|
|
990
|
+
});
|
|
991
|
+
const token = yield _commerceSdkIsomorphic.helpers.loginIDPUser(_this15.client, {
|
|
992
|
+
codeVerifier,
|
|
993
|
+
clientSecret: _this15.clientSecret
|
|
994
|
+
}, _objectSpread({
|
|
995
|
+
redirectURI,
|
|
996
|
+
code,
|
|
997
|
+
dnt: dntPref
|
|
998
|
+
}, usid && {
|
|
999
|
+
usid
|
|
1000
|
+
}));
|
|
1001
|
+
const isGuest = false;
|
|
1002
|
+
_this15.handleTokenResponse(token, isGuest);
|
|
1003
|
+
// Delete the code verifier once the user has logged in
|
|
1004
|
+
_this15.delete('code_verifier');
|
|
1005
|
+
if ((0, _utils.onClient)()) {
|
|
1006
|
+
void _this15.clearECOMSession();
|
|
1007
|
+
}
|
|
1008
|
+
return token;
|
|
1009
|
+
})();
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* A wrapper method for commerce-sdk-isomorphic helper: authorizePasswordless.
|
|
1014
|
+
*/
|
|
1015
|
+
authorizePasswordless(parameters) {
|
|
1016
|
+
var _this16 = this;
|
|
1017
|
+
return _asyncToGenerator(function* () {
|
|
1018
|
+
const userid = parameters.userid;
|
|
1019
|
+
const callbackURI = parameters.callbackURI || _this16.passwordlessLoginCallbackURI;
|
|
1020
|
+
const usid = _this16.get('usid');
|
|
1021
|
+
const mode = callbackURI ? 'callback' : 'sms';
|
|
1022
|
+
const res = yield _commerceSdkIsomorphic.helpers.authorizePasswordless(_this16.client, {
|
|
1023
|
+
clientSecret: _this16.clientSecret
|
|
1024
|
+
}, _objectSpread(_objectSpread(_objectSpread({}, callbackURI && {
|
|
1025
|
+
callbackURI: callbackURI
|
|
1026
|
+
}), usid && {
|
|
1027
|
+
usid
|
|
1028
|
+
}), {}, {
|
|
1029
|
+
userid,
|
|
1030
|
+
mode
|
|
1031
|
+
}));
|
|
1032
|
+
if (res && res.status !== 200) {
|
|
1033
|
+
const errorData = yield res.json();
|
|
1034
|
+
throw new Error(`${res.status} ${String(errorData.message)}`);
|
|
1035
|
+
}
|
|
1036
|
+
return res;
|
|
1037
|
+
})();
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* A wrapper method for commerce-sdk-isomorphic helper: getPasswordLessAccessToken.
|
|
1042
|
+
*/
|
|
1043
|
+
getPasswordLessAccessToken(parameters) {
|
|
1044
|
+
var _this17 = this;
|
|
1045
|
+
return _asyncToGenerator(function* () {
|
|
1046
|
+
const pwdlessLoginToken = parameters.pwdlessLoginToken;
|
|
1047
|
+
const dntPref = _this17.getDnt({
|
|
1048
|
+
includeDefaults: true
|
|
1049
|
+
});
|
|
1050
|
+
const token = yield _commerceSdkIsomorphic.helpers.getPasswordLessAccessToken(_this17.client, {
|
|
1051
|
+
clientSecret: _this17.clientSecret
|
|
1052
|
+
}, {
|
|
1053
|
+
pwdlessLoginToken,
|
|
1054
|
+
dnt: dntPref !== undefined ? String(dntPref) : undefined
|
|
1055
|
+
});
|
|
1056
|
+
const isGuest = false;
|
|
1057
|
+
_this17.handleTokenResponse(token, isGuest);
|
|
1058
|
+
if ((0, _utils.onClient)()) {
|
|
1059
|
+
void _this17.clearECOMSession();
|
|
1060
|
+
}
|
|
1061
|
+
return token;
|
|
1062
|
+
})();
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* A wrapper method for the SLAS endpoint: getPasswordResetToken.
|
|
1067
|
+
*
|
|
1068
|
+
*/
|
|
1069
|
+
getPasswordResetToken(parameters) {
|
|
1070
|
+
var _this18 = this;
|
|
1071
|
+
return _asyncToGenerator(function* () {
|
|
1072
|
+
const slasClient = _this18.client;
|
|
1073
|
+
const callbackURI = parameters.callback_uri;
|
|
1074
|
+
const options = {
|
|
1075
|
+
headers: {
|
|
1076
|
+
Authorization: ''
|
|
1077
|
+
},
|
|
1078
|
+
body: {
|
|
1079
|
+
user_id: parameters.user_id,
|
|
1080
|
+
mode: 'callback',
|
|
1081
|
+
channel_id: slasClient.clientConfig.parameters.siteId,
|
|
1082
|
+
client_id: slasClient.clientConfig.parameters.clientId,
|
|
1083
|
+
callback_uri: callbackURI,
|
|
1084
|
+
hint: 'cross_device'
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
// Only set authorization header if using private client
|
|
1089
|
+
if (_this18.clientSecret) {
|
|
1090
|
+
options.headers.Authorization = `Basic ${(0, _utils.stringToBase64)(`${slasClient.clientConfig.parameters.clientId}:${_this18.clientSecret}`)}`;
|
|
1091
|
+
}
|
|
1092
|
+
const res = yield slasClient.getPasswordResetToken(options);
|
|
1093
|
+
return res;
|
|
1094
|
+
})();
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* A wrapper method for the SLAS endpoint: resetPassword.
|
|
1099
|
+
*
|
|
1100
|
+
*/
|
|
1101
|
+
resetPassword(parameters) {
|
|
1102
|
+
var _this19 = this;
|
|
1103
|
+
return _asyncToGenerator(function* () {
|
|
1104
|
+
const slasClient = _this19.client;
|
|
1105
|
+
const options = {
|
|
1106
|
+
headers: {
|
|
1107
|
+
Authorization: ''
|
|
1108
|
+
},
|
|
1109
|
+
body: {
|
|
1110
|
+
pwd_action_token: parameters.pwd_action_token,
|
|
1111
|
+
channel_id: slasClient.clientConfig.parameters.siteId,
|
|
1112
|
+
client_id: slasClient.clientConfig.parameters.clientId,
|
|
1113
|
+
new_password: parameters.new_password,
|
|
1114
|
+
user_id: parameters.user_id
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
// Only set authorization header if using private client
|
|
1119
|
+
if (_this19.clientSecret) {
|
|
1120
|
+
options.headers.Authorization = `Basic ${(0, _utils.stringToBase64)(`${slasClient.clientConfig.parameters.clientId}:${_this19.clientSecret}`)}`;
|
|
1121
|
+
}
|
|
1122
|
+
// TODO: no code verifier needed with the fix blair has made, delete this when the fix has been merged to production
|
|
1123
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1124
|
+
// @ts-ignore
|
|
1125
|
+
const res = yield _this19.client.resetPassword(options);
|
|
1126
|
+
return res;
|
|
1127
|
+
})();
|
|
1128
|
+
}
|
|
1129
|
+
|
|
933
1130
|
/**
|
|
934
1131
|
* Decode SLAS JWT and extract information such as customer id, usid, etc.
|
|
935
1132
|
*
|
|
@@ -949,6 +1146,7 @@ class Auth {
|
|
|
949
1146
|
// ISB format
|
|
950
1147
|
// 'uido:ecom::upn:Guest||xxxEmailxxx::uidn:FirstName LastName::gcid:xxxGuestCustomerIdxxx::rcid:xxxRegisteredCustomerIdxxx::chid:xxxSiteIdxxx',
|
|
951
1148
|
const isbParts = isb.split('::');
|
|
1149
|
+
const uido = isbParts[0].split('uido:')[1];
|
|
952
1150
|
const isGuest = isbParts[1] === 'upn:Guest';
|
|
953
1151
|
const customerId = isGuest ? isbParts[3].replace('gcid:', '') : isbParts[4].replace('rcid:', '');
|
|
954
1152
|
const loginId = isGuest ? 'guest' : isbParts[1].replace('upn:', '');
|
|
@@ -965,7 +1163,8 @@ class Auth {
|
|
|
965
1163
|
dnt,
|
|
966
1164
|
loginId,
|
|
967
1165
|
isAgent,
|
|
968
|
-
agentId
|
|
1166
|
+
agentId,
|
|
1167
|
+
uido
|
|
969
1168
|
};
|
|
970
1169
|
}
|
|
971
1170
|
}
|
package/hooks/useAuthHelper.d.ts
CHANGED
|
@@ -6,10 +6,16 @@ import Auth from '../auth';
|
|
|
6
6
|
* @enum
|
|
7
7
|
*/
|
|
8
8
|
export declare const AuthHelpers: {
|
|
9
|
+
readonly AuthorizePasswordless: "authorizePasswordless";
|
|
10
|
+
readonly LoginPasswordlessUser: "getPasswordLessAccessToken";
|
|
11
|
+
readonly AuthorizeIDP: "authorizeIDP";
|
|
12
|
+
readonly GetPasswordResetToken: "getPasswordResetToken";
|
|
13
|
+
readonly LoginIDPUser: "loginIDPUser";
|
|
9
14
|
readonly LoginGuestUser: "loginGuestUser";
|
|
10
15
|
readonly LoginRegisteredUserB2C: "loginRegisteredUserB2C";
|
|
11
16
|
readonly Logout: "logout";
|
|
12
17
|
readonly Register: "register";
|
|
18
|
+
readonly ResetPassword: "resetPassword";
|
|
13
19
|
readonly UpdateCustomerPassword: "updateCustomerPassword";
|
|
14
20
|
};
|
|
15
21
|
/**
|
|
@@ -25,6 +31,8 @@ export type AuthHelper = (typeof AuthHelpers)[keyof typeof AuthHelpers];
|
|
|
25
31
|
* For more, see https://github.com/SalesforceCommerceCloud/commerce-sdk-isomorphic/#public-client-shopper-login-helpers
|
|
26
32
|
*
|
|
27
33
|
* Avaliable helpers:
|
|
34
|
+
* - authorizeIDP
|
|
35
|
+
* - loginIDPUser
|
|
28
36
|
* - loginRegisteredUserB2C
|
|
29
37
|
* - loginGuestUser
|
|
30
38
|
* - logout
|
package/hooks/useAuthHelper.js
CHANGED
|
@@ -22,10 +22,16 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
22
22
|
* @enum
|
|
23
23
|
*/
|
|
24
24
|
const AuthHelpers = exports.AuthHelpers = {
|
|
25
|
+
AuthorizePasswordless: 'authorizePasswordless',
|
|
26
|
+
LoginPasswordlessUser: 'getPasswordLessAccessToken',
|
|
27
|
+
AuthorizeIDP: 'authorizeIDP',
|
|
28
|
+
GetPasswordResetToken: 'getPasswordResetToken',
|
|
29
|
+
LoginIDPUser: 'loginIDPUser',
|
|
25
30
|
LoginGuestUser: 'loginGuestUser',
|
|
26
31
|
LoginRegisteredUserB2C: 'loginRegisteredUserB2C',
|
|
27
32
|
Logout: 'logout',
|
|
28
33
|
Register: 'register',
|
|
34
|
+
ResetPassword: 'resetPassword',
|
|
29
35
|
UpdateCustomerPassword: 'updateCustomerPassword'
|
|
30
36
|
};
|
|
31
37
|
/**
|
|
@@ -47,6 +53,8 @@ const noop = () => ({});
|
|
|
47
53
|
* For more, see https://github.com/SalesforceCommerceCloud/commerce-sdk-isomorphic/#public-client-shopper-login-helpers
|
|
48
54
|
*
|
|
49
55
|
* Avaliable helpers:
|
|
56
|
+
* - authorizeIDP
|
|
57
|
+
* - loginIDPUser
|
|
50
58
|
* - loginRegisteredUserB2C
|
|
51
59
|
* - loginGuestUser
|
|
52
60
|
* - logout
|
package/hooks/useCustomerType.js
CHANGED
|
@@ -44,10 +44,18 @@ const useCustomerType = () => {
|
|
|
44
44
|
if (customerType !== null && customerType !== 'guest' && customerType !== 'registered') {
|
|
45
45
|
customerType = null;
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
// The `uido` is a value within the `isb` claim of the SLAS access token that denotes the IDP origin of the user
|
|
49
|
+
// If `uido` is not equal to `slas` or `ecom`, the user is considered an external user
|
|
50
|
+
const uido = onClient ?
|
|
51
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
52
|
+
(0, _useLocalStorage.default)(`uido_${config.siteId}`) : auth.get('uido');
|
|
53
|
+
const isExternal = customerType === 'registered' && uido !== 'slas' && uido !== 'ecom';
|
|
47
54
|
return {
|
|
48
55
|
customerType,
|
|
49
56
|
isGuest,
|
|
50
|
-
isRegistered
|
|
57
|
+
isRegistered,
|
|
58
|
+
isExternal
|
|
51
59
|
};
|
|
52
60
|
};
|
|
53
61
|
var _default = exports.default = useCustomerType;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/commerce-sdk-react",
|
|
3
|
-
"version": "3.2.0-preview.
|
|
3
|
+
"version": "3.2.0-preview.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": {
|
|
@@ -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.2.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.9.0-preview.
|
|
48
|
+
"@salesforce/pwa-kit-dev": "3.9.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.9.0-preview.
|
|
63
|
+
"internal-lib-build": "3.9.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": "a4afa2da67a0c99f51ac1dfd9f63cd414f342dec"
|
|
94
94
|
}
|
package/provider.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface CommerceApiProviderProps extends ApiClientConfigParams {
|
|
|
17
17
|
silenceWarnings?: boolean;
|
|
18
18
|
logger?: Logger;
|
|
19
19
|
defaultDnt?: boolean;
|
|
20
|
+
passwordlessLoginCallbackURI?: string;
|
|
20
21
|
refreshTokenRegisteredCookieTTL?: number;
|
|
21
22
|
refreshTokenGuestCookieTTL?: number;
|
|
22
23
|
}
|
package/provider.js
CHANGED
|
@@ -97,6 +97,7 @@ const CommerceApiProvider = props => {
|
|
|
97
97
|
silenceWarnings,
|
|
98
98
|
logger,
|
|
99
99
|
defaultDnt,
|
|
100
|
+
passwordlessLoginCallbackURI,
|
|
100
101
|
refreshTokenRegisteredCookieTTL,
|
|
101
102
|
refreshTokenGuestCookieTTL
|
|
102
103
|
} = props;
|
|
@@ -118,10 +119,11 @@ const CommerceApiProvider = props => {
|
|
|
118
119
|
silenceWarnings,
|
|
119
120
|
logger: configLogger,
|
|
120
121
|
defaultDnt,
|
|
122
|
+
passwordlessLoginCallbackURI,
|
|
121
123
|
refreshTokenRegisteredCookieTTL,
|
|
122
124
|
refreshTokenGuestCookieTTL
|
|
123
125
|
});
|
|
124
|
-
}, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, enablePWAKitPrivateClient, clientSecret, silenceWarnings, configLogger, refreshTokenRegisteredCookieTTL, refreshTokenGuestCookieTTL]);
|
|
126
|
+
}, [clientId, organizationId, shortCode, siteId, proxy, redirectURI, fetchOptions, fetchedToken, enablePWAKitPrivateClient, clientSecret, silenceWarnings, configLogger, defaultDnt, passwordlessLoginCallbackURI, refreshTokenRegisteredCookieTTL, refreshTokenGuestCookieTTL]);
|
|
125
127
|
const dwsid = auth.get(_constant.DWSID_COOKIE_NAME);
|
|
126
128
|
const serverAffinityHeader = {};
|
|
127
129
|
if (dwsid) {
|
|
@@ -179,6 +181,7 @@ const CommerceApiProvider = props => {
|
|
|
179
181
|
silenceWarnings,
|
|
180
182
|
logger: configLogger,
|
|
181
183
|
defaultDnt,
|
|
184
|
+
passwordlessLoginCallbackURI,
|
|
182
185
|
refreshTokenRegisteredCookieTTL,
|
|
183
186
|
refreshTokenGuestCookieTTL
|
|
184
187
|
}
|
package/utils.d.ts
CHANGED
|
@@ -33,4 +33,29 @@ export declare const getDefaultCookieAttributes: () => CookieAttributes;
|
|
|
33
33
|
export declare function detectLocalStorageAvailable(): boolean;
|
|
34
34
|
/** Determines whether cookies are available by trying to set a test value. */
|
|
35
35
|
export declare function detectCookiesAvailable(options?: CookieAttributes): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Determines whether the given URL string is a valid absolute URL.
|
|
38
|
+
*
|
|
39
|
+
* Valid absolute URLs:
|
|
40
|
+
* - https://example.com
|
|
41
|
+
* - http://example.com
|
|
42
|
+
*
|
|
43
|
+
* Invalid or relative URLs:
|
|
44
|
+
* - http://example
|
|
45
|
+
* - example.com
|
|
46
|
+
* - /relative/path
|
|
47
|
+
*
|
|
48
|
+
* @param {string} url - The URL string to be checked.
|
|
49
|
+
* @returns {boolean} - Returns true if the given string is a valid absolute URL, false otherwise.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isAbsoluteUrl(url: string): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Provides a platform-specific method for Base64 encoding.
|
|
54
|
+
*
|
|
55
|
+
* - In a browser environment (where `window` and `document` are defined),
|
|
56
|
+
* the native `btoa` function is used.
|
|
57
|
+
* - In a non-browser environment (like Node.js), a fallback is provided
|
|
58
|
+
* that uses `Buffer` to perform the Base64 encoding.
|
|
59
|
+
*/
|
|
60
|
+
export declare const stringToBase64: typeof btoa;
|
|
36
61
|
//# sourceMappingURL=utils.d.ts.map
|
package/utils.js
CHANGED
|
@@ -7,7 +7,9 @@ exports.DEVELOPMENT_ORIGIN = void 0;
|
|
|
7
7
|
exports.detectCookiesAvailable = detectCookiesAvailable;
|
|
8
8
|
exports.detectInIframe = void 0;
|
|
9
9
|
exports.detectLocalStorageAvailable = detectLocalStorageAvailable;
|
|
10
|
-
exports.
|
|
10
|
+
exports.getParentOrigin = exports.getDefaultCookieAttributes = exports.getCookieSameSiteAttribute = void 0;
|
|
11
|
+
exports.isAbsoluteUrl = isAbsoluteUrl;
|
|
12
|
+
exports.stringToBase64 = exports.onClient = exports.isOriginTrusted = void 0;
|
|
11
13
|
var _jsCookie = _interopRequireDefault(require("js-cookie"));
|
|
12
14
|
var _constant = require("./constant");
|
|
13
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -123,4 +125,33 @@ function detectCookiesAvailable(options) {
|
|
|
123
125
|
} catch {
|
|
124
126
|
return false;
|
|
125
127
|
}
|
|
126
|
-
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Determines whether the given URL string is a valid absolute URL.
|
|
132
|
+
*
|
|
133
|
+
* Valid absolute URLs:
|
|
134
|
+
* - https://example.com
|
|
135
|
+
* - http://example.com
|
|
136
|
+
*
|
|
137
|
+
* Invalid or relative URLs:
|
|
138
|
+
* - http://example
|
|
139
|
+
* - example.com
|
|
140
|
+
* - /relative/path
|
|
141
|
+
*
|
|
142
|
+
* @param {string} url - The URL string to be checked.
|
|
143
|
+
* @returns {boolean} - Returns true if the given string is a valid absolute URL, false otherwise.
|
|
144
|
+
*/
|
|
145
|
+
function isAbsoluteUrl(url) {
|
|
146
|
+
return /^(https?:\/\/)/i.test(url);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Provides a platform-specific method for Base64 encoding.
|
|
151
|
+
*
|
|
152
|
+
* - In a browser environment (where `window` and `document` are defined),
|
|
153
|
+
* the native `btoa` function is used.
|
|
154
|
+
* - In a non-browser environment (like Node.js), a fallback is provided
|
|
155
|
+
* that uses `Buffer` to perform the Base64 encoding.
|
|
156
|
+
*/
|
|
157
|
+
const stringToBase64 = exports.stringToBase64 = typeof window === 'object' && typeof window.document === 'object' ? btoa : unencoded => Buffer.from(unencoded).toString('base64');
|