@agnostack/next-shopify 1.13.5-beta.7 → 1.13.5
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 +7 -59
- package/dist/lib/handlers/api/graph.d.ts.map +1 -1
- package/dist/lib/handlers/api/graph.js +79 -84
- package/dist/lib/handlers/api/graph.js.map +1 -1
- package/dist/lib/handlers/api/proxy.d.ts.map +1 -1
- package/dist/lib/handlers/api/proxy.js +149 -115
- package/dist/lib/handlers/api/proxy.js.map +1 -1
- package/dist/lib/handlers/api/rest.d.ts.map +1 -1
- package/dist/lib/handlers/api/rest.js +65 -70
- package/dist/lib/handlers/api/rest.js.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +4 -5
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/utils/index.d.ts +0 -1
- package/dist/lib/utils/index.js +0 -1
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/session.d.ts.map +1 -1
- package/dist/lib/utils/session.js +2 -2
- package/dist/lib/utils/session.js.map +1 -1
- package/dist/shared/display.d.ts +23 -88
- package/dist/shared/display.d.ts.map +1 -1
- package/dist/shared/display.js +104 -409
- package/dist/shared/display.js.map +1 -1
- package/dist/shared/index.d.ts +0 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +0 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/shopify.d.ts +6 -0
- package/dist/shared/shopify.d.ts.map +1 -1
- package/dist/shared/shopify.js +28 -1
- package/dist/shared/shopify.js.map +1 -1
- package/package.json +1 -6
- package/dist/lib/utils/verification.d.ts +0 -2
- package/dist/lib/utils/verification.d.ts.map +0 -1
- package/dist/lib/utils/verification.js +0 -69
- package/dist/lib/utils/verification.js.map +0 -1
- package/dist/react/hooks/index.d.ts +0 -2
- package/dist/react/hooks/index.d.ts.map +0 -1
- package/dist/react/hooks/index.js +0 -5
- package/dist/react/hooks/index.js.map +0 -1
- package/dist/react/hooks/useVerification.d.ts +0 -9
- package/dist/react/hooks/useVerification.d.ts.map +0 -1
- package/dist/react/hooks/useVerification.js +0 -63
- package/dist/react/hooks/useVerification.js.map +0 -1
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js +0 -5
- package/dist/react/index.js.map +0 -1
- package/dist/react/types.d.ts +0 -1
- package/dist/react/types.d.ts.map +0 -1
- package/dist/react/types.js +0 -1
- package/dist/react/types.js.map +0 -1
- package/dist/shared/datetime.d.ts +0 -96
- package/dist/shared/datetime.d.ts.map +0 -1
- package/dist/shared/datetime.js +0 -285
- package/dist/shared/datetime.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,52 +1,24 @@
|
|
|
1
|
-
## [1.13.5
|
|
1
|
+
## [1.13.5](https://github.com/agnostack/next-shopify/compare/v1.13.4...v1.13.5) (2023-11-30)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
* wip ([
|
|
6
|
+
* wip ([d0e3583](https://github.com/agnostack/next-shopify/commit/d0e35831a73f4c8ffc0a8f073a25bf37f6877502))
|
|
7
|
+
* wip ([6bc1e78](https://github.com/agnostack/next-shopify/commit/6bc1e78c764fde2673669c80ad525f733f413d7f))
|
|
7
8
|
|
|
8
|
-
## [1.13.5-
|
|
9
|
+
## [1.13.5-alpha.2](https://github.com/agnostack/next-shopify/compare/v1.13.5-alpha.1...v1.13.5-alpha.2) (2023-11-30)
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
### Bug Fixes
|
|
12
13
|
|
|
13
|
-
* wip ([
|
|
14
|
+
* wip ([d0e3583](https://github.com/agnostack/next-shopify/commit/d0e35831a73f4c8ffc0a8f073a25bf37f6877502))
|
|
14
15
|
|
|
15
|
-
## [1.13.5-
|
|
16
|
+
## [1.13.5-alpha.1](https://github.com/agnostack/next-shopify/compare/v1.13.4...v1.13.5-alpha.1) (2023-11-30)
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
### Bug Fixes
|
|
19
20
|
|
|
20
|
-
* wip ([
|
|
21
|
-
|
|
22
|
-
## [1.13.5-beta.4](https://github.com/agnostack/next-shopify/compare/v1.13.5-beta.3...v1.13.5-beta.4) (2023-11-29)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
### Bug Fixes
|
|
26
|
-
|
|
27
|
-
* wip ([ecd3625](https://github.com/agnostack/next-shopify/commit/ecd36257e4cde1bbdea48b895934e82ecedf0612))
|
|
28
|
-
|
|
29
|
-
## [1.13.5-beta.3](https://github.com/agnostack/next-shopify/compare/v1.13.5-beta.2...v1.13.5-beta.3) (2023-11-29)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
### Bug Fixes
|
|
33
|
-
|
|
34
|
-
* wip ([825f688](https://github.com/agnostack/next-shopify/commit/825f688f614be631c13a70e1c652c45f742408ed))
|
|
35
|
-
|
|
36
|
-
## [1.13.5-beta.2](https://github.com/agnostack/next-shopify/compare/v1.13.5-beta.1...v1.13.5-beta.2) (2023-11-29)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
### Bug Fixes
|
|
40
|
-
|
|
41
|
-
* wip ([a66af1e](https://github.com/agnostack/next-shopify/commit/a66af1e574e9e1cc08b2718c4a49f46caf42db9f))
|
|
42
|
-
|
|
43
|
-
## [1.13.5-beta.1](https://github.com/agnostack/next-shopify/compare/v1.13.4...v1.13.5-beta.1) (2023-11-29)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
### Bug Fixes
|
|
47
|
-
|
|
48
|
-
* added react export and useVerification ([7131369](https://github.com/agnostack/next-shopify/commit/71313698da5b30b94a0b28fa9a0d6e595e16c5bd))
|
|
49
|
-
* wip ([ab11674](https://github.com/agnostack/next-shopify/commit/ab116749073075133350e46d272b5475bb6e9d1b))
|
|
21
|
+
* wip ([6bc1e78](https://github.com/agnostack/next-shopify/commit/6bc1e78c764fde2673669c80ad525f733f413d7f))
|
|
50
22
|
|
|
51
23
|
## [1.13.4](https://github.com/agnostack/next-shopify/compare/v1.13.3...v1.13.4) (2023-11-29)
|
|
52
24
|
|
|
@@ -587,29 +559,6 @@
|
|
|
587
559
|
* updated for old headers ([acdc756](https://github.com/agnostack/next-shopify/commit/acdc756e31f87a30b8ab3e74544668cc5ac8bde3))
|
|
588
560
|
* updated for old headerss ([ff0db89](https://github.com/agnostack/next-shopify/commit/ff0db899dade86c24bb17b8a61c7a8a4024b85a0))
|
|
589
561
|
|
|
590
|
-
## [1.13.3-beta.3](https://github.com/agnostack/next-shopify/compare/v1.13.3-beta.2...v1.13.3-beta.3) (2023-11-26)
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
### Bug Fixes
|
|
594
|
-
|
|
595
|
-
* updated for old headers ([acdc756](https://github.com/agnostack/next-shopify/commit/acdc756e31f87a30b8ab3e74544668cc5ac8bde3))
|
|
596
|
-
* updated for old headerss ([ff0db89](https://github.com/agnostack/next-shopify/commit/ff0db899dade86c24bb17b8a61c7a8a4024b85a0))
|
|
597
|
-
|
|
598
|
-
## [1.13.3-beta.2](https://github.com/agnostack/next-shopify/compare/v1.13.3-beta.1...v1.13.3-beta.2) (2023-11-22)
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
### Bug Fixes
|
|
602
|
-
|
|
603
|
-
* exposed subtle crypto ([2a915d5](https://github.com/agnostack/next-shopify/commit/2a915d58914ae8ce54149dc81899caf8e9bc4ec1))
|
|
604
|
-
|
|
605
|
-
## [1.13.3-beta.1](https://github.com/agnostack/next-shopify/compare/v1.13.2...v1.13.3-beta.1) (2023-11-22)
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
### Bug Fixes
|
|
609
|
-
|
|
610
|
-
* exposed subtle crypto ([3f9f0ab](https://github.com/agnostack/next-shopify/commit/3f9f0ab48a75317c6d9d7dd2251cc9d51f222da4))
|
|
611
|
-
* exposed subtle crypto ([c68c1cc](https://github.com/agnostack/next-shopify/commit/c68c1cc0e0ea35dea83272db9c812f6c09e46201))
|
|
612
|
-
|
|
613
562
|
## [1.13.2](https://github.com/agnostack/next-shopify/compare/v1.13.1...v1.13.2) (2023-11-22)
|
|
614
563
|
|
|
615
564
|
|
|
@@ -627,7 +576,6 @@
|
|
|
627
576
|
* wip ([d1e3b84](https://github.com/agnostack/next-shopify/commit/d1e3b847764dc9341404c5ecd37428bfde2f26ec))
|
|
628
577
|
* wip ([e10a3a6](https://github.com/agnostack/next-shopify/commit/e10a3a67e4d3fe5bbb743a968730847b4479eb89))
|
|
629
578
|
* wip ([860ac69](https://github.com/agnostack/next-shopify/commit/860ac69b07e173f5098169673cf3e64c34aac52c))
|
|
630
|
-
|
|
631
579
|
## [1.13.1](https://github.com/agnostack/next-shopify/compare/v1.13.0...v1.13.1) (2023-11-17)
|
|
632
580
|
|
|
633
581
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../../src/lib/handlers/api/graph.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../../src/lib/handlers/api/graph.js"],"names":[],"mappings":"AAkBO,yGA0GN"}
|
|
@@ -5,94 +5,89 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const shopify_api_1 = require("@shopify/shopify-api");
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
7
|
const shared_1 = require("../../../shared");
|
|
8
|
-
const handleGraph = (serverRuntimeConfig) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
console.error(`${message}. Billing Error - ${error.message}.`, error.errorData);
|
|
54
|
-
statusCode = 402;
|
|
55
|
-
if (error === null || error === void 0 ? void 0 : error.message) {
|
|
56
|
-
message = error.message;
|
|
57
|
-
}
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
case error instanceof shopify_api_1.GraphqlQueryError: {
|
|
61
|
-
const errorMessages = (0, shared_1.ensureArray)((_b = error.response) === null || _b === void 0 ? void 0 : _b.errors).map(({ message }) => (0, shared_1.ensureString)(message));
|
|
62
|
-
console.error(`${message}. ${errorMessages.join('. ')}.`);
|
|
63
|
-
// HMMMM, should this be:
|
|
64
|
-
// message = `${message}. ${errorMessages.join('. ')}.`
|
|
65
|
-
// TODO: why are these not sending back different error codes?
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
default: {
|
|
69
|
-
console.error(`${message}. HandleGraph Error - ${error.message}.`);
|
|
70
|
-
break;
|
|
8
|
+
const handleGraph = (serverRuntimeConfig) => (req, res, params) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const { body = '{}' } = req, _c = req.query, _d = _c === void 0 ? {} : _c, { shop, apiVersion } = _d, _query = tslib_1.__rest(_d, ["shop", "apiVersion"]);
|
|
11
|
+
const _e = params !== null && params !== void 0 ? params : JSON.parse(body), { isOnline, query: graphQuery, variables: graphVariables, transform = (_data) => _data } = _e, graphParams = tslib_1.__rest(_e, ["isOnline", "query", "variables", "transform"]);
|
|
12
|
+
let query = _query;
|
|
13
|
+
if ((0, shared_1.isType)(query, 'string')) {
|
|
14
|
+
query = (0, shared_1.querystringToObject)(query);
|
|
15
|
+
}
|
|
16
|
+
if ((0, shared_1.stringEmpty)(shop) || (0, shared_1.stringEmpty)(graphQuery)) {
|
|
17
|
+
return res.status(400).json({ message: 'Invalid arguments' });
|
|
18
|
+
}
|
|
19
|
+
let statusCode;
|
|
20
|
+
let response;
|
|
21
|
+
let headers = {};
|
|
22
|
+
let message = 'Error handling query call';
|
|
23
|
+
try {
|
|
24
|
+
const { getVerifiedClients } = yield (0, utils_1.getShopifyHelpers)(serverRuntimeConfig, { shop });
|
|
25
|
+
const { Graphql } = yield getVerifiedClients({ req, res, shop, apiVersion, isOnline });
|
|
26
|
+
response = yield Graphql.query(Object.assign(Object.assign({ data: graphVariables ? {
|
|
27
|
+
query: graphQuery,
|
|
28
|
+
variables: graphVariables,
|
|
29
|
+
} : graphQuery }, (0, shared_1.objectNotEmpty)(query) && { query }), graphParams));
|
|
30
|
+
statusCode = 200;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
statusCode = 500;
|
|
34
|
+
// TODO: clean up to share between rest and graph (pr at least keep in sync)
|
|
35
|
+
switch (true) {
|
|
36
|
+
case error instanceof shared_1.ShopifyAuthenticationError: {
|
|
37
|
+
console.error(`${message}. Authentication Error.`, error);
|
|
38
|
+
const errorResponse = (0, utils_1.getAuthErrorResponse)(serverRuntimeConfig, { error, shop });
|
|
39
|
+
statusCode = errorResponse.statusCode;
|
|
40
|
+
message = errorResponse.message;
|
|
41
|
+
// HMMMM, should this be:
|
|
42
|
+
// message = `${message}. Authentication Error - ${errroResponse.message}.`
|
|
43
|
+
headers = errorResponse.headers;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case error instanceof shopify_api_1.BillingError: {
|
|
47
|
+
// HMMMM, should this be:
|
|
48
|
+
// message = `${message}. Billing Error - ${error.message}.`
|
|
49
|
+
console.error(`${message}. Billing Error - ${error.message}.`, error.errorData);
|
|
50
|
+
statusCode = 402;
|
|
51
|
+
if (error === null || error === void 0 ? void 0 : error.message) {
|
|
52
|
+
message = error.message;
|
|
71
53
|
}
|
|
54
|
+
break;
|
|
72
55
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if ((0, shared_1.arrayNotEmpty)(userErrors)) {
|
|
85
|
-
const errorMessages = (0, shared_1.ensureArray)(userErrors).map(({ message }) => (0, shared_1.ensureString)(message));
|
|
86
|
-
return res.status(500).json({ message: `${message}. ${errorMessages.join('. ')}.` });
|
|
56
|
+
case error instanceof shopify_api_1.GraphqlQueryError: {
|
|
57
|
+
const errorMessages = (0, shared_1.ensureArray)((_a = error.response) === null || _a === void 0 ? void 0 : _a.errors).map(({ message }) => (0, shared_1.ensureString)(message));
|
|
58
|
+
console.error(`${message}. ${errorMessages.join('. ')}.`);
|
|
59
|
+
// HMMMM, should this be:
|
|
60
|
+
// message = `${message}. ${errorMessages.join('. ')}.`
|
|
61
|
+
// TODO: why are these not sending back different error codes?
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
default: {
|
|
65
|
+
console.error(`${message}. HandleGraph Error - ${error.message}.`);
|
|
66
|
+
break;
|
|
87
67
|
}
|
|
88
|
-
// NOTE: sending in both to transform in case someone needs the userErrors
|
|
89
|
-
return res.status(statusCode).json(transform(responseData, responseBody));
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
console.error(`${message}. Transformation Error.`, error);
|
|
93
|
-
return res.status(500).json({ message });
|
|
94
68
|
}
|
|
69
|
+
}
|
|
70
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
71
|
+
res.setHeader(key, value);
|
|
95
72
|
});
|
|
96
|
-
|
|
73
|
+
if (!(response === null || response === void 0 ? void 0 : response.body)) {
|
|
74
|
+
return res.status(statusCode).json({ message });
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const responseBody = (_b = response.body.data) !== null && _b !== void 0 ? _b : response.body;
|
|
78
|
+
const [_responseData] = Object.values((0, shared_1.ensureObject)(responseBody));
|
|
79
|
+
const _f = (0, shared_1.ensureObject)(_responseData), { userErrors } = _f, responseData = tslib_1.__rest(_f, ["userErrors"]);
|
|
80
|
+
if ((0, shared_1.arrayNotEmpty)(userErrors)) {
|
|
81
|
+
const errorMessages = (0, shared_1.ensureArray)(userErrors).map(({ message }) => (0, shared_1.ensureString)(message));
|
|
82
|
+
return res.status(500).json({ message: `${message}. ${errorMessages.join('. ')}.` });
|
|
83
|
+
}
|
|
84
|
+
// NOTE: sending in both to transform in case someone needs the userErrors
|
|
85
|
+
return res.status(statusCode).json(transform(responseData, responseBody));
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error(`${message}. Transformation Error.`, error);
|
|
89
|
+
return res.status(500).json({ message });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
97
92
|
exports.handleGraph = handleGraph;
|
|
98
93
|
//# sourceMappingURL=graph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../../src/lib/handlers/api/graph.js"],"names":[],"mappings":";;;;AAAA,sDAAsE;AAEtE,
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../../src/lib/handlers/api/graph.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/lib/handlers/api/proxy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/lib/handlers/api/proxy.js"],"names":[],"mappings":"AAsCO,sHAgPN"}
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
6
6
|
const nextjs_cors_1 = tslib_1.__importDefault(require("nextjs-cors"));
|
|
7
7
|
const http_proxy_1 = tslib_1.__importDefault(require("http-proxy"));
|
|
8
|
+
const raw_body_1 = tslib_1.__importDefault(require("raw-body"));
|
|
8
9
|
const node_http_proxy_json_1 = tslib_1.__importDefault(require("node-http-proxy-json"));
|
|
9
10
|
const utils_1 = require("../../utils");
|
|
10
11
|
const shared_1 = require("../../../shared");
|
|
@@ -13,131 +14,164 @@ const verifyAppProxySignature = (signature, verifiable, hmacSecret) => {
|
|
|
13
14
|
const hmac = (0, utils_1.generateHMAC)((0, shared_1.objectToSortedString)(verifiable), hmacSecret);
|
|
14
15
|
return (0, utils_1.compareHashes)(signature, hmac);
|
|
15
16
|
};
|
|
16
|
-
const handleProxy = (serverRuntimeConfig, config) => {
|
|
17
|
+
const handleProxy = (serverRuntimeConfig, config) => (req, res, params) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
var _a, _b;
|
|
17
19
|
const { generateReplacements } = config !== null && config !== void 0 ? config : {};
|
|
18
|
-
const { API_PATHS, APP_CONFIG, APP_BASE_URL, TARGET_SAFELIST, ORIGIN_SAFELIST, } = serverRuntimeConfig;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
20
|
+
const { keyPairs, API_PATHS, APP_CONFIG, APP_BASE_URL, TARGET_SAFELIST, ORIGIN_SAFELIST, } = serverRuntimeConfig;
|
|
21
|
+
const _c = (_a = req.headers) !== null && _a !== void 0 ? _a : {}, { origin, 'x-api-key': apiKey, 'x-ephemeral-key': ephemeralPublicKey, 'x-authorization-timestamp': customAuthTimestamp, 'x-authorization': customAuth, 'x-forwarded-for': _forwardFor, 'x-forwarded-proto': _forwardProto, 'x-forwarded-host': forwardHost, 'x-proxy-origin': proxyOrigin } = _c, _headers = tslib_1.__rest(_c, ["origin", 'x-api-key', 'x-ephemeral-key', 'x-authorization-timestamp', 'x-authorization', 'x-forwarded-for', 'x-forwarded-proto', 'x-forwarded-host', 'x-proxy-origin']);
|
|
22
|
+
const { 'x-extension-session': sessionToken, 'x-extension-point': extensionPoint, 'x-shop-domain': shopDomainHeader, 'x-shopify-shop-domain': shopifyShopDomainHeader, 'x-shopify-shop': shopHeader = shopifyShopDomainHeader !== null && shopifyShopDomainHeader !== void 0 ? shopifyShopDomainHeader : shopDomainHeader, 'x-shopify-app-id': shopifyAppId, 'x-app-id': appId = shopifyAppId,
|
|
23
|
+
// 'x-shopify-app-installation-id': shopifyAppInstallationId,
|
|
24
|
+
// 'x-app-installation-id': appInstallationId = shopifyAppInstallationId, // TODO: pass along installationId??
|
|
25
|
+
// TODO: pass along providerSetId??
|
|
26
|
+
} = _headers;
|
|
27
|
+
let targetPath;
|
|
28
|
+
try {
|
|
29
|
+
const [authProtocol, authSignature] = (0, shared_1.ensureString)(customAuth).split(' ');
|
|
30
|
+
const isVerifiable = (apiKey &&
|
|
31
|
+
ephemeralPublicKey &&
|
|
32
|
+
(keyPairs === null || keyPairs === void 0 ? void 0 : keyPairs.shared) &&
|
|
33
|
+
customAuthTimestamp &&
|
|
34
|
+
authSignature &&
|
|
35
|
+
(authProtocol === 'HMAC-SHA256'));
|
|
36
|
+
let verificationKeys;
|
|
37
|
+
// NOTE raw request body is required for shopify's validation
|
|
38
|
+
const _rawBody = yield (0, raw_body_1.default)(req);
|
|
39
|
+
const rawBody = _rawBody.toString();
|
|
40
|
+
const parsedBody = JSON.parse(rawBody || '{}'); // NOTE: parsedBody should be encrypted when isVerifiable
|
|
41
|
+
let decryptedBody = parsedBody;
|
|
42
|
+
// NOTE: GET requests are not always sending along origin
|
|
43
|
+
if ((0, shared_1.stringEmpty)(origin)) {
|
|
44
|
+
req.headers = Object.assign(Object.assign({}, req.headers), { origin: proxyOrigin || forwardHost });
|
|
45
|
+
}
|
|
46
|
+
const _d = (_b = req.query) !== null && _b !== void 0 ? _b : {}, { signature, proxyEncoded } = _d, verifiable = tslib_1.__rest(_d, ["signature", "proxyEncoded"]);
|
|
47
|
+
const { shop: _shop, host, timestamp, path_prefix } = verifiable;
|
|
48
|
+
const shop = _shop || shopHeader;
|
|
49
|
+
yield (0, nextjs_cors_1.default)(req, res, {
|
|
50
|
+
methods: ['PUT', 'PATCH', 'POST', 'DELETE'],
|
|
51
|
+
origin: (origin, callback) => {
|
|
52
|
+
const isSafelisted = (0, shared_1.matchHostname)(origin, [
|
|
53
|
+
...ORIGIN_SAFELIST,
|
|
54
|
+
'cdn.shopify.com' // NOTE: this is the domain for checkout UI extensions
|
|
55
|
+
]);
|
|
56
|
+
if (isSafelisted) {
|
|
57
|
+
return callback(null, true);
|
|
58
|
+
}
|
|
59
|
+
return callback(new Error('Invalid CORS origin'));
|
|
60
|
+
},
|
|
61
|
+
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
|
|
62
|
+
});
|
|
63
|
+
const { target: targetParam } = params !== null && params !== void 0 ? params : {};
|
|
64
|
+
// eslint-disable-next-line max-len
|
|
65
|
+
const _targetUrl = ((0, shared_1.stringEmpty)(targetParam) || targetParam.startsWith('http')) ? targetParam : `${APP_BASE_URL}/${(0, shared_1.removeLeadingSlash)(targetParam)}`;
|
|
66
|
+
const { origin: target, hostname, pathname, search } = (0, shared_1.stringNotEmpty)(_targetUrl) ? new URL(_targetUrl) : {};
|
|
67
|
+
targetPath = [pathname, search].filter(shared_1.stringNotEmpty).join('');
|
|
68
|
+
const safelistedTarget = (0, shared_1.matchHostname)(hostname, Object.assign({ [new URL(APP_BASE_URL).hostname]: {
|
|
69
|
+
// HMMM: can we generate our own session token (or use the current one) so as to not have to tell handleGraph/Rest to behave as offline?
|
|
70
|
+
// headers: {
|
|
71
|
+
// Authorization: 'Bearer {{setting.zendesk.token}}',
|
|
72
|
+
// },
|
|
73
|
+
params: {
|
|
74
|
+
shop,
|
|
75
|
+
host,
|
|
48
76
|
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if ((
|
|
67
|
-
|
|
77
|
+
} }, TARGET_SAFELIST));
|
|
78
|
+
if ((0, shared_1.stringEmpty)(targetPath) || (safelistedTarget == undefined)) {
|
|
79
|
+
return res.status(407).json({ message: 'Unproxyable target' });
|
|
80
|
+
}
|
|
81
|
+
if (!shop || !host || !extensionPoint || !signature || !proxyEncoded) {
|
|
82
|
+
return res.status(400).json({ message: 'Invalid or missing headers', extensionPoint });
|
|
83
|
+
}
|
|
84
|
+
const isShopifyOriginOrRelative = (0, shared_1.stringNotEmpty)((0, shared_1.ensureString)(path_prefix).startsWith('http')
|
|
85
|
+
? (0, shared_1.sanitizeShop)(new URL(path_prefix).hostname)
|
|
86
|
+
: path_prefix);
|
|
87
|
+
// TODO: once Shopify fixes CORS issue when origin is cdn.shopify.com, update this!
|
|
88
|
+
if (!verifyAppProxySignature(signature, verifiable, isShopifyOriginOrRelative ? APP_CONFIG.apiSecretKey : timestamp)) {
|
|
89
|
+
return res.status(403).json({ message: 'Invalid signature' });
|
|
90
|
+
}
|
|
91
|
+
// TODO: clean up targetParam.startsWith??
|
|
92
|
+
if (!targetParam.startsWith(API_PATHS[shared_1.API_ROUTE_NAMES.SESSION_TOKEN])) {
|
|
93
|
+
const _getVerifiedSessionData = (0, utils_1.getVerifiedSessionData)(serverRuntimeConfig);
|
|
94
|
+
if (!_getVerifiedSessionData(sessionToken, { shop, host }).catch((_error) => {
|
|
95
|
+
if (_error instanceof shared_1.ShopifySessionInvalidError) {
|
|
96
|
+
return res.status(403).json({ message: _error.message });
|
|
97
|
+
}
|
|
98
|
+
throw _error;
|
|
99
|
+
})) {
|
|
100
|
+
return res.status(403).json({ message: 'Unverified signature' });
|
|
68
101
|
}
|
|
69
|
-
|
|
70
|
-
|
|
102
|
+
}
|
|
103
|
+
const { headers: targetHeaders, params: targetParams } = (0, shared_1.ensureObject)(safelistedTarget);
|
|
104
|
+
if ((0, shared_1.objectNotEmpty)(targetParams)) {
|
|
105
|
+
targetPath = (0, shared_1.appendQuery)(targetPath, new URLSearchParams(targetParams).toString());
|
|
106
|
+
}
|
|
107
|
+
// TEMP!!! remove isVerifiable check once webwidget moved to react
|
|
108
|
+
if (isVerifiable) {
|
|
109
|
+
if (!apiKey || !ephemeralPublicKey || !(keyPairs === null || keyPairs === void 0 ? void 0 : keyPairs.shared) || !customAuthTimestamp || !authSignature || (authProtocol !== 'HMAC-SHA256')) {
|
|
110
|
+
return res.status(401).json({ message: 'Invalid or missing authorization' });
|
|
71
111
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
:
|
|
75
|
-
|
|
76
|
-
if (!
|
|
77
|
-
return res.status(
|
|
112
|
+
verificationKeys = yield shared_1.subtle.getVerificationKeys({
|
|
113
|
+
publicKey: ephemeralPublicKey,
|
|
114
|
+
privateKey: keyPairs.shared.privateKey,
|
|
115
|
+
});
|
|
116
|
+
if (!verificationKeys) {
|
|
117
|
+
return res.status(412).json({ message: 'Invalid or missing verification' });
|
|
78
118
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (_error instanceof shared_1.ShopifySessionInvalidError) {
|
|
84
|
-
return res.status(403).json({ message: _error.message });
|
|
85
|
-
}
|
|
86
|
-
throw _error;
|
|
87
|
-
})) {
|
|
88
|
-
return res.status(403).json({ message: 'Unverified signature' });
|
|
89
|
-
}
|
|
119
|
+
const verificationPayload = (0, shared_1.objectToSortedString)(Object.assign({ method: (0, shared_1.getRequestMethod)(rawBody, req.method), timestamp: customAuthTimestamp, body: parsedBody }, (0, shared_1.normalizeURIParts)(targetPath)));
|
|
120
|
+
const isValid = yield shared_1.subtle.verifyHMAC(verificationPayload, verificationKeys.derivedHMACKey, authSignature);
|
|
121
|
+
if (!isValid) {
|
|
122
|
+
return res.status(412).json({ message: 'Invalid or missing verification' });
|
|
90
123
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
if (rawBody) {
|
|
125
|
+
const decryptedMessage = yield shared_1.subtle.decryptMessage(parsedBody, verificationKeys.derivedSecretKey);
|
|
126
|
+
decryptedBody = JSON.parse(decryptedMessage !== null && decryptedMessage !== void 0 ? decryptedMessage : '{}');
|
|
94
127
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
128
|
+
}
|
|
129
|
+
const _prepareHeaders = (0, utils_1.prepareHeaders)(serverRuntimeConfig);
|
|
130
|
+
const headers = yield _prepareHeaders({
|
|
131
|
+
generateReplacements,
|
|
132
|
+
shop,
|
|
133
|
+
appId,
|
|
134
|
+
headers: Object.assign(Object.assign({}, _headers), targetHeaders),
|
|
135
|
+
});
|
|
136
|
+
const proxy = http_proxy_1.default.createProxy();
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
req.url = targetPath;
|
|
139
|
+
if (headers) {
|
|
140
|
+
req.headers = headers;
|
|
141
|
+
}
|
|
142
|
+
proxy.on('proxyReq', (proxyReq, proxyReqRequest, proxyReqResponse, options) => {
|
|
143
|
+
if ((0, shared_1.objectNotEmpty)(decryptedBody)) {
|
|
144
|
+
const bodyData = JSON.stringify(decryptedBody);
|
|
145
|
+
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
|
|
146
|
+
proxyReq.write(bodyData);
|
|
109
147
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
148
|
+
});
|
|
149
|
+
proxy.on('proxyRes', function (proxyRes, proxyResRequest, proxyResResponse) {
|
|
150
|
+
(0, node_http_proxy_json_1.default)(proxyResResponse, proxyRes, function (proxyResBody) {
|
|
151
|
+
if (!proxyResBody || !isVerifiable || !verificationKeys) {
|
|
152
|
+
return proxyResBody;
|
|
115
153
|
}
|
|
116
|
-
|
|
117
|
-
proxy.on('proxyRes', function (proxyRes, proxyResRequest, proxyResResponse) {
|
|
118
|
-
(0, node_http_proxy_json_1.default)(proxyResResponse, proxyRes, function (proxyResBody) {
|
|
119
|
-
return processResponse(proxyResBody);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
proxy.once('error', (error) => {
|
|
123
|
-
console.error('Proxy error', error);
|
|
124
|
-
reject(error);
|
|
125
|
-
});
|
|
126
|
-
proxy.web(req, res, {
|
|
127
|
-
target,
|
|
128
|
-
timeout: PROXY_TIMEOUT,
|
|
129
|
-
proxyTimeout: PROXY_TIMEOUT,
|
|
130
|
-
followRedirects: false,
|
|
131
|
-
changeOrigin: true,
|
|
132
|
-
secure: true,
|
|
154
|
+
return shared_1.subtle.encryptMessage(JSON.stringify(proxyResBody), verificationKeys.derivedSecretKey);
|
|
133
155
|
});
|
|
134
156
|
});
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
proxy.once('error', (error) => {
|
|
158
|
+
console.error('Proxy error', error);
|
|
159
|
+
reject(error);
|
|
160
|
+
});
|
|
161
|
+
proxy.web(req, res, {
|
|
162
|
+
target,
|
|
163
|
+
timeout: PROXY_TIMEOUT,
|
|
164
|
+
proxyTimeout: PROXY_TIMEOUT,
|
|
165
|
+
followRedirects: false,
|
|
166
|
+
changeOrigin: true,
|
|
167
|
+
secure: true,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
console.error(`Error handling proxy request for '${targetPath}'`, error);
|
|
173
|
+
return res.status(200).json({ message: (error === null || error === void 0 ? void 0 : error.message) || 'Error handling proxy request', targetPath });
|
|
174
|
+
}
|
|
175
|
+
});
|
|
142
176
|
exports.handleProxy = handleProxy;
|
|
143
177
|
//# sourceMappingURL=proxy.js.map
|