@salesforce/pwa-kit-runtime 3.12.0-preview.0 → 3.12.0-preview.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-runtime",
|
|
3
|
-
"version": "3.12.0-preview.
|
|
3
|
+
"version": "3.12.0-preview.1",
|
|
4
4
|
"description": "The PWAKit Runtime",
|
|
5
5
|
"homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-runtime#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@loadable/component": "^5.15.3",
|
|
49
|
-
"@salesforce/pwa-kit-dev": "3.12.0-preview.
|
|
49
|
+
"@salesforce/pwa-kit-dev": "3.12.0-preview.1",
|
|
50
50
|
"@serverless/event-mocks": "^1.1.1",
|
|
51
51
|
"aws-lambda-mock-context": "^3.2.1",
|
|
52
52
|
"fs-extra": "^11.1.1",
|
|
53
|
-
"internal-lib-build": "3.12.0-preview.
|
|
53
|
+
"internal-lib-build": "3.12.0-preview.1",
|
|
54
54
|
"nock": "^13.3.0",
|
|
55
55
|
"nodemon": "^2.0.22",
|
|
56
56
|
"sinon": "^13.0.2",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"supertest": "^4.0.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@salesforce/pwa-kit-dev": "3.12.0-preview.
|
|
61
|
+
"@salesforce/pwa-kit-dev": "3.12.0-preview.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
64
64
|
"@salesforce/pwa-kit-dev": {
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"directory": "dist"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "0f66d26584f98d3322bffcb70e7feed08c81cc7a"
|
|
76
76
|
}
|
|
@@ -403,78 +403,84 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
403
403
|
* @private
|
|
404
404
|
*/
|
|
405
405
|
_setupRemoveBasePathFromPathMiddleware(app) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
406
|
+
// Use envBasePath as the feature flag for this middleware
|
|
407
|
+
// If envBasePath is `/`, '', or undefined when the server starts, we don't need to
|
|
408
|
+
// initialize this middleware.
|
|
409
|
+
if ((0, _ssrNamespacePaths.getEnvBasePath)()) {
|
|
410
|
+
const removeBasePathFromPath = path => {
|
|
411
|
+
const regex = new RegExp(`^${(0, _ssrNamespacePaths.getEnvBasePath)()}(/|$)`);
|
|
412
|
+
return path.replace(regex, '/');
|
|
413
|
+
};
|
|
414
|
+
const _convertExpressRouteToRegex = routePattern => {
|
|
415
|
+
if (!routePattern) return null;
|
|
416
|
+
if (routePattern instanceof RegExp) return routePattern;
|
|
417
|
+
if (typeof routePattern !== 'string') return null;
|
|
413
418
|
|
|
414
|
-
|
|
415
|
-
|
|
419
|
+
// Replace route parameters like :id with regex capture groups
|
|
420
|
+
let regexPattern = routePattern.replace(/:[^/]+/g, '[^/]+').replace(/\/\*/g, '/.*').replace(/\*/g, '.*');
|
|
416
421
|
|
|
417
|
-
|
|
418
|
-
|
|
422
|
+
// Escape other regex special characters except those we just handled
|
|
423
|
+
regexPattern = regexPattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
419
424
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
425
|
+
// Unescape the patterns we want to keep
|
|
426
|
+
regexPattern = regexPattern.replace(/\\\[\\\^\/\\\]\\\+/g, '[^/]+').replace(/\\\/\\\.\\\*/g, '/.*').replace(/\\\.\\\*/g, '.*').replace(/\\\(/g, '(').replace(/\\\)/g, ')').replace(/\\\?/g, '?');
|
|
427
|
+
return new RegExp(`^${regexPattern}$`);
|
|
428
|
+
};
|
|
424
429
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Very early request processing.
|
|
432
|
+
*
|
|
433
|
+
* If the server receives a request containing the base path, remove it before allowing it through
|
|
434
|
+
*
|
|
435
|
+
* @param req {express.req} the incoming request - modified in-place
|
|
436
|
+
* @private
|
|
437
|
+
*/
|
|
438
|
+
const removeBasePathFromPathMiddleware = (req, res, next) => {
|
|
439
|
+
// Scope base path removal to /mobify routes and routes defined by the express app (ie. worker.js)
|
|
440
|
+
// This is to avoid affecting other paths where a base path might be present if it happens to
|
|
441
|
+
// be equal to a site id.
|
|
442
|
+
// For example, if you have a base path of /us and a site id of /us we don't want
|
|
443
|
+
// to remove the /us from www.example.com/us/en-US/category/...
|
|
444
|
+
|
|
445
|
+
const basePath = (0, _ssrNamespacePaths.getEnvBasePath)();
|
|
446
|
+
let shouldRemoveBasePath = false;
|
|
447
|
+
if (basePath) {
|
|
448
|
+
if (req.path.startsWith(`${basePath}/mobify`)) {
|
|
449
|
+
shouldRemoveBasePath = true;
|
|
450
|
+
}
|
|
446
451
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
452
|
+
// Check if path matches any existing express route with base path prepended
|
|
453
|
+
if (!shouldRemoveBasePath) {
|
|
454
|
+
// Routes are dynamically checked since we want to ensure that any express route
|
|
455
|
+
// defined after the app is created, such as routes defined in ssr.js, are included.
|
|
456
|
+
const expressRoutes = app._router.stack
|
|
457
|
+
// specifically omit the generic wildcard from the express routes we want to
|
|
458
|
+
// remove the base path from since it is mapped to the app render
|
|
459
|
+
.filter(layer => layer.route && layer.route.path && layer.route.path !== '*').map(layer => layer.route.path);
|
|
460
|
+
for (const route of expressRoutes) {
|
|
461
|
+
if (route) {
|
|
462
|
+
const routeRegex = _convertExpressRouteToRegex(route);
|
|
463
|
+
if (routeRegex) {
|
|
464
|
+
const pathWithoutBase = req.path.replace(new RegExp(`^${basePath}`), '');
|
|
465
|
+
if (routeRegex.test(pathWithoutBase)) {
|
|
466
|
+
shouldRemoveBasePath = true;
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
463
469
|
}
|
|
464
470
|
}
|
|
465
471
|
}
|
|
466
472
|
}
|
|
467
473
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
474
|
+
if (shouldRemoveBasePath) {
|
|
475
|
+
const updatedPath = removeBasePathFromPath(req.path);
|
|
476
|
+
const parsed = _url.default.parse(req.url);
|
|
477
|
+
parsed.pathname = updatedPath;
|
|
478
|
+
req.url = _url.default.format(parsed);
|
|
479
|
+
}
|
|
480
|
+
next();
|
|
481
|
+
};
|
|
482
|
+
app.use(removeBasePathFromPathMiddleware);
|
|
483
|
+
}
|
|
478
484
|
},
|
|
479
485
|
/**
|
|
480
486
|
* @private
|
|
@@ -674,6 +680,15 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
674
680
|
if (!options.useSLASPrivateClient) {
|
|
675
681
|
return;
|
|
676
682
|
}
|
|
683
|
+
|
|
684
|
+
// This is the full path to the SLAS trusted-system endpoint
|
|
685
|
+
// We want to throw an error if the regex defined options.applySLASPrivateClientToEndpoints
|
|
686
|
+
// matches this path as an early warning to developers that they should update their regex
|
|
687
|
+
// in ssr.js to exclude this path.
|
|
688
|
+
const trustedSystemPath = '/shopper/auth/v1/oauth2/trusted-system/token';
|
|
689
|
+
if (trustedSystemPath.match(options.applySLASPrivateClientToEndpoints)) {
|
|
690
|
+
throw new Error('It is not allowed to include /oauth2/trusted-system endpoints in `applySLASPrivateClientToEndpoints`');
|
|
691
|
+
}
|
|
677
692
|
(0, _ssrServer.localDevLog)(`Proxying ${_ssrNamespacePaths.slasPrivateProxyPath} to ${options.slasTarget}`);
|
|
678
693
|
const clientId = (_options$mobify2 = options.mobify) === null || _options$mobify2 === void 0 ? void 0 : (_options$mobify2$app = _options$mobify2.app) === null || _options$mobify2$app === void 0 ? void 0 : (_options$mobify2$app$ = _options$mobify2$app.commerceAPI) === null || _options$mobify2$app$ === void 0 ? void 0 : (_options$mobify2$app$2 = _options$mobify2$app$.parameters) === null || _options$mobify2$app$2 === void 0 ? void 0 : _options$mobify2$app$2.clientId;
|
|
679
694
|
const clientSecret = process.env.PWA_KIT_SLAS_CLIENT_SECRET;
|
|
@@ -695,7 +710,7 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
695
710
|
return path.replace(regex, '');
|
|
696
711
|
},
|
|
697
712
|
onProxyReq: (proxyRequest, incomingRequest, res) => {
|
|
698
|
-
var _incomingRequest$path, _incomingRequest$path2, _incomingRequest$path3;
|
|
713
|
+
var _incomingRequest$path, _incomingRequest$path2, _incomingRequest$path3, _incomingRequest$path4;
|
|
699
714
|
(0, _configureProxy.applyProxyRequestHeaders)({
|
|
700
715
|
proxyRequest,
|
|
701
716
|
incomingRequest,
|
|
@@ -704,15 +719,9 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
704
719
|
targetProtocol: 'https'
|
|
705
720
|
});
|
|
706
721
|
|
|
707
|
-
// We
|
|
708
|
-
//
|
|
709
|
-
|
|
710
|
-
// Other SLAS endpoints, ie. SLAS authenticate (/oauth2/login) and
|
|
711
|
-
// SLAS logout (/oauth2/logout), use the Authorization header for a different
|
|
712
|
-
// purpose so we don't want to overwrite the header for those calls.
|
|
713
|
-
if ((_incomingRequest$path = incomingRequest.path) !== null && _incomingRequest$path !== void 0 && _incomingRequest$path.match(options.applySLASPrivateClientToEndpoints)) {
|
|
714
|
-
proxyRequest.setHeader('Authorization', `Basic ${encodedSlasCredentials}`);
|
|
715
|
-
} else if (!((_incomingRequest$path2 = incomingRequest.path) !== null && _incomingRequest$path2 !== void 0 && _incomingRequest$path2.match(options.slasApiPath))) {
|
|
722
|
+
// We don't want the proxy to handle any non-SLAS requests
|
|
723
|
+
// or any trusted system requests
|
|
724
|
+
if (!((_incomingRequest$path = incomingRequest.path) !== null && _incomingRequest$path !== void 0 && _incomingRequest$path.match(options.slasApiPath)) || (_incomingRequest$path2 = incomingRequest.path) !== null && _incomingRequest$path2 !== void 0 && _incomingRequest$path2.match(/\/oauth2\/trusted-system/)) {
|
|
716
725
|
const message = `Request to ${incomingRequest.path} is not allowed through the SLAS Private Client Proxy`;
|
|
717
726
|
_loggerInstance.default.error(message);
|
|
718
727
|
return res.status(403).json({
|
|
@@ -720,8 +729,17 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
720
729
|
});
|
|
721
730
|
}
|
|
722
731
|
|
|
723
|
-
//
|
|
724
|
-
|
|
732
|
+
// We pattern match and add client secrets only to endpoints that
|
|
733
|
+
// match the regex specified by options.applySLASPrivateClientToEndpoints.
|
|
734
|
+
//
|
|
735
|
+
// Other SLAS endpoints, ie. SLAS authenticate (/oauth2/login) and
|
|
736
|
+
// SLAS logout (/oauth2/logout), use the Authorization header for a different
|
|
737
|
+
// purpose so we don't want to overwrite the header for those calls.
|
|
738
|
+
if ((_incomingRequest$path3 = incomingRequest.path) !== null && _incomingRequest$path3 !== void 0 && _incomingRequest$path3.match(options.applySLASPrivateClientToEndpoints)) {
|
|
739
|
+
proxyRequest.setHeader('Authorization', `Basic ${encodedSlasCredentials}`);
|
|
740
|
+
} else if ((_incomingRequest$path4 = incomingRequest.path) !== null && _incomingRequest$path4 !== void 0 && _incomingRequest$path4.match(/\/oauth2\/trusted-agent\/token/)) {
|
|
741
|
+
// /oauth2/trusted-agent/token endpoint auth header comes from Account Manager
|
|
742
|
+
// so the SLAS private client is sent via this special header
|
|
725
743
|
proxyRequest.setHeader('_sfdc_client_auth', encodedSlasCredentials);
|
|
726
744
|
}
|
|
727
745
|
}
|
package/ssr/server/constants.js
CHANGED
|
@@ -14,7 +14,7 @@ const APPLICATION_OCTET_STREAM = exports.APPLICATION_OCTET_STREAM = 'application
|
|
|
14
14
|
const BUILD = exports.BUILD = 'build';
|
|
15
15
|
const STATIC_ASSETS = exports.STATIC_ASSETS = 'static_assets';
|
|
16
16
|
|
|
17
|
-
/** * @deprecated Use ssr-namespace-paths
|
|
17
|
+
/** * @deprecated Use ssr-namespace-paths proxyBasePath instead */
|
|
18
18
|
const PROXY_PATH_PREFIX = exports.PROXY_PATH_PREFIX = '/mobify/proxy';
|
|
19
19
|
|
|
20
20
|
// All these values MUST be lower case
|
|
@@ -918,9 +918,24 @@ describe('DevServer middleware', () => {
|
|
|
918
918
|
describe('SLAS private client proxy', () => {
|
|
919
919
|
const savedEnvironment = _extends({}, process.env);
|
|
920
920
|
let proxyApp;
|
|
921
|
+
let proxyServer;
|
|
921
922
|
const proxyPort = 12345;
|
|
922
923
|
const proxyPath = '/shopper/auth/responseHeaders';
|
|
923
924
|
const slasTarget = `http://localhost:${proxyPort}${proxyPath}`;
|
|
925
|
+
const appConfig = {
|
|
926
|
+
mobify: {
|
|
927
|
+
app: {
|
|
928
|
+
commerceAPI: {
|
|
929
|
+
parameters: {
|
|
930
|
+
clientId: 'clientId',
|
|
931
|
+
shortCode: 'shortCode'
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
useSLASPrivateClient: true,
|
|
937
|
+
slasTarget: slasTarget
|
|
938
|
+
};
|
|
924
939
|
beforeAll(() => {
|
|
925
940
|
jest.spyOn(ssrConfig, 'getConfig').mockReturnValue({});
|
|
926
941
|
// by setting slasTarget, rather than forwarding the request to SLAS,
|
|
@@ -929,14 +944,38 @@ describe('SLAS private client proxy', () => {
|
|
|
929
944
|
proxyApp.use(proxyPath, (req, res) => {
|
|
930
945
|
res.send(req.headers);
|
|
931
946
|
});
|
|
932
|
-
proxyApp.listen(proxyPort);
|
|
947
|
+
proxyServer = proxyApp.listen(proxyPort);
|
|
933
948
|
});
|
|
934
949
|
afterEach(() => {
|
|
935
950
|
process.env = savedEnvironment;
|
|
936
951
|
});
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
952
|
+
|
|
953
|
+
// There is a lot of cleanup done here to ensure the proxy server is closed
|
|
954
|
+
// after these tests.
|
|
955
|
+
afterAll(/*#__PURE__*/_asyncToGenerator(function* () {
|
|
956
|
+
if (proxyServer) {
|
|
957
|
+
// Close the server and wait for it to fully close
|
|
958
|
+
yield new Promise(resolve => {
|
|
959
|
+
proxyServer.close(() => {
|
|
960
|
+
resolve();
|
|
961
|
+
});
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
// Additional cleanup to ensure all connections are closed
|
|
965
|
+
proxyServer.unref();
|
|
966
|
+
|
|
967
|
+
// Force close any remaining connections
|
|
968
|
+
if (proxyServer._handle) {
|
|
969
|
+
proxyServer._handle.close();
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// Clear any remaining event listeners
|
|
973
|
+
proxyServer.removeAllListeners();
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// Clear any remaining timers or intervals
|
|
977
|
+
jest.clearAllTimers();
|
|
978
|
+
}));
|
|
940
979
|
test('should not create proxy by default', () => {
|
|
941
980
|
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts());
|
|
942
981
|
return (0, _supertest.default)(app).get('/mobify/slas/private').expect(404);
|
|
@@ -950,20 +989,7 @@ describe('SLAS private client proxy', () => {
|
|
|
950
989
|
});
|
|
951
990
|
test('does not insert client secret if request not for /oauth2/token', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
952
991
|
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
953
|
-
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(
|
|
954
|
-
mobify: {
|
|
955
|
-
app: {
|
|
956
|
-
commerceAPI: {
|
|
957
|
-
parameters: {
|
|
958
|
-
clientId: 'clientId',
|
|
959
|
-
shortCode: 'shortCode'
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
},
|
|
964
|
-
useSLASPrivateClient: true,
|
|
965
|
-
slasTarget: slasTarget
|
|
966
|
-
}));
|
|
992
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(appConfig));
|
|
967
993
|
return yield (0, _supertest.default)(app).get('/mobify/slas/private/shopper/auth/v1/somePath').then(response => {
|
|
968
994
|
expect(response.body.authorization).toBeUndefined();
|
|
969
995
|
expect(response.body.host).toBe('shortCode.api.commercecloud.salesforce.com');
|
|
@@ -973,20 +999,7 @@ describe('SLAS private client proxy', () => {
|
|
|
973
999
|
test('inserts client secret if request is for /oauth2/token', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
974
1000
|
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
975
1001
|
const encodedCredentials = Buffer.from('clientId:a secret').toString('base64');
|
|
976
|
-
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(
|
|
977
|
-
mobify: {
|
|
978
|
-
app: {
|
|
979
|
-
commerceAPI: {
|
|
980
|
-
parameters: {
|
|
981
|
-
clientId: 'clientId',
|
|
982
|
-
shortCode: 'shortCode'
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
},
|
|
987
|
-
useSLASPrivateClient: true,
|
|
988
|
-
slasTarget: slasTarget
|
|
989
|
-
}));
|
|
1002
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(appConfig));
|
|
990
1003
|
return yield (0, _supertest.default)(app).get('/mobify/slas/private/shopper/auth/v1/oauth2/token').then(response => {
|
|
991
1004
|
expect(response.body.authorization).toBe(`Basic ${encodedCredentials}`);
|
|
992
1005
|
expect(response.body.host).toBe('shortCode.api.commercecloud.salesforce.com');
|
|
@@ -995,21 +1008,7 @@ describe('SLAS private client proxy', () => {
|
|
|
995
1008
|
}), 15000);
|
|
996
1009
|
test('does not add _sfdc_client_auth header if request not for /oauth2/trusted-agent/token', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
997
1010
|
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
998
|
-
const
|
|
999
|
-
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts({
|
|
1000
|
-
mobify: {
|
|
1001
|
-
app: {
|
|
1002
|
-
commerceAPI: {
|
|
1003
|
-
parameters: {
|
|
1004
|
-
clientId: 'clientId',
|
|
1005
|
-
shortCode: 'shortCode'
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
},
|
|
1010
|
-
useSLASPrivateClient: true,
|
|
1011
|
-
slasTarget: slasTarget
|
|
1012
|
-
}));
|
|
1011
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(appConfig));
|
|
1013
1012
|
return yield (0, _supertest.default)(app).get('/mobify/slas/private/shopper/auth/v1/oauth2/other-path').then(response => {
|
|
1014
1013
|
expect(response.body._sfdc_client_auth).toBeUndefined();
|
|
1015
1014
|
});
|
|
@@ -1040,21 +1039,33 @@ describe('SLAS private client proxy', () => {
|
|
|
1040
1039
|
}), 15000);
|
|
1041
1040
|
test('returns 403 if request is not for /shopper/auth endpoints', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
1042
1041
|
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
1043
|
-
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1042
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(appConfig));
|
|
1043
|
+
return yield (0, _supertest.default)(app).get('/mobify/slas/private/shopper/auth-admin/v1/other-path').expect(403);
|
|
1044
|
+
}), 15000);
|
|
1045
|
+
test('returns 403 if request is for /oauth2/trusted-system/* endpoint', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
1046
|
+
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
1047
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts(appConfig));
|
|
1048
|
+
return yield (0, _supertest.default)(app).get('/mobify/slas/private/shopper/auth/v1/oauth2/trusted-system/token').expect(403);
|
|
1049
|
+
}), 15000);
|
|
1050
|
+
test('throws an error if /oauth2/trusted-system/* is included in applySLASPrivateClientToEndpoints', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
1051
|
+
process.env.PWA_KIT_SLAS_CLIENT_SECRET = 'a secret';
|
|
1052
|
+
expect(() => {
|
|
1053
|
+
_buildRemoteServer.RemoteServerFactory._createApp(opts({
|
|
1054
|
+
mobify: {
|
|
1055
|
+
app: {
|
|
1056
|
+
commerceAPI: {
|
|
1057
|
+
parameters: {
|
|
1058
|
+
clientId: 'clientId',
|
|
1059
|
+
shortCode: 'shortCode'
|
|
1060
|
+
}
|
|
1050
1061
|
}
|
|
1051
1062
|
}
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1063
|
+
},
|
|
1064
|
+
useSLASPrivateClient: true,
|
|
1065
|
+
slasTarget: slasTarget,
|
|
1066
|
+
applySLASPrivateClientToEndpoints: /\/oauth2\/trusted-system/
|
|
1067
|
+
}));
|
|
1068
|
+
}).toThrow('It is not allowed to include /oauth2/trusted-system endpoints in `applySLASPrivateClientToEndpoints`');
|
|
1058
1069
|
}), 15000);
|
|
1059
1070
|
});
|
|
1060
1071
|
describe('Base path tests', () => {
|
|
@@ -1099,6 +1110,24 @@ describe('Base path tests', () => {
|
|
|
1099
1110
|
expect(response.body.userId).toBe('123');
|
|
1100
1111
|
});
|
|
1101
1112
|
}), 15000);
|
|
1113
|
+
test('should remove base path from routes defined with regex', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
1114
|
+
jest.spyOn(ssrConfig, 'getConfig').mockReturnValue({
|
|
1115
|
+
envBasePath: '/basepath'
|
|
1116
|
+
});
|
|
1117
|
+
const app = _buildRemoteServer.RemoteServerFactory._createApp(opts());
|
|
1118
|
+
app.get(/\/api\/users\/\d+/, (req, res) => {
|
|
1119
|
+
// Extract the user ID from the URL path since regex routes don't create req.params automatically
|
|
1120
|
+
const match = req.path.match(/\/api\/users\/(\d+)/);
|
|
1121
|
+
const userId = match ? match[1] : 'unknown';
|
|
1122
|
+
res.status(200).json({
|
|
1123
|
+
userId: userId
|
|
1124
|
+
});
|
|
1125
|
+
});
|
|
1126
|
+
return (0, _supertest.default)(app).get('/basepath/api/users/123').then(response => {
|
|
1127
|
+
expect(response.status).toBe(200);
|
|
1128
|
+
expect(response.body.userId).toBe('123');
|
|
1129
|
+
});
|
|
1130
|
+
}), 15000);
|
|
1102
1131
|
test('remove base path can handle complex base paths', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
1103
1132
|
jest.spyOn(ssrConfig, 'getConfig').mockReturnValue({
|
|
1104
1133
|
envBasePath: '/my/base/path'
|
|
@@ -32,6 +32,7 @@ const SLAS_PRIVATE_CLIENT_PROXY_PATH = `${MOBIFY_PATH}/slas/private`;
|
|
|
32
32
|
|
|
33
33
|
/*
|
|
34
34
|
* Returns the base path. This is prepended to a /mobify path.
|
|
35
|
+
* Returns an empty string if the base path is not set or is '/'.
|
|
35
36
|
*/
|
|
36
37
|
const getEnvBasePath = () => {
|
|
37
38
|
const config = (0, _ssrConfig.getConfig)();
|