@scayle/storefront-core 8.4.0 → 8.5.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 +16 -0
- package/dist/rpc/methods/checkout/checkout.mjs +1 -1
- package/dist/rpc/methods/search.d.ts +22 -0
- package/package.json +9 -19
- package/dist/api/customer.cjs +0 -164
- package/dist/api/oauth.cjs +0 -238
- package/dist/cache/cache.cjs +0 -1
- package/dist/cache/cached.cjs +0 -90
- package/dist/cache/index.cjs +0 -27
- package/dist/cache/providers/unstorage.cjs +0 -55
- package/dist/constants/basket.cjs +0 -26
- package/dist/constants/cache.cjs +0 -7
- package/dist/constants/hash.cjs +0 -11
- package/dist/constants/httpStatus.cjs +0 -634
- package/dist/constants/index.cjs +0 -93
- package/dist/constants/product.cjs +0 -10
- package/dist/constants/promotion.cjs +0 -12
- package/dist/constants/sorting.cjs +0 -22
- package/dist/constants/withParameters.cjs +0 -132
- package/dist/errors/errorResponse.cjs +0 -27
- package/dist/errors/index.cjs +0 -16
- package/dist/helpers/advancedAttributeHelpers.cjs +0 -30
- package/dist/helpers/arrayHelpers.cjs +0 -10
- package/dist/helpers/attributeHelpers.cjs +0 -24
- package/dist/helpers/basketHelpers.cjs +0 -12
- package/dist/helpers/categoryHelper.cjs +0 -61
- package/dist/helpers/filterHelper.cjs +0 -185
- package/dist/helpers/formHelpers.cjs +0 -114
- package/dist/helpers/imageHelpers.cjs +0 -20
- package/dist/helpers/index.cjs +0 -181
- package/dist/helpers/localization.cjs +0 -13
- package/dist/helpers/objectHelpers.cjs +0 -19
- package/dist/helpers/orderHelpers.cjs +0 -10
- package/dist/helpers/product.fixture.cjs +0 -766
- package/dist/helpers/productDisruptorHelper.cjs +0 -37
- package/dist/helpers/productHelpers.cjs +0 -156
- package/dist/helpers/sanitizationHelpers.cjs +0 -35
- package/dist/helpers/sortingHelper.cjs +0 -68
- package/dist/helpers/stringHelpers.cjs +0 -8
- package/dist/index.cjs +0 -100
- package/dist/rpc/methods/basket/basket.cjs +0 -270
- package/dist/rpc/methods/brands.cjs +0 -33
- package/dist/rpc/methods/categories.cjs +0 -129
- package/dist/rpc/methods/cbd.cjs +0 -38
- package/dist/rpc/methods/checkout/checkout.cjs +0 -48
- package/dist/rpc/methods/checkout/index.cjs +0 -49
- package/dist/rpc/methods/checkout/order.cjs +0 -42
- package/dist/rpc/methods/checkout/shopUser.cjs +0 -110
- package/dist/rpc/methods/checkout/shopUserAddresses.cjs +0 -12
- package/dist/rpc/methods/index.cjs +0 -225
- package/dist/rpc/methods/navigationTrees.cjs +0 -54
- package/dist/rpc/methods/oauth/idp.cjs +0 -59
- package/dist/rpc/methods/products.cjs +0 -309
- package/dist/rpc/methods/promotion.cjs +0 -51
- package/dist/rpc/methods/search.cjs +0 -40
- package/dist/rpc/methods/session.cjs +0 -257
- package/dist/rpc/methods/shopConfiguration.cjs +0 -15
- package/dist/rpc/methods/user.cjs +0 -103
- package/dist/rpc/methods/variants.cjs +0 -29
- package/dist/rpc/methods/wishlist.cjs +0 -104
- package/dist/server.cjs +0 -47
- package/dist/test/factories/index.cjs +0 -16
- package/dist/types/api/auth.cjs +0 -1
- package/dist/types/api/context.cjs +0 -15
- package/dist/types/api/rpc.cjs +0 -1
- package/dist/types/breadcrumb.cjs +0 -1
- package/dist/types/index.cjs +0 -267
- package/dist/types/promises.cjs +0 -1
- package/dist/types/sapi/basket.cjs +0 -1
- package/dist/types/sapi/brand.cjs +0 -1
- package/dist/types/sapi/campaign.cjs +0 -1
- package/dist/types/sapi/category.cjs +0 -1
- package/dist/types/sapi/filter.cjs +0 -1
- package/dist/types/sapi/navigation.cjs +0 -1
- package/dist/types/sapi/order.cjs +0 -1
- package/dist/types/sapi/product.cjs +0 -1
- package/dist/types/sapi/productFilter.cjs +0 -1
- package/dist/types/sapi/promotion.cjs +0 -1
- package/dist/types/sapi/redirects.cjs +0 -1
- package/dist/types/sapi/router.cjs +0 -1
- package/dist/types/sapi/search.cjs +0 -1
- package/dist/types/sapi/sorting.cjs +0 -1
- package/dist/types/sapi/variant.cjs +0 -1
- package/dist/types/sapi/wishlist.cjs +0 -1
- package/dist/types/user.cjs +0 -1
- package/dist/utils/basket.cjs +0 -14
- package/dist/utils/fetch.cjs +0 -19
- package/dist/utils/hash.cjs +0 -72
- package/dist/utils/index.cjs +0 -49
- package/dist/utils/keys.cjs +0 -67
- package/dist/utils/log.cjs +0 -93
- package/dist/utils/response.cjs +0 -13
- package/dist/utils/sapi.cjs +0 -26
- package/dist/utils/timeout.cjs +0 -18
- package/dist/utils/user.cjs +0 -90
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @scayle/storefront-core
|
|
2
2
|
|
|
3
|
+
## 8.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- The CommonJS export format will be removed in this version. All exports are provided through ES Modules (`import`/`export`) exclusively
|
|
8
|
+
|
|
9
|
+
This change will primarily affect users who are currently using the CommonJS format of this package. To update your code, you should replace `require` statements with `import` statements and update your build tooling if necessary.
|
|
10
|
+
|
|
11
|
+
```TypeScript
|
|
12
|
+
const { ... } = require('@scayle/storefront-core');
|
|
13
|
+
|
|
14
|
+
// will become
|
|
15
|
+
|
|
16
|
+
import { ... } from '@scayle/storefront-core';
|
|
17
|
+
```
|
|
18
|
+
|
|
3
19
|
## 8.4.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -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"}@${"8.
|
|
38
|
+
}).setIssuedAt(now).setNotBefore(now).setExpirationTime("1h").setIssuer(`${"@scayle/storefront-core"}@${"8.5.0"}`).setProtectedHeader({ alg: "HS256", typ: "JWT" }).sign(secret);
|
|
39
39
|
return {
|
|
40
40
|
accessToken: refreshedAccessToken,
|
|
41
41
|
checkoutJwt
|
|
@@ -1,3 +1,25 @@
|
|
|
1
1
|
import type { SearchEntity, SearchV2ResolveEndpointParameters, SearchV2SuggestionsEndpointParameters, SearchV2SuggestionsEndpointResponseData } from '../../types/sapi/search';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches search suggestions for a given term.
|
|
4
|
+
*
|
|
5
|
+
* @param option - The parameters for the request.
|
|
6
|
+
* @param option.term - The term to search for.
|
|
7
|
+
* @param option.with - An object describing which data the returned suggestions should contain.
|
|
8
|
+
* @param option.categoryId - The category ID to search within.
|
|
9
|
+
* @param context - The rpc context associated with the request.
|
|
10
|
+
*
|
|
11
|
+
* @returns A promise that resolves to a list of search suggestions.
|
|
12
|
+
*/
|
|
2
13
|
export declare const getSearchSuggestions: ({ term, with: _with, categoryId }: SearchV2SuggestionsEndpointParameters, { sapiClient, withParams }: import("../../types").RpcContext) => Promise<Response | SearchV2SuggestionsEndpointResponseData>;
|
|
14
|
+
/**
|
|
15
|
+
* Resolves a search query and returns the resolved entity.
|
|
16
|
+
*
|
|
17
|
+
* @param option - The parameters for the search query.
|
|
18
|
+
* @param option.term - The search query to resolve.
|
|
19
|
+
* @param option.with - An object describing which data the returned result should contain.
|
|
20
|
+
* @param option.categoryId - The category ID for which the search should be performed.
|
|
21
|
+
* @param context - The rpc context associated with the request.
|
|
22
|
+
*
|
|
23
|
+
* @returns A promise that resolves to the resolved entity or null if no entity is found.
|
|
24
|
+
*/
|
|
3
25
|
export declare const resolveSearch: ({ term, with: _with, categoryId }: SearchV2ResolveEndpointParameters, { cached, sapiClient, withParams }: import("../../types").RpcContext) => Promise<SearchEntity | null>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-core",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.0",
|
|
4
4
|
"description": "Collection of essential utilities to work with the Storefront API",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,36 +14,26 @@
|
|
|
14
14
|
"./package.json": "./package.json",
|
|
15
15
|
".": {
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
|
-
"
|
|
18
|
-
"require": "./dist/index.cjs",
|
|
19
|
-
"default": "./dist/index.cjs"
|
|
17
|
+
"default": "./dist/index.mjs"
|
|
20
18
|
},
|
|
21
19
|
"./server": {
|
|
22
20
|
"types": "./dist/server.d.ts",
|
|
23
|
-
"
|
|
24
|
-
"require": "./dist/server.cjs",
|
|
25
|
-
"default": "./dist/server.cjs"
|
|
21
|
+
"default": "./dist/server.mjs"
|
|
26
22
|
},
|
|
27
23
|
"./dist/test/factories": {
|
|
28
24
|
"types": "./dist/test/factories/index.d.ts",
|
|
29
|
-
"
|
|
30
|
-
"require": "./dist/test/factories/index.cjs",
|
|
31
|
-
"default": "./dist/test/factories/index.cjs"
|
|
25
|
+
"default": "./dist/test/factories/index.mjs"
|
|
32
26
|
},
|
|
33
27
|
"./test/factories": {
|
|
34
28
|
"types": "./dist/test/factories/index.d.ts",
|
|
35
|
-
"
|
|
36
|
-
"require": "./dist/test/factories/index.cjs",
|
|
37
|
-
"default": "./dist/test/factories/index.cjs"
|
|
29
|
+
"default": "./dist/test/factories/index.mjs"
|
|
38
30
|
},
|
|
39
31
|
"./dist/*": {
|
|
40
32
|
"types": "./dist/*.d.ts",
|
|
41
|
-
"
|
|
42
|
-
"require": "./dist/*.cjs",
|
|
43
|
-
"default": "./dist/*.cjs"
|
|
33
|
+
"default": "./dist/*.mjs"
|
|
44
34
|
}
|
|
45
35
|
},
|
|
46
|
-
"main": "./dist/index.
|
|
36
|
+
"main": "./dist/index.mjs",
|
|
47
37
|
"module": "./dist/index.mjs",
|
|
48
38
|
"types": "./dist/index.d.ts",
|
|
49
39
|
"files": [
|
|
@@ -83,11 +73,11 @@
|
|
|
83
73
|
"devDependencies": {
|
|
84
74
|
"@scayle/eslint-config-storefront": "4.4.1",
|
|
85
75
|
"@types/crypto-js": "4.2.2",
|
|
86
|
-
"@types/node": "22.13.
|
|
76
|
+
"@types/node": "22.13.2",
|
|
87
77
|
"@types/webpack-env": "1.18.8",
|
|
88
78
|
"@vitest/coverage-v8": "2.1.9",
|
|
89
79
|
"dprint": "0.49.0",
|
|
90
|
-
"eslint": "9.
|
|
80
|
+
"eslint": "9.20.1",
|
|
91
81
|
"eslint-formatter-gitlab": "5.1.0",
|
|
92
82
|
"publint": "0.2.12",
|
|
93
83
|
"rimraf": "6.0.1",
|
package/dist/api/customer.cjs
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.CustomerAPIClient = void 0;
|
|
7
|
-
var _fetch = require("../utils/fetch.cjs");
|
|
8
|
-
var _httpStatus = require("../constants/httpStatus.cjs");
|
|
9
|
-
var _oauth = require("./oauth.cjs");
|
|
10
|
-
class CustomerAPIClient {
|
|
11
|
-
baseURL;
|
|
12
|
-
context;
|
|
13
|
-
additionalHeaders;
|
|
14
|
-
constructor(context) {
|
|
15
|
-
this.baseURL = context.checkout.url;
|
|
16
|
-
this.context = context;
|
|
17
|
-
this.additionalHeaders = context.internalAccessHeader ? {
|
|
18
|
-
"x-internal-access": context.internalAccessHeader
|
|
19
|
-
} : {};
|
|
20
|
-
}
|
|
21
|
-
get headers() {
|
|
22
|
-
return {
|
|
23
|
-
Authorization: `Bearer ${this.context.accessToken}`,
|
|
24
|
-
Accept: "application/json",
|
|
25
|
-
"Content-Type": "application/json",
|
|
26
|
-
...this.additionalHeaders
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
async sendRequest(request, retry = true) {
|
|
30
|
-
const response = await request();
|
|
31
|
-
if (response.ok) {
|
|
32
|
-
return await response.json();
|
|
33
|
-
}
|
|
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
|
-
if (retry) {
|
|
36
|
-
const client = (0, _oauth.getOAuthClient)(this.context);
|
|
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
|
-
}
|
|
55
|
-
return await this.sendRequest(request, false);
|
|
56
|
-
} else {
|
|
57
|
-
this.context.log.debug("Invalid Checkout Token. Deleting session");
|
|
58
|
-
await this.context.destroySession();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
throw new _fetch.FetchError(response);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Get the addresses for the current customer.
|
|
65
|
-
*
|
|
66
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/customer/address/list-addresses
|
|
67
|
-
*/
|
|
68
|
-
async getAddresses(shopId) {
|
|
69
|
-
return await this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/customer/addresses`, {
|
|
70
|
-
headers: {
|
|
71
|
-
...this.headers,
|
|
72
|
-
"X-Shop-Id": shopId.toString()
|
|
73
|
-
}
|
|
74
|
-
}));
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Returns customer data and latest orders.
|
|
78
|
-
* When not logged in, it will return `undefined`.
|
|
79
|
-
*
|
|
80
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/customer/get-customer
|
|
81
|
-
*/
|
|
82
|
-
async getMe(shopId, accessToken) {
|
|
83
|
-
return await this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/me`, {
|
|
84
|
-
headers: {
|
|
85
|
-
...this.headers,
|
|
86
|
-
...(accessToken ? {
|
|
87
|
-
Authorization: `Bearer ${accessToken}`
|
|
88
|
-
} : {}),
|
|
89
|
-
"X-Shop-Id": shopId.toString()
|
|
90
|
-
}
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Retrieve a customer's order.
|
|
95
|
-
*
|
|
96
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/order/get-order
|
|
97
|
-
*/
|
|
98
|
-
async getOrder(shopId, orderId) {
|
|
99
|
-
return this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/customer/order/${orderId}`, {
|
|
100
|
-
headers: {
|
|
101
|
-
...this.headers,
|
|
102
|
-
"X-Shop-Id": shopId.toString()
|
|
103
|
-
}
|
|
104
|
-
}));
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Update contact details of a customer.
|
|
108
|
-
*
|
|
109
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/customer/update-contact-details
|
|
110
|
-
*/
|
|
111
|
-
async updateContactInfo(shopId, {
|
|
112
|
-
email,
|
|
113
|
-
phone
|
|
114
|
-
}) {
|
|
115
|
-
return await this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/customer/contact`, {
|
|
116
|
-
method: "PUT",
|
|
117
|
-
headers: {
|
|
118
|
-
...this.headers,
|
|
119
|
-
"X-Shop-Id": shopId.toString()
|
|
120
|
-
},
|
|
121
|
-
body: JSON.stringify({
|
|
122
|
-
email,
|
|
123
|
-
phone
|
|
124
|
-
})
|
|
125
|
-
}));
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Update customer personal data.
|
|
129
|
-
*
|
|
130
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/customer/update-personal-data
|
|
131
|
-
*/
|
|
132
|
-
async updatePersonalInfo(shopId, payload) {
|
|
133
|
-
return await this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/customer/personal`, {
|
|
134
|
-
method: "PUT",
|
|
135
|
-
headers: {
|
|
136
|
-
...this.headers,
|
|
137
|
-
"X-Shop-Id": shopId.toString()
|
|
138
|
-
},
|
|
139
|
-
body: JSON.stringify(payload)
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Update customer password.
|
|
144
|
-
*
|
|
145
|
-
* @see https://scayle.dev/en/api-guides/customer-account-api/resources/customer/update-password
|
|
146
|
-
*/
|
|
147
|
-
async updatePassword(shopId, {
|
|
148
|
-
password,
|
|
149
|
-
newPassword
|
|
150
|
-
}) {
|
|
151
|
-
return await this.sendRequest(() => fetch(`${this.baseURL}/api/oauth/customer/password`, {
|
|
152
|
-
method: "PUT",
|
|
153
|
-
headers: {
|
|
154
|
-
...this.headers,
|
|
155
|
-
"X-Shop-Id": shopId.toString()
|
|
156
|
-
},
|
|
157
|
-
body: JSON.stringify({
|
|
158
|
-
password,
|
|
159
|
-
newPassword
|
|
160
|
-
})
|
|
161
|
-
}));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
exports.CustomerAPIClient = CustomerAPIClient;
|
package/dist/api/oauth.cjs
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.OAuthClient = void 0;
|
|
7
|
-
exports.getOAuthClient = getOAuthClient;
|
|
8
|
-
var _jose = require("jose");
|
|
9
|
-
var _fetch = require("../utils/fetch.cjs");
|
|
10
|
-
var _hash = require("../utils/hash.cjs");
|
|
11
|
-
class MissingCredentialsError extends Error {
|
|
12
|
-
constructor() {
|
|
13
|
-
super("[OAuth API] No credentials configured");
|
|
14
|
-
this.name = "MissingCredentialsError";
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
async function oauthResponseHandler(response) {
|
|
18
|
-
const data = await response.json();
|
|
19
|
-
if (!response.ok) {
|
|
20
|
-
throw new _fetch.FetchError(response, data);
|
|
21
|
-
}
|
|
22
|
-
return data;
|
|
23
|
-
}
|
|
24
|
-
function emptyOAuthResponseHandler(response) {
|
|
25
|
-
if (!response.ok) {
|
|
26
|
-
throw new _fetch.FetchError(response);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function getOAuthClient(context) {
|
|
30
|
-
if (!context.oauth) {
|
|
31
|
-
throw new Error("OAuth configuration is missing");
|
|
32
|
-
}
|
|
33
|
-
const clientId = context.oauth.clientId;
|
|
34
|
-
const clientSecret = context.oauth.clientSecret;
|
|
35
|
-
const apiHost = context.oauth.apiHost;
|
|
36
|
-
const accessHeader = context.internalAccessHeader;
|
|
37
|
-
return new OAuthClient({
|
|
38
|
-
clientId,
|
|
39
|
-
clientSecret,
|
|
40
|
-
apiHost,
|
|
41
|
-
additionalHeaders: accessHeader ? {
|
|
42
|
-
"x-internal-access": accessHeader
|
|
43
|
-
} : {}
|
|
44
|
-
}, context.log);
|
|
45
|
-
}
|
|
46
|
-
class OAuthClient {
|
|
47
|
-
headers;
|
|
48
|
-
baseURL;
|
|
49
|
-
logger;
|
|
50
|
-
clientId;
|
|
51
|
-
constructor(options, logger) {
|
|
52
|
-
const {
|
|
53
|
-
clientId,
|
|
54
|
-
clientSecret,
|
|
55
|
-
apiHost,
|
|
56
|
-
additionalHeaders
|
|
57
|
-
} = options;
|
|
58
|
-
if (!clientId || !clientSecret) {
|
|
59
|
-
throw new MissingCredentialsError();
|
|
60
|
-
}
|
|
61
|
-
this.clientId = clientId;
|
|
62
|
-
this.baseURL = `${apiHost}/v1`;
|
|
63
|
-
this.logger = logger ? logger.space("auth-client") : void 0;
|
|
64
|
-
const basicAuthHash = (0, _hash.encodeBase64)(`${clientId}:${clientSecret}`);
|
|
65
|
-
this.headers = {
|
|
66
|
-
Authorization: `Basic ${basicAuthHash}`,
|
|
67
|
-
Accept: "application/json",
|
|
68
|
-
"Content-Type": "application/json",
|
|
69
|
-
...additionalHeaders
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Register a new User and receive an access token.
|
|
74
|
-
*
|
|
75
|
-
* @param payload
|
|
76
|
-
*
|
|
77
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/oauth-client/create-new-user
|
|
78
|
-
*/
|
|
79
|
-
async register(payload) {
|
|
80
|
-
this.logger?.debug("Registering user");
|
|
81
|
-
return await fetch(`${this.baseURL}/auth/register`, {
|
|
82
|
-
method: "POST",
|
|
83
|
-
headers: this.headers,
|
|
84
|
-
body: JSON.stringify(payload)
|
|
85
|
-
}).then(oauthResponseHandler);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Login a User and receive an access token.
|
|
89
|
-
*
|
|
90
|
-
* @param payload
|
|
91
|
-
*
|
|
92
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/oauth-client/log-in-users
|
|
93
|
-
*/
|
|
94
|
-
async login(payload) {
|
|
95
|
-
this.logger?.debug("Logging in");
|
|
96
|
-
return await fetch(`${this.baseURL}/auth/login`, {
|
|
97
|
-
method: "POST",
|
|
98
|
-
headers: this.headers,
|
|
99
|
-
body: JSON.stringify(payload)
|
|
100
|
-
}).then(oauthResponseHandler);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Login a User as a guest and receive an access token.
|
|
104
|
-
*
|
|
105
|
-
* @param payload
|
|
106
|
-
*
|
|
107
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/oauth-client/log-in-users-as-guest
|
|
108
|
-
*/
|
|
109
|
-
async guestLogin(payload) {
|
|
110
|
-
this.logger?.debug("Logging in as guest");
|
|
111
|
-
return await fetch(`${this.baseURL}/auth/login/guest`, {
|
|
112
|
-
method: "POST",
|
|
113
|
-
headers: this.headers,
|
|
114
|
-
body: JSON.stringify(payload)
|
|
115
|
-
}).then(oauthResponseHandler);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Send a reset password email to a User.
|
|
119
|
-
*
|
|
120
|
-
* @param payload
|
|
121
|
-
*
|
|
122
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/oauth-client/send-password-reset-email
|
|
123
|
-
*/
|
|
124
|
-
async sendPasswordResetEmail(payload) {
|
|
125
|
-
this.logger?.debug("Sending password reset email");
|
|
126
|
-
await fetch(`${this.baseURL}/auth/password/send-reset-email`, {
|
|
127
|
-
method: "POST",
|
|
128
|
-
headers: this.headers,
|
|
129
|
-
body: JSON.stringify(payload)
|
|
130
|
-
}).then(emptyOAuthResponseHandler);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Update password by using hash.
|
|
134
|
-
* All older tokens of the User are also invalidated.
|
|
135
|
-
*
|
|
136
|
-
* @param payload
|
|
137
|
-
*
|
|
138
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/oauth-client/update-password-by-hash
|
|
139
|
-
*/
|
|
140
|
-
async updatePasswordByHash(payload) {
|
|
141
|
-
this.logger?.debug("Updating password by hash");
|
|
142
|
-
return await fetch(`${this.baseURL}/auth/password/update-by-hash`, {
|
|
143
|
-
method: "PUT",
|
|
144
|
-
headers: this.headers,
|
|
145
|
-
body: JSON.stringify(payload)
|
|
146
|
-
}).then(oauthResponseHandler);
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Update password via plain string.
|
|
150
|
-
*
|
|
151
|
-
* @param payload
|
|
152
|
-
* @param accessToken
|
|
153
|
-
*/
|
|
154
|
-
async updatePassword(payload, accessToken) {
|
|
155
|
-
this.logger?.debug("Updating password");
|
|
156
|
-
return await fetch(`${this.baseURL}/auth/password`, {
|
|
157
|
-
method: "PUT",
|
|
158
|
-
headers: {
|
|
159
|
-
...this.headers,
|
|
160
|
-
Authorization: `Bearer ${accessToken}`
|
|
161
|
-
},
|
|
162
|
-
body: JSON.stringify(payload)
|
|
163
|
-
}).then(emptyOAuthResponseHandler);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Generate a new access token via a refresh token.
|
|
167
|
-
*
|
|
168
|
-
* @param payload
|
|
169
|
-
*/
|
|
170
|
-
async refreshToken(payload) {
|
|
171
|
-
this.logger?.debug("Refreshing access token");
|
|
172
|
-
return await fetch(`${this.baseURL}/oauth/token`, {
|
|
173
|
-
method: "POST",
|
|
174
|
-
headers: this.headers,
|
|
175
|
-
body: JSON.stringify(payload)
|
|
176
|
-
}).then(oauthResponseHandler);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Validate a token.
|
|
180
|
-
*
|
|
181
|
-
* @param accessToken
|
|
182
|
-
*
|
|
183
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/bearer-auth/validate-present-token
|
|
184
|
-
*/
|
|
185
|
-
async validateToken(accessToken) {
|
|
186
|
-
this.logger?.debug("Validating access token");
|
|
187
|
-
await fetch(`${this.baseURL}/oauth/token/validate`, {
|
|
188
|
-
headers: {
|
|
189
|
-
...this.headers,
|
|
190
|
-
Authorization: `Bearer ${accessToken}`
|
|
191
|
-
}
|
|
192
|
-
}).then(emptyOAuthResponseHandler);
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Revoke an Access Token and all related Refresh Tokens.
|
|
196
|
-
*
|
|
197
|
-
* Uses a valid Bearer Access Token in the Authorization header and will
|
|
198
|
-
* revoke the token with the given ID (_which could be a different token_).
|
|
199
|
-
* If a external identity provider was used for the target token,
|
|
200
|
-
* the corresponding IDP-AccessToken and IDP-RefreshToken will be revoked as well.
|
|
201
|
-
* In case the identity provider does not support revoking tokens over api calls
|
|
202
|
-
* (_because a frontend redirect is required_) this step will be skipped and the IDP-Tokens
|
|
203
|
-
* will remain valid until they expire or are revoked from IDP side.
|
|
204
|
-
*
|
|
205
|
-
* @param shopId
|
|
206
|
-
* @param accessToken
|
|
207
|
-
*
|
|
208
|
-
* @see https://scayle.dev/en/api-guides/checkout-authentication-api/resources/bearer-auth/delete-access-token-with-id
|
|
209
|
-
*/
|
|
210
|
-
async revokeToken(shopId, accessToken) {
|
|
211
|
-
this.logger?.debug("Revoking access token");
|
|
212
|
-
const decodedAccessToken = (0, _jose.decodeJwt)(accessToken);
|
|
213
|
-
await fetch(`${this.baseURL}/oauth/tokens/${decodedAccessToken.jti}`, {
|
|
214
|
-
method: "DELETE",
|
|
215
|
-
headers: {
|
|
216
|
-
...this.headers,
|
|
217
|
-
"X-Shop-Id": `${shopId}`,
|
|
218
|
-
Authorization: `Bearer ${accessToken}`
|
|
219
|
-
}
|
|
220
|
-
}).then(emptyOAuthResponseHandler);
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Generate a new token based on authorization code.
|
|
224
|
-
*
|
|
225
|
-
* @param code
|
|
226
|
-
*/
|
|
227
|
-
async generateToken(code) {
|
|
228
|
-
return await fetch(`${this.baseURL}/oauth/token`, {
|
|
229
|
-
method: "POST",
|
|
230
|
-
headers: this.headers,
|
|
231
|
-
body: JSON.stringify({
|
|
232
|
-
grant_type: "authorization_code",
|
|
233
|
-
code
|
|
234
|
-
})
|
|
235
|
-
}).then(oauthResponseHandler);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
exports.OAuthClient = OAuthClient;
|
package/dist/cache/cache.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/dist/cache/cached.cjs
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.MINUTE = exports.Cached = void 0;
|
|
7
|
-
var _utils = require("../utils/index.cjs");
|
|
8
|
-
var _hash = require("../utils/hash.cjs");
|
|
9
|
-
var _constants = require("../constants/index.cjs");
|
|
10
|
-
const MINUTE = exports.MINUTE = 60;
|
|
11
|
-
const CACHE_NOT_INITIALIZED_MSG = "Cache is not initialized";
|
|
12
|
-
class Cached {
|
|
13
|
-
cache;
|
|
14
|
-
log;
|
|
15
|
-
prefix;
|
|
16
|
-
enabled;
|
|
17
|
-
constructor(cache, log, prefix = "", enabled) {
|
|
18
|
-
if (!cache) {
|
|
19
|
-
log.error(CACHE_NOT_INITIALIZED_MSG);
|
|
20
|
-
throw new Error(CACHE_NOT_INITIALIZED_MSG);
|
|
21
|
-
}
|
|
22
|
-
this.cache = cache;
|
|
23
|
-
this.log = log.space("cached.init");
|
|
24
|
-
this.prefix = prefix;
|
|
25
|
-
this.enabled = enabled;
|
|
26
|
-
}
|
|
27
|
-
get isCacheEnabled() {
|
|
28
|
-
return this.enabled;
|
|
29
|
-
}
|
|
30
|
-
execute(fn, options) {
|
|
31
|
-
return async (...args) => {
|
|
32
|
-
const prefix = options?.cacheKeyPrefix ?? fn.name;
|
|
33
|
-
const params = [...args, this?.prefix];
|
|
34
|
-
const cacheKey = options?.cacheKey ?? (await this.createCacheKey(params, prefix));
|
|
35
|
-
try {
|
|
36
|
-
const cachedResponse = await this.getCacheValue(cacheKey, options);
|
|
37
|
-
if (cachedResponse !== void 0 && cachedResponse !== null) {
|
|
38
|
-
return cachedResponse;
|
|
39
|
-
}
|
|
40
|
-
} catch (e) {
|
|
41
|
-
if (e instanceof Error) {
|
|
42
|
-
this.handleError(e);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const response = await fn(...args);
|
|
46
|
-
if (response === void 0 || response === null) {
|
|
47
|
-
return response;
|
|
48
|
-
}
|
|
49
|
-
if (response instanceof Response && !response.ok) {
|
|
50
|
-
return response;
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
await this.setCacheValue(cacheKey, response, options);
|
|
54
|
-
} catch (e) {
|
|
55
|
-
if (e instanceof Error) {
|
|
56
|
-
this.handleError(e);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return response;
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
async getCacheValue(cacheKey, options) {
|
|
63
|
-
if (!this.isCacheEnabled) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const data = await (0, _utils.timeout)(options?.timeout ?? _constants.CACHE_TIMEOUT, this.cache.get(cacheKey));
|
|
67
|
-
if (data !== null) {
|
|
68
|
-
return data;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
async setCacheValue(cacheKey, value, options) {
|
|
72
|
-
if (!this.isCacheEnabled) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const ttl = options?.ttl ?? 60 * MINUTE;
|
|
76
|
-
if (ttl) {
|
|
77
|
-
await (0, _utils.timeout)(_constants.CACHE_TIMEOUT, this.cache.set(cacheKey, value, ttl));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async createCacheKey(params, prefix = "") {
|
|
81
|
-
return [prefix, await (0, _hash.sha256)(JSON.stringify(params))].join(":");
|
|
82
|
-
}
|
|
83
|
-
handleError(error) {
|
|
84
|
-
if (error.message === "timeout") {
|
|
85
|
-
return this.log.error("Cache timeout");
|
|
86
|
-
}
|
|
87
|
-
this.log.error(error);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
exports.Cached = Cached;
|
package/dist/cache/index.cjs
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
var _cache = require("./cache.cjs");
|
|
7
|
-
Object.keys(_cache).forEach(function (key) {
|
|
8
|
-
if (key === "default" || key === "__esModule") return;
|
|
9
|
-
if (key in exports && exports[key] === _cache[key]) return;
|
|
10
|
-
Object.defineProperty(exports, key, {
|
|
11
|
-
enumerable: true,
|
|
12
|
-
get: function () {
|
|
13
|
-
return _cache[key];
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
var _cached = require("./cached.cjs");
|
|
18
|
-
Object.keys(_cached).forEach(function (key) {
|
|
19
|
-
if (key === "default" || key === "__esModule") return;
|
|
20
|
-
if (key in exports && exports[key] === _cached[key]) return;
|
|
21
|
-
Object.defineProperty(exports, key, {
|
|
22
|
-
enumerable: true,
|
|
23
|
-
get: function () {
|
|
24
|
-
return _cached[key];
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
});
|