@scayle/storefront-core 7.65.6 → 7.65.8
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 +12 -0
- package/dist/api/customer.cjs +21 -10
- package/dist/api/customer.d.ts +1 -1
- package/dist/api/customer.mjs +25 -10
- package/dist/rpc/methods/checkout/checkout.cjs +1 -1
- package/dist/rpc/methods/checkout/checkout.mjs +1 -1
- package/dist/rpc/methods/session.cjs +6 -0
- package/dist/rpc/methods/session.mjs +10 -0
- package/dist/rpc/methods/user.cjs +26 -12
- package/dist/rpc/methods/user.mjs +31 -13
- package/dist/utils/hash.cjs +8 -5
- package/dist/utils/hash.mjs +8 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 7.65.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed an issue with handling the deprecated MD5 hash support, e.g. used for generating a user-specific basket hash, resulting in a potential application crash
|
|
8
|
+
|
|
9
|
+
## 7.65.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Delete `refreshToken` if it fails to refresh the access token
|
|
14
|
+
|
|
3
15
|
## 7.65.6
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/api/customer.cjs
CHANGED
|
@@ -34,18 +34,29 @@ class CustomerAPIClient {
|
|
|
34
34
|
if ((response.status === _httpStatus.HttpStatusCode.UNAUTHORIZED && response.headers.get("WWW-Authenticate")?.includes("invalid_token") || response.status === _httpStatus.HttpStatusCode.FORBIDDEN) && this.context.accessToken && this.context.refreshToken) {
|
|
35
35
|
if (retry) {
|
|
36
36
|
const client = (0, _oauth.getOAuthClient)(this.context);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
try {
|
|
38
|
+
const tokens = await client.refreshToken({
|
|
39
|
+
grant_type: "refresh_token",
|
|
40
|
+
refresh_token: this.context.refreshToken
|
|
41
|
+
});
|
|
42
|
+
this.context.updateTokens({
|
|
43
|
+
accessToken: tokens?.access_token,
|
|
44
|
+
refreshToken: tokens?.refresh_token
|
|
45
|
+
});
|
|
46
|
+
} catch (e) {
|
|
47
|
+
if (e instanceof _fetch.FetchError && e.response.status === _httpStatus.HttpStatusCode.UNAUTHORIZED) {
|
|
48
|
+
this.context.log.debug("Failed to refresh Checkout Token due to invalid refresh token. Deleting session");
|
|
49
|
+
await this.context.destroySession();
|
|
50
|
+
} else {
|
|
51
|
+
this.context.log.debug("Failed to refresh Checkout Token for unknown reason.");
|
|
52
|
+
}
|
|
53
|
+
throw new _fetch.FetchError(response);
|
|
54
|
+
}
|
|
45
55
|
return await this.sendRequest(request, false);
|
|
56
|
+
} else {
|
|
57
|
+
this.context.log.debug("Invalid Checkout Token. Deleting session");
|
|
58
|
+
await this.context.destroySession();
|
|
46
59
|
}
|
|
47
|
-
this.context.log.debug("Invalid Checkout Token. Deleting session");
|
|
48
|
-
await this.context.destroySession();
|
|
49
60
|
}
|
|
50
61
|
throw new _fetch.FetchError(response);
|
|
51
62
|
}
|
package/dist/api/customer.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ interface PasswordUpdate {
|
|
|
37
37
|
export declare class CustomerAPIClient {
|
|
38
38
|
baseURL: string;
|
|
39
39
|
context: RpcContext;
|
|
40
|
-
|
|
40
|
+
additionalHeaders: HeadersInit | undefined;
|
|
41
41
|
constructor(context: RpcContext);
|
|
42
42
|
get headers(): HeadersInit;
|
|
43
43
|
sendRequest<BodyType>(request: () => Promise<Response>, retry?: boolean): Promise<BodyType>;
|
package/dist/api/customer.mjs
CHANGED
|
@@ -28,18 +28,33 @@ export class CustomerAPIClient {
|
|
|
28
28
|
) || response.status === HttpStatusCode.FORBIDDEN) && this.context.accessToken && this.context.refreshToken) {
|
|
29
29
|
if (retry) {
|
|
30
30
|
const client = getOAuthClient(this.context);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
try {
|
|
32
|
+
const tokens = await client.refreshToken({
|
|
33
|
+
grant_type: "refresh_token",
|
|
34
|
+
refresh_token: this.context.refreshToken
|
|
35
|
+
});
|
|
36
|
+
this.context.updateTokens({
|
|
37
|
+
accessToken: tokens?.access_token,
|
|
38
|
+
refreshToken: tokens?.refresh_token
|
|
39
|
+
});
|
|
40
|
+
} catch (e) {
|
|
41
|
+
if (e instanceof FetchError && e.response.status === HttpStatusCode.UNAUTHORIZED) {
|
|
42
|
+
this.context.log.debug(
|
|
43
|
+
"Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
|
|
44
|
+
);
|
|
45
|
+
await this.context.destroySession();
|
|
46
|
+
} else {
|
|
47
|
+
this.context.log.debug(
|
|
48
|
+
"Failed to refresh Checkout Token for unknown reason."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
throw new FetchError(response);
|
|
52
|
+
}
|
|
39
53
|
return await this.sendRequest(request, false);
|
|
54
|
+
} else {
|
|
55
|
+
this.context.log.debug("Invalid Checkout Token. Deleting session");
|
|
56
|
+
await this.context.destroySession();
|
|
40
57
|
}
|
|
41
|
-
this.context.log.debug("Invalid Checkout Token. Deleting session");
|
|
42
|
-
await this.context.destroySession();
|
|
43
58
|
}
|
|
44
59
|
throw new FetchError(response);
|
|
45
60
|
}
|
|
@@ -37,7 +37,7 @@ const getCheckoutToken = exports.getCheckoutToken = async function getCheckoutTo
|
|
|
37
37
|
carrier,
|
|
38
38
|
basketId: context.basketKey,
|
|
39
39
|
campaignKey: context.campaignKey
|
|
40
|
-
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.
|
|
40
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.8"}`).setProtectedHeader({
|
|
41
41
|
alg: "HS256",
|
|
42
42
|
typ: "JWT"
|
|
43
43
|
}).sign(secret);
|
|
@@ -35,7 +35,7 @@ export const getCheckoutToken = async function getCheckoutToken2(jwtPayload = {}
|
|
|
35
35
|
carrier,
|
|
36
36
|
basketId: context.basketKey,
|
|
37
37
|
campaignKey: context.campaignKey
|
|
38
|
-
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.
|
|
38
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"7.65.8"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
|
|
39
39
|
return {
|
|
40
40
|
accessToken: refreshedAccessToken,
|
|
41
41
|
checkoutJwt
|
|
@@ -143,6 +143,12 @@ const refreshAccessToken = async context => {
|
|
|
143
143
|
};
|
|
144
144
|
} catch (error) {
|
|
145
145
|
const res = convertErrorForRpcCall(error, [_constants.HttpStatusCode.BAD_REQUEST, _constants.HttpStatusCode.UNAUTHORIZED]);
|
|
146
|
+
if (res && res.status === _constants.HttpStatusCode.UNAUTHORIZED) {
|
|
147
|
+
context.log.debug("Failed to refresh Checkout Token due to invalid refresh token. Deleting session");
|
|
148
|
+
await context.destroySession();
|
|
149
|
+
} else {
|
|
150
|
+
context.log.debug("Failed to refresh Checkout Token for unknown reason.");
|
|
151
|
+
}
|
|
146
152
|
if (res) {
|
|
147
153
|
return res;
|
|
148
154
|
}
|
|
@@ -190,6 +190,16 @@ export const refreshAccessToken = async (context) => {
|
|
|
190
190
|
HttpStatusCode.BAD_REQUEST,
|
|
191
191
|
HttpStatusCode.UNAUTHORIZED
|
|
192
192
|
]);
|
|
193
|
+
if (res && res.status === HttpStatusCode.UNAUTHORIZED) {
|
|
194
|
+
context.log.debug(
|
|
195
|
+
"Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
|
|
196
|
+
);
|
|
197
|
+
await context.destroySession();
|
|
198
|
+
} else {
|
|
199
|
+
context.log.debug(
|
|
200
|
+
"Failed to refresh Checkout Token for unknown reason."
|
|
201
|
+
);
|
|
202
|
+
}
|
|
193
203
|
if (res) {
|
|
194
204
|
return res;
|
|
195
205
|
}
|
|
@@ -9,6 +9,7 @@ var _customer = require("../../api/customer.cjs");
|
|
|
9
9
|
var _oauth = require("../../api/oauth.cjs");
|
|
10
10
|
var _constants = require("../../constants/index.cjs");
|
|
11
11
|
var _errors = require("../../errors/index.cjs");
|
|
12
|
+
var _fetch = require("../../utils/fetch.cjs");
|
|
12
13
|
const getUser = exports.getUser = function getUser2(context) {
|
|
13
14
|
const {
|
|
14
15
|
user,
|
|
@@ -84,18 +85,31 @@ const getAccessToken = exports.getAccessToken = async function getAccessToken2({
|
|
|
84
85
|
return new _errors.ErrorResponse(_constants.HttpStatusCode.UNAUTHORIZED, _constants.HttpStatusMessage.UNAUTHORIZED, "No refresh token present");
|
|
85
86
|
}
|
|
86
87
|
const client = (0, _oauth.getOAuthClient)(context);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
try {
|
|
89
|
+
const tokens = await client.refreshToken({
|
|
90
|
+
grant_type: "refresh_token",
|
|
91
|
+
refresh_token: context.refreshToken
|
|
92
|
+
});
|
|
93
|
+
context.updateTokens({
|
|
94
|
+
accessToken: tokens.access_token,
|
|
95
|
+
refreshToken: tokens.refresh_token
|
|
96
|
+
});
|
|
97
|
+
try {
|
|
98
|
+
const user = await fetchUser({
|
|
99
|
+
accessToken: tokens.access_token
|
|
100
|
+
}, context);
|
|
101
|
+
context.updateUser(user);
|
|
102
|
+
} catch {
|
|
103
|
+
context.log.debug("Failed to update user");
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
if (e instanceof _fetch.FetchError && e.response.status === _constants.HttpStatusCode.UNAUTHORIZED) {
|
|
107
|
+
context.log.debug("Failed to refresh Checkout Token due to invalid refresh token. Deleting session");
|
|
108
|
+
await context.destroySession();
|
|
109
|
+
} else {
|
|
110
|
+
context.log.debug("Failed to refresh Checkout Token for unknown reason.");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
99
113
|
}
|
|
100
114
|
return context.accessToken;
|
|
101
115
|
};
|
|
@@ -3,6 +3,7 @@ import { CustomerAPIClient } from "../../api/customer.mjs";
|
|
|
3
3
|
import { getOAuthClient } from "../../api/oauth.mjs";
|
|
4
4
|
import { HttpStatusCode, HttpStatusMessage } from "../../constants/index.mjs";
|
|
5
5
|
import { ErrorResponse } from "../../errors/index.mjs";
|
|
6
|
+
import { FetchError } from "../../utils/fetch.mjs";
|
|
6
7
|
const getUser = function getUser2(context) {
|
|
7
8
|
const { user, accessToken, shopId } = context;
|
|
8
9
|
if (user) {
|
|
@@ -74,19 +75,36 @@ const getAccessToken = async function getAccessToken2({ forceTokenRefresh = fals
|
|
|
74
75
|
);
|
|
75
76
|
}
|
|
76
77
|
const client = getOAuthClient(context);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
try {
|
|
79
|
+
const tokens = await client.refreshToken({
|
|
80
|
+
grant_type: "refresh_token",
|
|
81
|
+
refresh_token: context.refreshToken
|
|
82
|
+
});
|
|
83
|
+
context.updateTokens({
|
|
84
|
+
accessToken: tokens.access_token,
|
|
85
|
+
refreshToken: tokens.refresh_token
|
|
86
|
+
});
|
|
87
|
+
try {
|
|
88
|
+
const user = await fetchUser(
|
|
89
|
+
{ accessToken: tokens.access_token },
|
|
90
|
+
context
|
|
91
|
+
);
|
|
92
|
+
context.updateUser(user);
|
|
93
|
+
} catch {
|
|
94
|
+
context.log.debug("Failed to update user");
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {
|
|
97
|
+
if (e instanceof FetchError && e.response.status === HttpStatusCode.UNAUTHORIZED) {
|
|
98
|
+
context.log.debug(
|
|
99
|
+
"Failed to refresh Checkout Token due to invalid refresh token. Deleting session"
|
|
100
|
+
);
|
|
101
|
+
await context.destroySession();
|
|
102
|
+
} else {
|
|
103
|
+
context.log.debug(
|
|
104
|
+
"Failed to refresh Checkout Token for unknown reason."
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
90
108
|
}
|
|
91
109
|
return context.accessToken;
|
|
92
110
|
};
|
package/dist/utils/hash.cjs
CHANGED
|
@@ -5,12 +5,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.verifyOrderSuccessToken = exports.sha256 = exports.md5 = exports.hmac = exports.encodeBase64 = exports.decodeBase64 = exports.buildSignature = exports.buildHashPayload = void 0;
|
|
7
7
|
var _uncrypto = require("uncrypto");
|
|
8
|
+
function stringToBoolean(value, defaultValue = false) {
|
|
9
|
+
return value ? value.toLowerCase() === "true" : defaultValue;
|
|
10
|
+
}
|
|
8
11
|
const md5 = async value => {
|
|
9
|
-
if (!process.env.SFC_OMIT_MD5) {
|
|
10
|
-
const md5EncryptImport = await Promise.resolve().then(() => require("crypto-js/md5"));
|
|
11
|
-
const hexImport = await Promise.resolve().then(() => require("crypto-js/enc-hex"));
|
|
12
|
-
const md5Encrypt = md5EncryptImport.default && typeof md5EncryptImport.default === "function" ? md5EncryptImport.default : md5EncryptImport;
|
|
13
|
-
const hex = hexImport.default && typeof hexImport.default === "function" ? hexImport.default : hexImport;
|
|
12
|
+
if (!stringToBoolean(process.env.SFC_OMIT_MD5)) {
|
|
13
|
+
const md5EncryptImport = await Promise.resolve().then(() => require("crypto-js/md5.js"));
|
|
14
|
+
const hexImport = await Promise.resolve().then(() => require("crypto-js/enc-hex.js"));
|
|
15
|
+
const md5Encrypt = md5EncryptImport.default && (typeof md5EncryptImport.default === "function" || typeof md5EncryptImport.default === "object") ? md5EncryptImport.default : md5EncryptImport;
|
|
16
|
+
const hex = hexImport.default && (typeof hexImport.default === "function" || typeof hexImport.default === "object") ? hexImport.default : hexImport;
|
|
14
17
|
return hex.stringify(md5Encrypt(value));
|
|
15
18
|
} else {
|
|
16
19
|
throw Error("SFC was built without support for MD5");
|
package/dist/utils/hash.mjs
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { subtle } from "uncrypto";
|
|
2
|
+
function stringToBoolean(value, defaultValue = false) {
|
|
3
|
+
return value ? value.toLowerCase() === "true" : defaultValue;
|
|
4
|
+
}
|
|
2
5
|
export const md5 = async (value) => {
|
|
3
|
-
if (!process.env.SFC_OMIT_MD5) {
|
|
4
|
-
const md5EncryptImport = await import("crypto-js/md5");
|
|
5
|
-
const hexImport = await import("crypto-js/enc-hex");
|
|
6
|
-
const md5Encrypt = md5EncryptImport.default && typeof md5EncryptImport.default === "function" ? md5EncryptImport.default : md5EncryptImport;
|
|
7
|
-
const hex = hexImport.default && typeof hexImport.default === "function" ? hexImport.default : hexImport;
|
|
6
|
+
if (!stringToBoolean(process.env.SFC_OMIT_MD5)) {
|
|
7
|
+
const md5EncryptImport = await import("crypto-js/md5.js");
|
|
8
|
+
const hexImport = await import("crypto-js/enc-hex.js");
|
|
9
|
+
const md5Encrypt = md5EncryptImport.default && (typeof md5EncryptImport.default === "function" || typeof md5EncryptImport.default === "object") ? md5EncryptImport.default : md5EncryptImport;
|
|
10
|
+
const hex = hexImport.default && (typeof hexImport.default === "function" || typeof hexImport.default === "object") ? hexImport.default : hexImport;
|
|
8
11
|
return hex.stringify(md5Encrypt(value));
|
|
9
12
|
} else {
|
|
10
13
|
throw Error("SFC was built without support for MD5");
|