@commercetools-backend/express 21.6.0 → 21.8.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/LICENSE +1 -1
- package/README.md +1 -69
- package/dist/commercetools-backend-express.cjs.dev.js +47 -10
- package/dist/commercetools-backend-express.cjs.prod.js +47 -10
- package/dist/commercetools-backend-express.esm.js +45 -10
- package/dist/declarations/src/types.d.ts +30 -0
- package/dist/declarations/src/utils.d.ts +3 -2
- package/package.json +2 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -14,72 +14,4 @@ This package is primarily built for HTTP servers used by Custom Applications and
|
|
|
14
14
|
$ npm install --save @commercetools-backend/express
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
This Express.js middleware should be used to handle the authentication exchange between the server and the `/proxy/forward-to` endpoint of the Merchant Center API Gateway.
|
|
20
|
-
|
|
21
|
-
> You can read more about the "Proxy to External API" concepts [here](https://docs.commercetools.com/custom-applications/main-concepts/proxy-to-external-api).
|
|
22
|
-
|
|
23
|
-
```js
|
|
24
|
-
const {
|
|
25
|
-
createSessionMiddleware,
|
|
26
|
-
CLOUD_IDENTIFIERS,
|
|
27
|
-
} = require('@commercetools-backend/express');
|
|
28
|
-
|
|
29
|
-
app.use(
|
|
30
|
-
createSessionMiddleware({
|
|
31
|
-
audience: 'https://my-api-server.com',
|
|
32
|
-
issuer: CLOUD_IDENTIFIERS.GCP_EU,
|
|
33
|
-
})
|
|
34
|
-
);
|
|
35
|
-
app.use((request, response, next) => {
|
|
36
|
-
// `request.session` contains the useful information
|
|
37
|
-
});
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Middleware options
|
|
41
|
-
|
|
42
|
-
- `audience` (_string_): The public-facing URL of your API server. The value should only contain the origin URL (protocol, hostname, port), the request path is inferred from the incoming request.
|
|
43
|
-
|
|
44
|
-
- `issuer` (_string_): Either a cloud identifier or a valid URL to the Merchant Center API Gateway. The cloud identifier maps to the Merchant Center API URL of the related [cloud region](https://docs.commercetools.com/custom-applications/concepts/merchant-center-api#cloud-regions).
|
|
45
|
-
|
|
46
|
-
- `gcp-au`: `https://mc-api.australia-southeast1.gcp.commercetools.com`
|
|
47
|
-
- `gcp-eu`: `https://mc-api.europe-west1.gcp.commercetools.com`
|
|
48
|
-
- `gcp-us`: `https://mc-api.us-central1.gcp.commercetools.com`
|
|
49
|
-
- `aws-fra`: `https://mc-api.eu-central-1.aws.commercetools.com`
|
|
50
|
-
- `aws-ohio`: `https://mc-api.us-east-2.aws.commercetools.com`
|
|
51
|
-
|
|
52
|
-
- `inferIssuer` (_boolean_): Determines whether the issuer should be inferred from the custom request HTTP header `x-mc-api-cloud-identifier` which is sent by the Merchant Center API Gateway when forwarding the request. This might be useful in case the server is used in multiple regions.
|
|
53
|
-
|
|
54
|
-
- `jwks` (_object_): See options of `jwks-rsa`.
|
|
55
|
-
|
|
56
|
-
### Usage in Serverless Functions
|
|
57
|
-
|
|
58
|
-
If your HTTP server runs as a Serverless Function, the Express.js middleware should not be needed. Instead you can use the underlying function that does not require the `next` callback.
|
|
59
|
-
|
|
60
|
-
**Example for Google Cloud Functions**
|
|
61
|
-
|
|
62
|
-
```js
|
|
63
|
-
const {
|
|
64
|
-
createSessionAuthVerifier,
|
|
65
|
-
CLOUD_IDENTIFIERS,
|
|
66
|
-
} = require('@commercetools-backend/express');
|
|
67
|
-
|
|
68
|
-
const sessionAuthVerifier = createSessionAuthVerifier({
|
|
69
|
-
audience: 'https://my-api-server.com',
|
|
70
|
-
issuer: CLOUD_IDENTIFIERS.GCP_EU,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
exports.handler = async function (request, response) {
|
|
74
|
-
try {
|
|
75
|
-
await sessionAuthVerifier(request, response);
|
|
76
|
-
} catch (error) {
|
|
77
|
-
response.status(401).send(JSON.stringify({ message: 'Unauthorized' }));
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// `request.session` contains the useful information
|
|
82
|
-
};
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
> The same concept applies for serverless functions in other cloud providers.
|
|
17
|
+
Check out the [documentation](https://docs.commercetools.com/custom-applications/concepts/integrate-with-your-own-api) for more information.
|
|
@@ -18,6 +18,9 @@ var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/ob
|
|
|
18
18
|
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
|
|
19
19
|
var jwksRsa = require('jwks-rsa');
|
|
20
20
|
var expressJwt = require('express-jwt');
|
|
21
|
+
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
|
|
22
|
+
var _findInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find');
|
|
23
|
+
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
21
24
|
var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
|
|
22
25
|
|
|
23
26
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -35,6 +38,8 @@ var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_O
|
|
|
35
38
|
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
|
|
36
39
|
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
|
|
37
40
|
var jwksRsa__default = /*#__PURE__*/_interopDefault(jwksRsa);
|
|
41
|
+
var _findInstanceProperty__default = /*#__PURE__*/_interopDefault(_findInstanceProperty);
|
|
42
|
+
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
38
43
|
var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
|
|
39
44
|
|
|
40
45
|
var CLOUD_IDENTIFIERS = {
|
|
@@ -56,12 +61,34 @@ var MC_API_PROXY_HEADERS = {
|
|
|
56
61
|
CLOUD_IDENTIFIER: 'x-mc-api-cloud-identifier'
|
|
57
62
|
};
|
|
58
63
|
|
|
59
|
-
var
|
|
60
|
-
|
|
64
|
+
var getHeaderByCaseInsensitiveKey = function getHeaderByCaseInsensitiveKey(headers, headerKey) {
|
|
65
|
+
var _context;
|
|
66
|
+
|
|
67
|
+
var matchingHeader = _findInstanceProperty__default["default"](_context = _Object$entries__default["default"](headers)).call(_context, function (_ref) {
|
|
68
|
+
var _ref2 = _slicedToArray(_ref, 1),
|
|
69
|
+
key = _ref2[0];
|
|
70
|
+
|
|
71
|
+
return headerKey.toLowerCase() === key.toLowerCase();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (matchingHeader && matchingHeader.length > 0) {
|
|
75
|
+
var _matchingHeader = _slicedToArray(matchingHeader, 2),
|
|
76
|
+
headerValue = _matchingHeader[1];
|
|
77
|
+
|
|
78
|
+
return _Array$isArray__default["default"](headerValue) ? headerValue[0] : headerValue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
var getFirstHeaderValueOrThrow = function getFirstHeaderValueOrThrow(headers, headerKey, errorMessage) {
|
|
85
|
+
var headerValue = getHeaderByCaseInsensitiveKey(headers, headerKey);
|
|
86
|
+
|
|
87
|
+
if (!headerValue) {
|
|
61
88
|
throw new Error(errorMessage);
|
|
62
89
|
}
|
|
63
90
|
|
|
64
|
-
return
|
|
91
|
+
return headerValue;
|
|
65
92
|
};
|
|
66
93
|
|
|
67
94
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys__default["default"](object); if (_Object$getOwnPropertySymbols__default["default"]) { var symbols = _Object$getOwnPropertySymbols__default["default"](object); enumerableOnly && (symbols = _filterInstanceProperty__default["default"](symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor__default["default"](object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -162,16 +189,26 @@ var getConfiguredDefaultIssuer = function getConfiguredDefaultIssuer(options) {
|
|
|
162
189
|
|
|
163
190
|
|
|
164
191
|
var getConfiguredAudience = function getConfiguredAudience(options, requestPath) {
|
|
165
|
-
var _context
|
|
192
|
+
var _context;
|
|
166
193
|
|
|
167
194
|
// remove the trailing slash
|
|
168
195
|
var url = new _URL__default["default"](_concatInstanceProperty__default["default"](_context = "".concat(options.audience.replace(/\/?$/, ''))).call(_context, requestPath));
|
|
169
196
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
switch (options.audiencePolicy) {
|
|
198
|
+
case 'forward-url-origin':
|
|
199
|
+
return url.origin;
|
|
200
|
+
|
|
201
|
+
default:
|
|
202
|
+
{
|
|
203
|
+
var _context2;
|
|
173
204
|
|
|
174
|
-
|
|
205
|
+
if (requestPath === '/') {
|
|
206
|
+
return url.origin;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return _concatInstanceProperty__default["default"](_context2 = "".concat(url.origin)).call(_context2, url.pathname);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
175
212
|
};
|
|
176
213
|
|
|
177
214
|
function createSessionAuthVerifier(options) {
|
|
@@ -189,11 +226,11 @@ function createSessionAuthVerifier(options) {
|
|
|
189
226
|
switch (_context3.prev = _context3.next) {
|
|
190
227
|
case 0:
|
|
191
228
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
192
|
-
cloudIdentifierHeader =
|
|
229
|
+
cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, "Missing \"X-MC-API-Cloud-Identifier\" header.");
|
|
193
230
|
issuer = options.inferIssuer && cloudIdentifierHeader ? (_mapCloudIdentifierTo = mapCloudIdentifierToIssuer(cloudIdentifierHeader)) !== null && _mapCloudIdentifierTo !== void 0 ? _mapCloudIdentifierTo : configuredDefaultIssuer : configuredDefaultIssuer; // Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
194
231
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
195
232
|
|
|
196
|
-
proxyForwardVersion =
|
|
233
|
+
proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, "Missing \"X-MC-API-Forward-To-Version\" header.");
|
|
197
234
|
|
|
198
235
|
if (proxyForwardVersion === 'v1') {
|
|
199
236
|
// Fall back to legacy issuer domains
|
|
@@ -18,6 +18,9 @@ var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/ob
|
|
|
18
18
|
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
|
|
19
19
|
var jwksRsa = require('jwks-rsa');
|
|
20
20
|
var expressJwt = require('express-jwt');
|
|
21
|
+
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
|
|
22
|
+
var _findInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find');
|
|
23
|
+
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
21
24
|
var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
|
|
22
25
|
|
|
23
26
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -35,6 +38,8 @@ var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_O
|
|
|
35
38
|
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
|
|
36
39
|
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
|
|
37
40
|
var jwksRsa__default = /*#__PURE__*/_interopDefault(jwksRsa);
|
|
41
|
+
var _findInstanceProperty__default = /*#__PURE__*/_interopDefault(_findInstanceProperty);
|
|
42
|
+
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
|
|
38
43
|
var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
|
|
39
44
|
|
|
40
45
|
var CLOUD_IDENTIFIERS = {
|
|
@@ -56,12 +61,34 @@ var MC_API_PROXY_HEADERS = {
|
|
|
56
61
|
CLOUD_IDENTIFIER: 'x-mc-api-cloud-identifier'
|
|
57
62
|
};
|
|
58
63
|
|
|
59
|
-
var
|
|
60
|
-
|
|
64
|
+
var getHeaderByCaseInsensitiveKey = function getHeaderByCaseInsensitiveKey(headers, headerKey) {
|
|
65
|
+
var _context;
|
|
66
|
+
|
|
67
|
+
var matchingHeader = _findInstanceProperty__default["default"](_context = _Object$entries__default["default"](headers)).call(_context, function (_ref) {
|
|
68
|
+
var _ref2 = _slicedToArray(_ref, 1),
|
|
69
|
+
key = _ref2[0];
|
|
70
|
+
|
|
71
|
+
return headerKey.toLowerCase() === key.toLowerCase();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (matchingHeader && matchingHeader.length > 0) {
|
|
75
|
+
var _matchingHeader = _slicedToArray(matchingHeader, 2),
|
|
76
|
+
headerValue = _matchingHeader[1];
|
|
77
|
+
|
|
78
|
+
return _Array$isArray__default["default"](headerValue) ? headerValue[0] : headerValue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
var getFirstHeaderValueOrThrow = function getFirstHeaderValueOrThrow(headers, headerKey, errorMessage) {
|
|
85
|
+
var headerValue = getHeaderByCaseInsensitiveKey(headers, headerKey);
|
|
86
|
+
|
|
87
|
+
if (!headerValue) {
|
|
61
88
|
throw new Error(errorMessage);
|
|
62
89
|
}
|
|
63
90
|
|
|
64
|
-
return
|
|
91
|
+
return headerValue;
|
|
65
92
|
};
|
|
66
93
|
|
|
67
94
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys__default["default"](object); if (_Object$getOwnPropertySymbols__default["default"]) { var symbols = _Object$getOwnPropertySymbols__default["default"](object); enumerableOnly && (symbols = _filterInstanceProperty__default["default"](symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor__default["default"](object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -162,16 +189,26 @@ var getConfiguredDefaultIssuer = function getConfiguredDefaultIssuer(options) {
|
|
|
162
189
|
|
|
163
190
|
|
|
164
191
|
var getConfiguredAudience = function getConfiguredAudience(options, requestPath) {
|
|
165
|
-
var _context
|
|
192
|
+
var _context;
|
|
166
193
|
|
|
167
194
|
// remove the trailing slash
|
|
168
195
|
var url = new _URL__default["default"](_concatInstanceProperty__default["default"](_context = "".concat(options.audience.replace(/\/?$/, ''))).call(_context, requestPath));
|
|
169
196
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
switch (options.audiencePolicy) {
|
|
198
|
+
case 'forward-url-origin':
|
|
199
|
+
return url.origin;
|
|
200
|
+
|
|
201
|
+
default:
|
|
202
|
+
{
|
|
203
|
+
var _context2;
|
|
173
204
|
|
|
174
|
-
|
|
205
|
+
if (requestPath === '/') {
|
|
206
|
+
return url.origin;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return _concatInstanceProperty__default["default"](_context2 = "".concat(url.origin)).call(_context2, url.pathname);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
175
212
|
};
|
|
176
213
|
|
|
177
214
|
function createSessionAuthVerifier(options) {
|
|
@@ -189,11 +226,11 @@ function createSessionAuthVerifier(options) {
|
|
|
189
226
|
switch (_context3.prev = _context3.next) {
|
|
190
227
|
case 0:
|
|
191
228
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
192
|
-
cloudIdentifierHeader =
|
|
229
|
+
cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, "Missing \"X-MC-API-Cloud-Identifier\" header.");
|
|
193
230
|
issuer = options.inferIssuer && cloudIdentifierHeader ? (_mapCloudIdentifierTo = mapCloudIdentifierToIssuer(cloudIdentifierHeader)) !== null && _mapCloudIdentifierTo !== void 0 ? _mapCloudIdentifierTo : configuredDefaultIssuer : configuredDefaultIssuer; // Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
194
231
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
195
232
|
|
|
196
|
-
proxyForwardVersion =
|
|
233
|
+
proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, "Missing \"X-MC-API-Forward-To-Version\" header.");
|
|
197
234
|
|
|
198
235
|
if (proxyForwardVersion === 'v1') {
|
|
199
236
|
// Fall back to legacy issuer domains
|
|
@@ -14,6 +14,9 @@ import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/obje
|
|
|
14
14
|
import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
|
|
15
15
|
import jwksRsa from 'jwks-rsa';
|
|
16
16
|
import { expressjwt } from 'express-jwt';
|
|
17
|
+
import _slicedToArray from '@babel/runtime-corejs3/helpers/esm/slicedToArray';
|
|
18
|
+
import _findInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/find';
|
|
19
|
+
import _Object$entries from '@babel/runtime-corejs3/core-js-stable/object/entries';
|
|
17
20
|
import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
|
|
18
21
|
|
|
19
22
|
var CLOUD_IDENTIFIERS = {
|
|
@@ -35,12 +38,34 @@ var MC_API_PROXY_HEADERS = {
|
|
|
35
38
|
CLOUD_IDENTIFIER: 'x-mc-api-cloud-identifier'
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
var
|
|
39
|
-
|
|
41
|
+
var getHeaderByCaseInsensitiveKey = function getHeaderByCaseInsensitiveKey(headers, headerKey) {
|
|
42
|
+
var _context;
|
|
43
|
+
|
|
44
|
+
var matchingHeader = _findInstanceProperty(_context = _Object$entries(headers)).call(_context, function (_ref) {
|
|
45
|
+
var _ref2 = _slicedToArray(_ref, 1),
|
|
46
|
+
key = _ref2[0];
|
|
47
|
+
|
|
48
|
+
return headerKey.toLowerCase() === key.toLowerCase();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (matchingHeader && matchingHeader.length > 0) {
|
|
52
|
+
var _matchingHeader = _slicedToArray(matchingHeader, 2),
|
|
53
|
+
headerValue = _matchingHeader[1];
|
|
54
|
+
|
|
55
|
+
return _Array$isArray(headerValue) ? headerValue[0] : headerValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var getFirstHeaderValueOrThrow = function getFirstHeaderValueOrThrow(headers, headerKey, errorMessage) {
|
|
62
|
+
var headerValue = getHeaderByCaseInsensitiveKey(headers, headerKey);
|
|
63
|
+
|
|
64
|
+
if (!headerValue) {
|
|
40
65
|
throw new Error(errorMessage);
|
|
41
66
|
}
|
|
42
67
|
|
|
43
|
-
return
|
|
68
|
+
return headerValue;
|
|
44
69
|
};
|
|
45
70
|
|
|
46
71
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -141,16 +166,26 @@ var getConfiguredDefaultIssuer = function getConfiguredDefaultIssuer(options) {
|
|
|
141
166
|
|
|
142
167
|
|
|
143
168
|
var getConfiguredAudience = function getConfiguredAudience(options, requestPath) {
|
|
144
|
-
var _context
|
|
169
|
+
var _context;
|
|
145
170
|
|
|
146
171
|
// remove the trailing slash
|
|
147
172
|
var url = new _URL(_concatInstanceProperty(_context = "".concat(options.audience.replace(/\/?$/, ''))).call(_context, requestPath));
|
|
148
173
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
174
|
+
switch (options.audiencePolicy) {
|
|
175
|
+
case 'forward-url-origin':
|
|
176
|
+
return url.origin;
|
|
177
|
+
|
|
178
|
+
default:
|
|
179
|
+
{
|
|
180
|
+
var _context2;
|
|
152
181
|
|
|
153
|
-
|
|
182
|
+
if (requestPath === '/') {
|
|
183
|
+
return url.origin;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return _concatInstanceProperty(_context2 = "".concat(url.origin)).call(_context2, url.pathname);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
154
189
|
};
|
|
155
190
|
|
|
156
191
|
function createSessionAuthVerifier(options) {
|
|
@@ -168,11 +203,11 @@ function createSessionAuthVerifier(options) {
|
|
|
168
203
|
switch (_context3.prev = _context3.next) {
|
|
169
204
|
case 0:
|
|
170
205
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
171
|
-
cloudIdentifierHeader =
|
|
206
|
+
cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, "Missing \"X-MC-API-Cloud-Identifier\" header.");
|
|
172
207
|
issuer = options.inferIssuer && cloudIdentifierHeader ? (_mapCloudIdentifierTo = mapCloudIdentifierToIssuer(cloudIdentifierHeader)) !== null && _mapCloudIdentifierTo !== void 0 ? _mapCloudIdentifierTo : configuredDefaultIssuer : configuredDefaultIssuer; // Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
173
208
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
174
209
|
|
|
175
|
-
proxyForwardVersion =
|
|
210
|
+
proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, "Missing \"X-MC-API-Forward-To-Version\" header.");
|
|
176
211
|
|
|
177
212
|
if (proxyForwardVersion === 'v1') {
|
|
178
213
|
// Fall back to legacy issuer domains
|
|
@@ -3,16 +3,46 @@ import { CLOUD_IDENTIFIERS } from './constants';
|
|
|
3
3
|
export declare type TAudience = string;
|
|
4
4
|
export declare type TIssuer = string;
|
|
5
5
|
export declare type TCloudIdentifier = typeof CLOUD_IDENTIFIERS[keyof typeof CLOUD_IDENTIFIERS];
|
|
6
|
+
export declare type TAudiencePolicy = 'forward-url-full-path' | 'forward-url-origin';
|
|
6
7
|
export interface TBaseRequest {
|
|
7
8
|
headers: Record<string, string | string[] | undefined>;
|
|
8
9
|
url?: string;
|
|
9
10
|
originalUrl?: string;
|
|
10
11
|
}
|
|
11
12
|
export declare type TSessionMiddlewareOptions<Request extends TBaseRequest> = {
|
|
13
|
+
/**
|
|
14
|
+
* The public-facing URL used to connect to the server / serverless function.
|
|
15
|
+
* The value should only contain the origin URL (protocol, hostname, port),
|
|
16
|
+
* the request path is inferred from the incoming request.
|
|
17
|
+
*/
|
|
12
18
|
audience: TAudience;
|
|
19
|
+
/**
|
|
20
|
+
* How the audience value should be exchanged between the server and the client.
|
|
21
|
+
* By default it uses the full URL (origin + pathname).
|
|
22
|
+
*/
|
|
23
|
+
audiencePolicy?: TAudiencePolicy;
|
|
24
|
+
/**
|
|
25
|
+
* The cloud identifier (see `CLOUD_IDENTIFIERS`) that maps to the MC API URL
|
|
26
|
+
* of the related cloud region or the MC API URL.
|
|
27
|
+
*/
|
|
13
28
|
issuer: TCloudIdentifier | TIssuer;
|
|
29
|
+
/**
|
|
30
|
+
* Determines whether the issuer should be inferred from the custom request
|
|
31
|
+
* HTTP header `x-mc-api-cloud-identifier` which is sent by the MC API when
|
|
32
|
+
* forwarding the request.
|
|
33
|
+
* This might be useful in case the server is used in multiple regions.
|
|
34
|
+
*/
|
|
14
35
|
inferIssuer?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Options for the `jwksRsa.expressJwtSecret`
|
|
38
|
+
*/
|
|
15
39
|
jwks?: Omit<ExpressJwtOptions, 'jwksUri'>;
|
|
40
|
+
/**
|
|
41
|
+
* By default we assume that the `request` is a Node.js-like object having either
|
|
42
|
+
* an `originalUrl` or `url` properties.
|
|
43
|
+
* If that's not the case (for example in AWS Lambda functions) you need to correctly
|
|
44
|
+
* map the URL (URI path + query string) of the `request`.
|
|
45
|
+
*/
|
|
16
46
|
getRequestUrl?: (request: Request) => string;
|
|
17
47
|
};
|
|
18
48
|
export declare type TSession = {
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
|
|
1
|
+
declare const getHeaderByCaseInsensitiveKey: (headers: Record<string, string | string[] | undefined>, headerKey: string) => string | undefined;
|
|
2
|
+
declare const getFirstHeaderValueOrThrow: (headers: Record<string, string | string[] | undefined>, headerKey: string, errorMessage: string) => string;
|
|
3
|
+
export { getHeaderByCaseInsensitiveKey, getFirstHeaderValueOrThrow };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-backend/express",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.8.0",
|
|
4
4
|
"description": "Zero-config HTTP server as Express.js to facilitate development",
|
|
5
5
|
"bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
|
|
6
6
|
"repository": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"jwks-rsa": "2.1.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
+
"@tsconfig/node16": "^1.0.2",
|
|
29
30
|
"@types/express-unless": "^0.5.3",
|
|
30
31
|
"@types/jsonwebtoken": "^8.5.8",
|
|
31
32
|
"jose": "2.0.5",
|