@commercetools-backend/express 22.30.3 → 22.32.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.
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
|
|
6
6
|
var _URL = require('@babel/runtime-corejs3/core-js-stable/url');
|
|
7
|
-
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
8
7
|
var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/starts-with');
|
|
9
8
|
var _Promise = require('@babel/runtime-corejs3/core-js-stable/promise');
|
|
10
9
|
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
@@ -25,7 +24,6 @@ var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-arr
|
|
|
25
24
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
26
25
|
|
|
27
26
|
var _URL__default = /*#__PURE__*/_interopDefault(_URL);
|
|
28
|
-
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
29
27
|
var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefault(_startsWithInstanceProperty);
|
|
30
28
|
var _Promise__default = /*#__PURE__*/_interopDefault(_Promise);
|
|
31
29
|
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
@@ -87,20 +85,20 @@ const getFirstHeaderValueOrThrow = (headers, headerKey, errorMessage) => {
|
|
|
87
85
|
};
|
|
88
86
|
|
|
89
87
|
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
90
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
88
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
91
89
|
const decodedTokenKey = 'decoded_token';
|
|
92
90
|
// Assign a session object to the request object.
|
|
93
91
|
const writeSessionContext = request => {
|
|
94
92
|
const decodedToken = request[decodedTokenKey];
|
|
95
93
|
if (decodedToken) {
|
|
96
|
-
const publicClaimForProjectKey =
|
|
97
|
-
const publicClaimForUserPermissionsKey =
|
|
94
|
+
const publicClaimForProjectKey = `${decodedToken.iss}/claims/project_key`;
|
|
95
|
+
const publicClaimForUserPermissionsKey = `${decodedToken.iss}/claims/user_permissions`;
|
|
98
96
|
request.session = {
|
|
99
97
|
userId: decodedToken.sub,
|
|
100
98
|
projectKey: decodedToken[publicClaimForProjectKey]
|
|
101
99
|
};
|
|
102
100
|
const userPermissions = decodedToken[publicClaimForUserPermissionsKey];
|
|
103
|
-
if (Boolean(userPermissions
|
|
101
|
+
if (Boolean(userPermissions?.length)) {
|
|
104
102
|
request.session.userPermissions = userPermissions;
|
|
105
103
|
}
|
|
106
104
|
}
|
|
@@ -150,16 +148,16 @@ const throwIfIssuerIsNotAValidUrl = issuer => {
|
|
|
150
148
|
try {
|
|
151
149
|
new _URL__default["default"](issuer);
|
|
152
150
|
} catch (error) {
|
|
153
|
-
throw new Error(
|
|
151
|
+
throw new Error(`Invalid issuer URL "${issuer}". Expected a valid URL to the Merchant Center API Gateway, or a cloud identifier to one of the available cloud regions. See https://docs.commercetools.com/merchant-center-customizations/concepts/merchant-center-api#hostnames.`);
|
|
154
152
|
}
|
|
155
153
|
};
|
|
156
154
|
// Validates required option values.
|
|
157
155
|
const validateRequiredValues = options => {
|
|
158
156
|
if (!options.audience) {
|
|
159
|
-
throw new Error(
|
|
157
|
+
throw new Error(`Missing required option "audience"`);
|
|
160
158
|
}
|
|
161
159
|
if (!options.issuer) {
|
|
162
|
-
throw new Error(
|
|
160
|
+
throw new Error(`Missing required option "issuer"`);
|
|
163
161
|
}
|
|
164
162
|
};
|
|
165
163
|
// Attempt to parse the given issuer. If the value is a cloud identifier, it will
|
|
@@ -177,19 +175,17 @@ const getConfiguredDefaultIssuer = options => {
|
|
|
177
175
|
// If the request path is `/`, do not append it to the audience, otherwise
|
|
178
176
|
// the token validation might fail because of mismatching audiences.
|
|
179
177
|
const getConfiguredAudience = (options, requestPath) => {
|
|
180
|
-
var _context;
|
|
181
178
|
// remove the trailing slash
|
|
182
|
-
const url = new _URL__default["default"](
|
|
179
|
+
const url = new _URL__default["default"](`${options.audience.replace(/\/?$/, '')}${requestPath}`);
|
|
183
180
|
switch (options.audiencePolicy) {
|
|
184
181
|
case 'forward-url-origin':
|
|
185
182
|
return url.origin;
|
|
186
183
|
default:
|
|
187
184
|
{
|
|
188
|
-
var _context2;
|
|
189
185
|
if (requestPath === '/') {
|
|
190
186
|
return url.origin;
|
|
191
187
|
}
|
|
192
|
-
return
|
|
188
|
+
return `${url.origin}${url.pathname}`;
|
|
193
189
|
}
|
|
194
190
|
}
|
|
195
191
|
};
|
|
@@ -199,22 +195,20 @@ function createSessionAuthVerifier(options) {
|
|
|
199
195
|
|
|
200
196
|
// Returns an async HTTP handler.
|
|
201
197
|
return async (request, response) => {
|
|
202
|
-
var _mapCloudIdentifierTo, _request$originalUrl;
|
|
203
198
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
204
|
-
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER,
|
|
205
|
-
let issuer = options.inferIssuer && cloudIdentifierHeader ?
|
|
199
|
+
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, `Missing "X-MC-API-Cloud-Identifier" header.`);
|
|
200
|
+
let issuer = options.inferIssuer && cloudIdentifierHeader ? mapCloudIdentifierToIssuer(cloudIdentifierHeader) ?? configuredDefaultIssuer : configuredDefaultIssuer;
|
|
206
201
|
|
|
207
202
|
// Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
208
203
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
209
|
-
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION,
|
|
204
|
+
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, `Missing "X-MC-API-Forward-To-Version" header.`);
|
|
210
205
|
if (proxyForwardVersion === 'v1') {
|
|
211
|
-
var _mapToLegacyIssuer;
|
|
212
206
|
// Fall back to legacy issuer domains
|
|
213
|
-
issuer =
|
|
207
|
+
issuer = mapToLegacyIssuer(cloudIdentifierHeader) ?? issuer;
|
|
214
208
|
}
|
|
215
|
-
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) :
|
|
209
|
+
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) : request.originalUrl ?? request.url;
|
|
216
210
|
if (!requestUrlPath || !_startsWithInstanceProperty__default["default"](requestUrlPath).call(requestUrlPath, '/')) {
|
|
217
|
-
throw new Error(
|
|
211
|
+
throw new Error(`Invalid request URI path "${requestUrlPath}". Please make sure that the "request" object has either a property "originalUrl" or "url". If not, you should implement the "getRequestUrl" function and make sure to return a valid URI path value starting with "/". More info at https://docs.commercetools.com/merchant-center-customizations/concepts/integrate-with-your-own-api#validating-the-json-web-token`);
|
|
218
212
|
}
|
|
219
213
|
const audience = getConfiguredAudience(options, requestUrlPath);
|
|
220
214
|
return new _Promise__default["default"]((resolve, reject) => {
|
|
@@ -228,7 +222,7 @@ function createSessionAuthVerifier(options) {
|
|
|
228
222
|
jwksRequestsPerMinute: 5
|
|
229
223
|
}, options.jwks || {}), {}, {
|
|
230
224
|
// This should be set by the middleware, no matter what.
|
|
231
|
-
jwksUri:
|
|
225
|
+
jwksUri: `${issuer}/.well-known/jwks.json`
|
|
232
226
|
})),
|
|
233
227
|
requestProperty: decodedTokenKey,
|
|
234
228
|
// Validate the audience and the issuer.
|
|
@@ -236,7 +230,7 @@ function createSessionAuthVerifier(options) {
|
|
|
236
230
|
issuer,
|
|
237
231
|
algorithms: ['RS256']
|
|
238
232
|
// @ts-ignore: the middleware expects an Express.js Request/Response objects
|
|
239
|
-
})(request, response
|
|
233
|
+
})(request, response ?? {}, error => {
|
|
240
234
|
if (error) {
|
|
241
235
|
reject(error);
|
|
242
236
|
} else {
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
|
|
6
6
|
var _URL = require('@babel/runtime-corejs3/core-js-stable/url');
|
|
7
|
-
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
8
7
|
var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/starts-with');
|
|
9
8
|
var _Promise = require('@babel/runtime-corejs3/core-js-stable/promise');
|
|
10
9
|
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
@@ -25,7 +24,6 @@ var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-arr
|
|
|
25
24
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
26
25
|
|
|
27
26
|
var _URL__default = /*#__PURE__*/_interopDefault(_URL);
|
|
28
|
-
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
29
27
|
var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefault(_startsWithInstanceProperty);
|
|
30
28
|
var _Promise__default = /*#__PURE__*/_interopDefault(_Promise);
|
|
31
29
|
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
@@ -87,20 +85,20 @@ const getFirstHeaderValueOrThrow = (headers, headerKey, errorMessage) => {
|
|
|
87
85
|
};
|
|
88
86
|
|
|
89
87
|
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
90
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
88
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
91
89
|
const decodedTokenKey = 'decoded_token';
|
|
92
90
|
// Assign a session object to the request object.
|
|
93
91
|
const writeSessionContext = request => {
|
|
94
92
|
const decodedToken = request[decodedTokenKey];
|
|
95
93
|
if (decodedToken) {
|
|
96
|
-
const publicClaimForProjectKey =
|
|
97
|
-
const publicClaimForUserPermissionsKey =
|
|
94
|
+
const publicClaimForProjectKey = `${decodedToken.iss}/claims/project_key`;
|
|
95
|
+
const publicClaimForUserPermissionsKey = `${decodedToken.iss}/claims/user_permissions`;
|
|
98
96
|
request.session = {
|
|
99
97
|
userId: decodedToken.sub,
|
|
100
98
|
projectKey: decodedToken[publicClaimForProjectKey]
|
|
101
99
|
};
|
|
102
100
|
const userPermissions = decodedToken[publicClaimForUserPermissionsKey];
|
|
103
|
-
if (Boolean(userPermissions
|
|
101
|
+
if (Boolean(userPermissions?.length)) {
|
|
104
102
|
request.session.userPermissions = userPermissions;
|
|
105
103
|
}
|
|
106
104
|
}
|
|
@@ -150,16 +148,16 @@ const throwIfIssuerIsNotAValidUrl = issuer => {
|
|
|
150
148
|
try {
|
|
151
149
|
new _URL__default["default"](issuer);
|
|
152
150
|
} catch (error) {
|
|
153
|
-
throw new Error(
|
|
151
|
+
throw new Error(`Invalid issuer URL "${issuer}". Expected a valid URL to the Merchant Center API Gateway, or a cloud identifier to one of the available cloud regions. See https://docs.commercetools.com/merchant-center-customizations/concepts/merchant-center-api#hostnames.`);
|
|
154
152
|
}
|
|
155
153
|
};
|
|
156
154
|
// Validates required option values.
|
|
157
155
|
const validateRequiredValues = options => {
|
|
158
156
|
if (!options.audience) {
|
|
159
|
-
throw new Error(
|
|
157
|
+
throw new Error(`Missing required option "audience"`);
|
|
160
158
|
}
|
|
161
159
|
if (!options.issuer) {
|
|
162
|
-
throw new Error(
|
|
160
|
+
throw new Error(`Missing required option "issuer"`);
|
|
163
161
|
}
|
|
164
162
|
};
|
|
165
163
|
// Attempt to parse the given issuer. If the value is a cloud identifier, it will
|
|
@@ -177,19 +175,17 @@ const getConfiguredDefaultIssuer = options => {
|
|
|
177
175
|
// If the request path is `/`, do not append it to the audience, otherwise
|
|
178
176
|
// the token validation might fail because of mismatching audiences.
|
|
179
177
|
const getConfiguredAudience = (options, requestPath) => {
|
|
180
|
-
var _context;
|
|
181
178
|
// remove the trailing slash
|
|
182
|
-
const url = new _URL__default["default"](
|
|
179
|
+
const url = new _URL__default["default"](`${options.audience.replace(/\/?$/, '')}${requestPath}`);
|
|
183
180
|
switch (options.audiencePolicy) {
|
|
184
181
|
case 'forward-url-origin':
|
|
185
182
|
return url.origin;
|
|
186
183
|
default:
|
|
187
184
|
{
|
|
188
|
-
var _context2;
|
|
189
185
|
if (requestPath === '/') {
|
|
190
186
|
return url.origin;
|
|
191
187
|
}
|
|
192
|
-
return
|
|
188
|
+
return `${url.origin}${url.pathname}`;
|
|
193
189
|
}
|
|
194
190
|
}
|
|
195
191
|
};
|
|
@@ -199,22 +195,20 @@ function createSessionAuthVerifier(options) {
|
|
|
199
195
|
|
|
200
196
|
// Returns an async HTTP handler.
|
|
201
197
|
return async (request, response) => {
|
|
202
|
-
var _mapCloudIdentifierTo, _request$originalUrl;
|
|
203
198
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
204
|
-
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER,
|
|
205
|
-
let issuer = options.inferIssuer && cloudIdentifierHeader ?
|
|
199
|
+
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, `Missing "X-MC-API-Cloud-Identifier" header.`);
|
|
200
|
+
let issuer = options.inferIssuer && cloudIdentifierHeader ? mapCloudIdentifierToIssuer(cloudIdentifierHeader) ?? configuredDefaultIssuer : configuredDefaultIssuer;
|
|
206
201
|
|
|
207
202
|
// Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
208
203
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
209
|
-
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION,
|
|
204
|
+
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, `Missing "X-MC-API-Forward-To-Version" header.`);
|
|
210
205
|
if (proxyForwardVersion === 'v1') {
|
|
211
|
-
var _mapToLegacyIssuer;
|
|
212
206
|
// Fall back to legacy issuer domains
|
|
213
|
-
issuer =
|
|
207
|
+
issuer = mapToLegacyIssuer(cloudIdentifierHeader) ?? issuer;
|
|
214
208
|
}
|
|
215
|
-
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) :
|
|
209
|
+
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) : request.originalUrl ?? request.url;
|
|
216
210
|
if (!requestUrlPath || !_startsWithInstanceProperty__default["default"](requestUrlPath).call(requestUrlPath, '/')) {
|
|
217
|
-
throw new Error(
|
|
211
|
+
throw new Error(`Invalid request URI path "${requestUrlPath}". Please make sure that the "request" object has either a property "originalUrl" or "url". If not, you should implement the "getRequestUrl" function and make sure to return a valid URI path value starting with "/". More info at https://docs.commercetools.com/merchant-center-customizations/concepts/integrate-with-your-own-api#validating-the-json-web-token`);
|
|
218
212
|
}
|
|
219
213
|
const audience = getConfiguredAudience(options, requestUrlPath);
|
|
220
214
|
return new _Promise__default["default"]((resolve, reject) => {
|
|
@@ -228,7 +222,7 @@ function createSessionAuthVerifier(options) {
|
|
|
228
222
|
jwksRequestsPerMinute: 5
|
|
229
223
|
}, options.jwks || {}), {}, {
|
|
230
224
|
// This should be set by the middleware, no matter what.
|
|
231
|
-
jwksUri:
|
|
225
|
+
jwksUri: `${issuer}/.well-known/jwks.json`
|
|
232
226
|
})),
|
|
233
227
|
requestProperty: decodedTokenKey,
|
|
234
228
|
// Validate the audience and the issuer.
|
|
@@ -236,7 +230,7 @@ function createSessionAuthVerifier(options) {
|
|
|
236
230
|
issuer,
|
|
237
231
|
algorithms: ['RS256']
|
|
238
232
|
// @ts-ignore: the middleware expects an Express.js Request/Response objects
|
|
239
|
-
})(request, response
|
|
233
|
+
})(request, response ?? {}, error => {
|
|
240
234
|
if (error) {
|
|
241
235
|
reject(error);
|
|
242
236
|
} else {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty';
|
|
2
2
|
import _URL from '@babel/runtime-corejs3/core-js-stable/url';
|
|
3
|
-
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
|
|
4
3
|
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
|
5
4
|
import _Promise from '@babel/runtime-corejs3/core-js-stable/promise';
|
|
6
5
|
import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
|
|
@@ -64,20 +63,20 @@ const getFirstHeaderValueOrThrow = (headers, headerKey, errorMessage) => {
|
|
|
64
63
|
};
|
|
65
64
|
|
|
66
65
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
67
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
66
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
68
67
|
const decodedTokenKey = 'decoded_token';
|
|
69
68
|
// Assign a session object to the request object.
|
|
70
69
|
const writeSessionContext = request => {
|
|
71
70
|
const decodedToken = request[decodedTokenKey];
|
|
72
71
|
if (decodedToken) {
|
|
73
|
-
const publicClaimForProjectKey =
|
|
74
|
-
const publicClaimForUserPermissionsKey =
|
|
72
|
+
const publicClaimForProjectKey = `${decodedToken.iss}/claims/project_key`;
|
|
73
|
+
const publicClaimForUserPermissionsKey = `${decodedToken.iss}/claims/user_permissions`;
|
|
75
74
|
request.session = {
|
|
76
75
|
userId: decodedToken.sub,
|
|
77
76
|
projectKey: decodedToken[publicClaimForProjectKey]
|
|
78
77
|
};
|
|
79
78
|
const userPermissions = decodedToken[publicClaimForUserPermissionsKey];
|
|
80
|
-
if (Boolean(userPermissions
|
|
79
|
+
if (Boolean(userPermissions?.length)) {
|
|
81
80
|
request.session.userPermissions = userPermissions;
|
|
82
81
|
}
|
|
83
82
|
}
|
|
@@ -127,16 +126,16 @@ const throwIfIssuerIsNotAValidUrl = issuer => {
|
|
|
127
126
|
try {
|
|
128
127
|
new _URL(issuer);
|
|
129
128
|
} catch (error) {
|
|
130
|
-
throw new Error(
|
|
129
|
+
throw new Error(`Invalid issuer URL "${issuer}". Expected a valid URL to the Merchant Center API Gateway, or a cloud identifier to one of the available cloud regions. See https://docs.commercetools.com/merchant-center-customizations/concepts/merchant-center-api#hostnames.`);
|
|
131
130
|
}
|
|
132
131
|
};
|
|
133
132
|
// Validates required option values.
|
|
134
133
|
const validateRequiredValues = options => {
|
|
135
134
|
if (!options.audience) {
|
|
136
|
-
throw new Error(
|
|
135
|
+
throw new Error(`Missing required option "audience"`);
|
|
137
136
|
}
|
|
138
137
|
if (!options.issuer) {
|
|
139
|
-
throw new Error(
|
|
138
|
+
throw new Error(`Missing required option "issuer"`);
|
|
140
139
|
}
|
|
141
140
|
};
|
|
142
141
|
// Attempt to parse the given issuer. If the value is a cloud identifier, it will
|
|
@@ -154,19 +153,17 @@ const getConfiguredDefaultIssuer = options => {
|
|
|
154
153
|
// If the request path is `/`, do not append it to the audience, otherwise
|
|
155
154
|
// the token validation might fail because of mismatching audiences.
|
|
156
155
|
const getConfiguredAudience = (options, requestPath) => {
|
|
157
|
-
var _context;
|
|
158
156
|
// remove the trailing slash
|
|
159
|
-
const url = new _URL(
|
|
157
|
+
const url = new _URL(`${options.audience.replace(/\/?$/, '')}${requestPath}`);
|
|
160
158
|
switch (options.audiencePolicy) {
|
|
161
159
|
case 'forward-url-origin':
|
|
162
160
|
return url.origin;
|
|
163
161
|
default:
|
|
164
162
|
{
|
|
165
|
-
var _context2;
|
|
166
163
|
if (requestPath === '/') {
|
|
167
164
|
return url.origin;
|
|
168
165
|
}
|
|
169
|
-
return
|
|
166
|
+
return `${url.origin}${url.pathname}`;
|
|
170
167
|
}
|
|
171
168
|
}
|
|
172
169
|
};
|
|
@@ -176,22 +173,20 @@ function createSessionAuthVerifier(options) {
|
|
|
176
173
|
|
|
177
174
|
// Returns an async HTTP handler.
|
|
178
175
|
return async (request, response) => {
|
|
179
|
-
var _mapCloudIdentifierTo, _request$originalUrl;
|
|
180
176
|
// Get the cloud identifier header, forwarded by the `/proxy/forward-to` endpoint.
|
|
181
|
-
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER,
|
|
182
|
-
let issuer = options.inferIssuer && cloudIdentifierHeader ?
|
|
177
|
+
const cloudIdentifierHeader = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.CLOUD_IDENTIFIER, `Missing "X-MC-API-Cloud-Identifier" header.`);
|
|
178
|
+
let issuer = options.inferIssuer && cloudIdentifierHeader ? mapCloudIdentifierToIssuer(cloudIdentifierHeader) ?? configuredDefaultIssuer : configuredDefaultIssuer;
|
|
183
179
|
|
|
184
180
|
// Get the `Accept-version` header, forwarded by the `/proxy/forward-to` endpoint.
|
|
185
181
|
// The version should be sent by the client making the request, to use the features of v2.
|
|
186
|
-
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION,
|
|
182
|
+
const proxyForwardVersion = getFirstHeaderValueOrThrow(request.headers, MC_API_PROXY_HEADERS.FORWARD_TO_VERSION, `Missing "X-MC-API-Forward-To-Version" header.`);
|
|
187
183
|
if (proxyForwardVersion === 'v1') {
|
|
188
|
-
var _mapToLegacyIssuer;
|
|
189
184
|
// Fall back to legacy issuer domains
|
|
190
|
-
issuer =
|
|
185
|
+
issuer = mapToLegacyIssuer(cloudIdentifierHeader) ?? issuer;
|
|
191
186
|
}
|
|
192
|
-
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) :
|
|
187
|
+
const requestUrlPath = options.getRequestUrl ? options.getRequestUrl(request) : request.originalUrl ?? request.url;
|
|
193
188
|
if (!requestUrlPath || !_startsWithInstanceProperty(requestUrlPath).call(requestUrlPath, '/')) {
|
|
194
|
-
throw new Error(
|
|
189
|
+
throw new Error(`Invalid request URI path "${requestUrlPath}". Please make sure that the "request" object has either a property "originalUrl" or "url". If not, you should implement the "getRequestUrl" function and make sure to return a valid URI path value starting with "/". More info at https://docs.commercetools.com/merchant-center-customizations/concepts/integrate-with-your-own-api#validating-the-json-web-token`);
|
|
195
190
|
}
|
|
196
191
|
const audience = getConfiguredAudience(options, requestUrlPath);
|
|
197
192
|
return new _Promise((resolve, reject) => {
|
|
@@ -205,7 +200,7 @@ function createSessionAuthVerifier(options) {
|
|
|
205
200
|
jwksRequestsPerMinute: 5
|
|
206
201
|
}, options.jwks || {}), {}, {
|
|
207
202
|
// This should be set by the middleware, no matter what.
|
|
208
|
-
jwksUri:
|
|
203
|
+
jwksUri: `${issuer}/.well-known/jwks.json`
|
|
209
204
|
})),
|
|
210
205
|
requestProperty: decodedTokenKey,
|
|
211
206
|
// Validate the audience and the issuer.
|
|
@@ -213,7 +208,7 @@ function createSessionAuthVerifier(options) {
|
|
|
213
208
|
issuer,
|
|
214
209
|
algorithms: ['RS256']
|
|
215
210
|
// @ts-ignore: the middleware expects an Express.js Request/Response objects
|
|
216
|
-
})(request, response
|
|
211
|
+
})(request, response ?? {}, error => {
|
|
217
212
|
if (error) {
|
|
218
213
|
reject(error);
|
|
219
214
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-backend/express",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.32.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": {
|