perimeterx-js-core 0.12.1 → 0.14.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.
Files changed (38) hide show
  1. package/lib/cjs/config/ConfigurationBase.js +14 -0
  2. package/lib/cjs/config/defaults/DefaultCommonConfigurationParams.js +2 -5
  3. package/lib/cjs/impl/url/UrlImpl.js +27 -7
  4. package/lib/cjs/logger/LoggerBase.js +3 -0
  5. package/lib/cjs/phase/flow/PostEnforceFlow.js +1 -1
  6. package/lib/cjs/phase/impl/CreateBlockResponsePhase.js +1 -1
  7. package/lib/cjs/phase/impl/FirstPartyPhase.js +1 -1
  8. package/lib/cjs/phase/impl/ModifyOutgoingResponsePhase.js +3 -2
  9. package/lib/cjs/phase/impl/SendLogsPhase.js +3 -1
  10. package/lib/cjs/products/bot_defender/block/templates/captcha_template.js +1 -1
  11. package/lib/cjs/products/bot_defender/first_party/DefaultBotDefenderFirstParty.js +45 -10
  12. package/lib/cjs/pxhd/PXHDUtils.js +7 -6
  13. package/lib/cjs/utils/constants.js +2 -2
  14. package/lib/esm/config/ConfigurationBase.js +6 -0
  15. package/lib/esm/config/defaults/DefaultCommonConfigurationParams.js +2 -5
  16. package/lib/esm/impl/url/UrlImpl.js +26 -7
  17. package/lib/esm/logger/LoggerBase.js +3 -0
  18. package/lib/esm/phase/flow/PostEnforceFlow.js +1 -1
  19. package/lib/esm/phase/impl/CreateBlockResponsePhase.js +1 -1
  20. package/lib/esm/phase/impl/FirstPartyPhase.js +1 -1
  21. package/lib/esm/phase/impl/ModifyOutgoingResponsePhase.js +4 -2
  22. package/lib/esm/phase/impl/SendLogsPhase.js +1 -0
  23. package/lib/esm/products/bot_defender/block/templates/captcha_template.js +60 -34
  24. package/lib/esm/products/bot_defender/first_party/DefaultBotDefenderFirstParty.js +45 -10
  25. package/lib/esm/pxhd/PXHDUtils.js +7 -6
  26. package/lib/esm/utils/constants.js +2 -2
  27. package/lib/types/config/ConfigurationBase.d.ts +2 -0
  28. package/lib/types/config/IConfiguration.d.ts +8 -0
  29. package/lib/types/config/params/CommonConfigurationParams.d.ts +2 -5
  30. package/lib/types/impl/url/UrlImpl.d.ts +5 -1
  31. package/lib/types/logger/ILogger.d.ts +4 -0
  32. package/lib/types/logger/LoggerBase.d.ts +1 -0
  33. package/lib/types/phase/impl/ModifyOutgoingResponsePhase.d.ts +3 -1
  34. package/lib/types/products/bot_defender/block/templates/captcha_template.d.ts +1 -1
  35. package/lib/types/products/bot_defender/first_party/DefaultBotDefenderFirstParty.d.ts +1 -0
  36. package/lib/types/pxhd/PXHDUtils.d.ts +1274 -3
  37. package/lib/types/utils/constants.d.ts +1 -1
  38. package/package.json +1 -1
@@ -214,6 +214,13 @@ var ConfigurationBase = /** @class */ (function () {
214
214
  enumerable: false,
215
215
  configurable: true
216
216
  });
217
+ Object.defineProperty(ConfigurationBase.prototype, "firstPartyTimeoutMs", {
218
+ get: function () {
219
+ return this.configParams.px_first_party_timeout_ms;
220
+ },
221
+ enumerable: false,
222
+ configurable: true
223
+ });
217
224
  Object.defineProperty(ConfigurationBase.prototype, "loggerSeverity", {
218
225
  get: function () {
219
226
  return this.logger.getLoggerSeverity();
@@ -627,6 +634,13 @@ var ConfigurationBase = /** @class */ (function () {
627
634
  enumerable: false,
628
635
  configurable: true
629
636
  });
637
+ Object.defineProperty(ConfigurationBase.prototype, "securedPxhdEnabled", {
638
+ get: function () {
639
+ return this.configParams.px_secured_pxhd_enabled;
640
+ },
641
+ enumerable: false,
642
+ configurable: true
643
+ });
630
644
  return ConfigurationBase;
631
645
  }());
632
646
  exports.ConfigurationBase = ConfigurationBase;
@@ -13,7 +13,6 @@ exports.DEFAULT_COMMON_CONFIGURATION_PARAMS = {
13
13
  px_risk_cookie_max_iterations: 5000,
14
14
  px_logger_severity: logger_1.LoggerSeverity.ERROR,
15
15
  px_ip_headers: [],
16
- px_extract_ip: null,
17
16
  px_module_enabled: true,
18
17
  px_module_mode: utils_1.ModuleMode.MONITOR,
19
18
  px_additional_activity_handler: null,
@@ -21,15 +20,13 @@ exports.DEFAULT_COMMON_CONFIGURATION_PARAMS = {
21
20
  px_max_activity_batch_size: 0,
22
21
  px_batch_activities_timeout_ms: 1000,
23
22
  px_bypass_monitor_header: '',
24
- px_csp_enabled: false,
25
- px_csp_no_updates_max_interval_minutes: 60,
26
- px_csp_policy_refresh_interval_minutes: 5,
27
23
  px_enforced_routes: [],
28
24
  px_first_party_enabled: true,
29
25
  px_custom_first_party_prefix: '',
30
26
  px_custom_first_party_sensor_endpoint: '',
31
27
  px_custom_first_party_xhr_endpoint: '',
32
28
  px_custom_first_party_captcha_endpoint: '',
29
+ px_first_party_timeout_ms: 4000,
33
30
  px_backend_url: '',
34
31
  px_backend_collector_url: '',
35
32
  px_backend_captcha_url: 'https://captcha.px-cdn.net',
@@ -103,7 +100,6 @@ exports.DEFAULT_COMMON_CONFIGURATION_PARAMS = {
103
100
  px_sensitive_graphql_operation_names: [],
104
101
  px_sensitive_graphql_operation_types: [],
105
102
  px_enrich_custom_parameters: null,
106
- px_proxy_url: '',
107
103
  px_jwt_cookie_name: '',
108
104
  px_jwt_cookie_user_id_field_name: '',
109
105
  px_jwt_cookie_additional_field_names: [],
@@ -117,4 +113,5 @@ exports.DEFAULT_COMMON_CONFIGURATION_PARAMS = {
117
113
  px_remote_config_max_fetch_attempts: 5,
118
114
  px_remote_config_retry_interval_ms: 1000,
119
115
  px_url_decode_reserved_characters: false,
116
+ px_secured_pxhd_enabled: false,
120
117
  };
@@ -11,15 +11,18 @@ var UrlImpl = /** @class */ (function () {
11
11
  throw new Error("Invalid UrlImpl: ".concat(rawUrl));
12
12
  }
13
13
  this.protocol = match[1];
14
- this.hostname = match[3];
15
- this.port = match[4] || '';
16
- this.pathname = match[5] || '/';
17
- this.search = match[6] || '';
18
- this.hash = match[7] || '';
14
+ this.username = match[3] || '';
15
+ this.password = match[4] || '';
16
+ this.hostname = match[6];
17
+ this.port = match[7] || '';
18
+ this.pathname = match[8] || '/';
19
+ this.search = match[9] || '';
20
+ this.hash = match[10] || '';
21
+ this.urlUtils = new CustomImplUrlUtils_1.CustomImplUrlUtils();
19
22
  }
20
23
  Object.defineProperty(UrlImpl.prototype, "href", {
21
24
  get: function () {
22
- return "".concat(this.origin).concat(this.pathname).concat(this.search).concat(this.hash);
25
+ return "".concat(this.protocol, "//").concat(this.credentials).concat(this.host).concat(this.pathname).concat(this.search).concat(this.hash);
23
26
  },
24
27
  enumerable: false,
25
28
  configurable: true
@@ -57,7 +60,7 @@ var UrlImpl = /** @class */ (function () {
57
60
  });
58
61
  Object.defineProperty(UrlImpl.prototype, "searchParams", {
59
62
  get: function () {
60
- return new UrlSearchParamsImpl_1.UrlSearchParamsImpl(new CustomImplUrlUtils_1.CustomImplUrlUtils(), this.search);
63
+ return new UrlSearchParamsImpl_1.UrlSearchParamsImpl(this.urlUtils, this.search);
61
64
  },
62
65
  enumerable: false,
63
66
  configurable: true
@@ -69,6 +72,23 @@ var UrlImpl = /** @class */ (function () {
69
72
  };
70
73
  return PROTOCOL_TO_DEFAULT_PORT[this.protocol] === port;
71
74
  };
75
+ Object.defineProperty(UrlImpl.prototype, "credentials", {
76
+ get: function () {
77
+ if (!this.username && !this.password) {
78
+ return '';
79
+ }
80
+ var credentials = '';
81
+ if (this.username) {
82
+ credentials += this.urlUtils.encodeUriComponent(this.username);
83
+ }
84
+ if (this.password) {
85
+ credentials += ":".concat(this.urlUtils.encodeUriComponent(this.password));
86
+ }
87
+ return "".concat(credentials, "@");
88
+ },
89
+ enumerable: false,
90
+ configurable: true
91
+ });
72
92
  return UrlImpl;
73
93
  }());
74
94
  exports.UrlImpl = UrlImpl;
@@ -54,6 +54,9 @@ var LoggerBase = /** @class */ (function () {
54
54
  var logRecord = __assign(__assign({}, metadata), { message: message, severity: loggerSeverity, messageTimestamp: Date.now() });
55
55
  this.logs.push(logRecord);
56
56
  };
57
+ LoggerBase.prototype.clearLogs = function () {
58
+ this.logs = [];
59
+ };
57
60
  return LoggerBase;
58
61
  }());
59
62
  exports.LoggerBase = LoggerBase;
@@ -23,7 +23,7 @@ var PostEnforceFlow = /** @class */ (function (_super) {
23
23
  var products = _a.products, activityClient = _a.activityClient;
24
24
  return _super.call(this, [
25
25
  new impl_1.EnrichContextFromResponsePhase(config, products),
26
- new impl_1.ModifyOutgoingResponsePhase(Object.values(products)),
26
+ new impl_1.ModifyOutgoingResponsePhase(config, Object.values(products)),
27
27
  new impl_1.SendAsyncActivitiesOnResponsePhase(activityClient),
28
28
  ]) || this;
29
29
  }
@@ -92,7 +92,7 @@ var CreateBlockResponsePhase = /** @class */ (function () {
92
92
  switch (_c.label) {
93
93
  case 0:
94
94
  if (!context.isMobile && ((_a = context.pxhd) === null || _a === void 0 ? void 0 : _a.source) === pxhd_1.PXHDSource.RISK) {
95
- response = pxhd_1.PXHDUtils.addPxhdToMinimalResponse(context, response);
95
+ response = pxhd_1.PXHDUtils.addPxhdToMinimalResponse(this.config, context, response);
96
96
  }
97
97
  if (!(this.config.corsSupportEnabled && ((_b = this.cors) === null || _b === void 0 ? void 0 : _b.isCorsRequest(context)))) return [3 /*break*/, 2];
98
98
  return [4 /*yield*/, this.cors.getCorsBlockHeaders(context)];
@@ -85,7 +85,7 @@ var FirstPartyPhase = /** @class */ (function () {
85
85
  _b.label = 1;
86
86
  case 1:
87
87
  _b.trys.push([1, 3, , 4]);
88
- return [4 /*yield*/, this.httpClient.send(request)];
88
+ return [4 /*yield*/, this.httpClient.send(request, { timeoutMs: this.config.firstPartyTimeoutMs })];
89
89
  case 2:
90
90
  response = _b.sent();
91
91
  return [2 /*return*/, http_1.MinimalResponseUtils.from(response)];
@@ -39,7 +39,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.ModifyOutgoingResponsePhase = void 0;
40
40
  var pxhd_1 = require("../../pxhd");
41
41
  var ModifyOutgoingResponsePhase = /** @class */ (function () {
42
- function ModifyOutgoingResponsePhase(products) {
42
+ function ModifyOutgoingResponsePhase(config, products) {
43
+ this.config = config;
43
44
  this.products = products;
44
45
  }
45
46
  ModifyOutgoingResponsePhase.prototype.execute = function (context) {
@@ -51,7 +52,7 @@ var ModifyOutgoingResponsePhase = /** @class */ (function () {
51
52
  case 1:
52
53
  _b.sent();
53
54
  if (((_a = context.pxhd) === null || _a === void 0 ? void 0 : _a.source) === pxhd_1.PXHDSource.RISK) {
54
- pxhd_1.PXHDUtils.addPxhdToOutgoingResponse(context, context.response);
55
+ pxhd_1.PXHDUtils.addPxhdToOutgoingResponse(this.config, context, context.response);
55
56
  }
56
57
  return [2 /*return*/, { done: false }];
57
58
  }
@@ -52,7 +52,9 @@ var SendLogsPhase = /** @class */ (function () {
52
52
  case 1:
53
53
  _a.sent();
54
54
  _a.label = 2;
55
- case 2: return [2 /*return*/, { done: false }];
55
+ case 2:
56
+ this.config.logger.clearLogs();
57
+ return [2 /*return*/, { done: false }];
56
58
  }
57
59
  });
58
60
  });
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CAPTCHA_TEMPLATE = void 0;
4
- exports.CAPTCHA_TEMPLATE = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <meta name=\"description\" content=\"px-captcha\">\n <title>Access to this page has been denied</title>\n {{cssRef}}\n</head>\n<body>\n <script>\n /* PerimeterX assignments */\n window._pxVid = '{{vid}}';\n window._pxUuid = '{{uuid}}';\n window._pxAppId = '{{appId}}';\n window._pxMobile = {{isMobile}};\n window._pxHostUrl = '{{hostUrl}}';\n window._pxCustomLogo = '{{customLogo}}';\n window._pxJsClientSrc = '{{jsClientSrc}}';\n window._pxFirstPartyEnabled = {{firstPartyEnabled}};\n var pxCaptchaSrc = '{{blockScript}}';\n\n var script = document.createElement('script');\n script.src = pxCaptchaSrc;\n script.onerror = function () {\n script = document.createElement('script');\n script.src = '{{altBlockScript}}';\n script.onerror = window._pxOnError;\n document.head.appendChild(script);\n };\n window._pxOnError = function () {\n var style = document.createElement('style');\n style.innerText = '@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap);body{background-color:#fafbfc}.px-captcha-error-container{position:fixed;height:340px;background-color:#fff;font-family:Roboto,sans-serif}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:67px 0 33px;font-weight:500;line-height:.83;text-align:center}.px-captcha-error-message{color:#f0f1f2;font-size:18px;margin:0 0 29px;line-height:1.33;text-align:center}.px-captcha-error-button{text-align:center;line-height:48px;width:253px;margin:auto;border-radius:50px;border:solid 1px #f0f1f2;font-size:20px;color:#f0f1f2}.px-captcha-error-wrapper{margin:18px 0 0}div.px-captcha-error{margin:auto;text-align:center;width:400px;height:30px;font-size:12px;background-color:#fcf0f2;color:#ce0e2d}img.px-captcha-error{margin:6px 8px -2px 0}.px-captcha-error-refid{border-top:solid 1px #f0eeee;height:27px;margin:13px 0 0;border-radius:0 0 3px 3px;background-color:#fafbfc;font-size:10px;line-height:2.5;text-align:center;color:#b1b5b8}@media (min-width:620px){.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (min-width:481px) and (max-width:620px){.px-captcha-error-container{width:85%;top:50%;left:50%;margin-top:-170px;margin-left:-42.5%;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (max-width:480px){body{background-color:#fff}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:55px 0 33px}.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px}.px-captcha-error-refid{position:fixed;width:100%;left:0;bottom:0;border-radius:0;font-size:14px;line-height:2}}@media (max-width:390px){div.px-captcha-error{font-size:10px}.px-captcha-error-refid{font-size:11px;line-height:2.5}}';\n document.head.appendChild(style);\n var div = document.createElement('div');\n div.className = 'px-captcha-error-container';\n div.innerHTML = '<div class=\"px-captcha-error-header\">Before we continue...</div><div class=\"px-captcha-error-message\">Press & Hold to confirm you are<br>a human (and not a bot).</div><div class=\"px-captcha-error-button\">Press & Hold</div><div class=\"px-captcha-error-wrapper\"><div class=\"px-captcha-error\"><img class=\"px-captcha-error\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAQCAMAAADDGrRQAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABFUExURUdwTNYELOEGONQILd0AONwALtwEL+AAL9MFLfkJSNQGLdMJLdQJLdQGLdQKLtYFLNcELdUGLdcBL9gFL88OLdUFLNEOLglBhT4AAAAXdFJOUwC8CqgNIRgRoAS1dWWuR4RTjzgryZpYblfkcAAAAI9JREFUGNNdj+sWhCAIhAdvqGVa1r7/oy6RZ7eaH3D4ZACBIed9wlOOMtUnSrEmZ6cHa9YAIfsbCkWrdpi/c50Bk2CO9mNLdMAu03wJA3HpEnfpxbyOg6ruyx8JJi6KNstnslp1dbPd9GnqmuYq7mmcv1zjnbQw8cV0xzkqo+fX1zkjUOO7wnrInUTxJiruC3vtBNRoQQn2AAAAAElFTkSuQmCC\">Please check your internet connection' + (window._pxMobile ? '' : ' or disable your ad-blocker') + '.</div></div><div class=\"px-captcha-error-refid\">Reference ID ' + window._pxUuid + '</div>';\n document.body.appendChild(div);\n if (window._pxMobile) {\n setTimeout(function() {\n location.href = '/px/captcha_close?status=-1';\n }, 5000);\n }\n };\n document.head.appendChild(script);\n </script>\n {{jsRef}}\n</body>\n</html>\n";
4
+ exports.CAPTCHA_TEMPLATE = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <meta name=\"description\" content=\"px-captcha\">\n <title>Access to this page has been denied</title>\n {{cssRef}}\n</head>\n<body>\n<script>\n /* PerimeterX assignments */\n window._pxVid = '{{vid}}';\n window._pxUuid = '{{uuid}}';\n window._pxAppId = '{{appId}}';\n window._pxHostUrl = '{{hostUrl}}';\n window._pxCustomLogo = '{{customLogo}}';\n window._pxJsClientSrc = '{{jsClientSrc}}';\n window._pxMobile = {{isMobile}};\n window._pxFirstPartyEnabled = {{firstPartyEnabled}};\n var pxCaptchaSrc = '{{blockScript}}';\n var script = document.createElement('script');\n script.src = pxCaptchaSrc;\n script.onload = onScriptLoad;\n script.onerror = onScriptError;\n var onScriptErrorCalled;\n document.head.appendChild(script);\n var timeoutID = setTimeout(onScriptError, 5000);\n function onScriptLoad() {\n clearTimeout(timeoutID);\n setTimeout(function() {\n if (isCaptchaNotLoaded()) {\n onScriptError();\n }\n }, 1000);\n }\n function onScriptError() {\n if (onScriptErrorCalled) {\n return;\n }\n onScriptErrorCalled = true;\n script = document.createElement('script');\n script.src = '{{altBlockScript}}';\n script.onload = function() {\n clearTimeout(timeoutID);\n };\n script.onerror = window._pxOnError;\n document.head.appendChild(script);\n timeoutID = setTimeout(function() {\n if (isCaptchaNotLoaded()) {\n window._pxOnError();\n }\n }, 5000);\n }\n function isCaptchaNotLoaded() {\n return !document.querySelector('div');\n }\n window._pxOnError = function () {\n var style = document.createElement('style');\n style.innerText = '@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap);body{background-color:#fafbfc}.px-captcha-error-container{position:fixed;height:340px;background-color:#fff;font-family:Roboto,sans-serif}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:67px 0 33px;font-weight:500;line-height:.83;text-align:center}.px-captcha-error-message{color:#f0f1f2;font-size:18px;margin:0 0 29px;line-height:1.33;text-align:center}.px-captcha-error-button{text-align:center;line-height:48px;width:253px;margin:auto;border-radius:50px;border:solid 1px #f0f1f2;font-size:20px;color:#f0f1f2}.px-captcha-error-wrapper{margin:18px 0 0}div.px-captcha-error{margin:auto;text-align:center;width:400px;height:30px;font-size:12px;background-color:#fcf0f2;color:#ce0e2d}img.px-captcha-error{margin:6px 8px -2px 0}.px-captcha-error-refid{border-top:solid 1px #f0eeee;height:27px;margin:13px 0 0;border-radius:0 0 3px 3px;background-color:#fafbfc;font-size:10px;line-height:2.5;text-align:center;color:#b1b5b8}@media (min-width:620px){.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (min-width:481px) and (max-width:620px){.px-captcha-error-container{width:85%;top:50%;left:50%;margin-top:-170px;margin-left:-42.5%;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (max-width:480px){body{background-color:#fff}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:55px 0 33px}.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px}.px-captcha-error-refid{position:fixed;width:100%;left:0;bottom:0;border-radius:0;font-size:14px;line-height:2}}@media (max-width:390px){div.px-captcha-error{font-size:10px}.px-captcha-error-refid{font-size:11px;line-height:2.5}}';\n document.head.appendChild(style);\n var div = document.createElement('div');\n div.className = 'px-captcha-error-container';\n div.innerHTML = '<div class=\"px-captcha-error-header\">Before we continue...</div><div class=\"px-captcha-error-message\">Press & Hold to confirm you are<br>a human (and not a bot).</div><div class=\"px-captcha-error-button\">Press & Hold</div><div class=\"px-captcha-error-wrapper\"><div class=\"px-captcha-error\"><img class=\"px-captcha-error\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAQCAMAAADDGrRQAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABFUExURUdwTNYELOEGONQILd0AONwALtwEL+AAL9MFLfkJSNQGLdMJLdQJLdQGLdQKLtYFLNcELdUGLdcBL9gFL88OLdUFLNEOLglBhT4AAAAXdFJOUwC8CqgNIRgRoAS1dWWuR4RTjzgryZpYblfkcAAAAI9JREFUGNNdj+sWhCAIhAdvqGVa1r7/oy6RZ7eaH3D4ZACBIed9wlOOMtUnSrEmZ6cHa9YAIfsbCkWrdpi/c50Bk2CO9mNLdMAu03wJA3HpEnfpxbyOg6ruyx8JJi6KNstnslp1dbPd9GnqmuYq7mmcv1zjnbQw8cV0xzkqo+fX1zkjUOO7wnrInUTxJiruC3vtBNRoQQn2AAAAAElFTkSuQmCC\">Please check your internet connection' + (window._pxMobile ? '' : ' or disable your ad-blocker') + '.</div></div><div class=\"px-captcha-error-refid\">Reference ID ' + window._pxUuid + '</div>';\n document.body.appendChild(div);\n if (window._pxMobile) {\n setTimeout(function() {\n location.href = '/px/captcha_close?status=-1';\n }, 5000);\n }\n };\n</script>\n{{jsRef}}\n</body>\n</html>\n";
@@ -85,6 +85,9 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
85
85
  return [2 /*return*/, { defaultResponse: defaultResponse }];
86
86
  }
87
87
  url = this.getThirdPartySensorScriptUrl();
88
+ if (!url) {
89
+ return [2 /*return*/, { defaultResponse: defaultResponse }];
90
+ }
88
91
  return [4 /*yield*/, this.getOutgoingRequest(url, context)];
89
92
  case 1:
90
93
  request = _a.sent();
@@ -105,6 +108,9 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
105
108
  return [2 /*return*/, { defaultResponse: defaultResponse }];
106
109
  }
107
110
  url = this.getThirdPartyXhrUrl(context, prefix);
111
+ if (!url) {
112
+ return [2 /*return*/, { defaultResponse: defaultResponse }];
113
+ }
108
114
  return [4 /*yield*/, this.getOutgoingRequest(url, context)];
109
115
  case 1:
110
116
  request = _a.sent();
@@ -133,6 +139,9 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
133
139
  return [2 /*return*/, { defaultResponse: defaultResponse }];
134
140
  }
135
141
  url = this.getThirdPartyCaptchaScriptUrl(context);
142
+ if (!url) {
143
+ return [2 /*return*/, { defaultResponse: defaultResponse }];
144
+ }
136
145
  return [4 /*yield*/, this.getOutgoingRequest(url, context)];
137
146
  case 1:
138
147
  request = _a.sent();
@@ -147,7 +156,7 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
147
156
  return __awaiter(this, void 0, void 0, function () {
148
157
  return __generator(this, function (_b) {
149
158
  return [2 /*return*/, new http_1.OutgoingRequestImpl({
150
- url: url,
159
+ url: url.href,
151
160
  method: requestData.method,
152
161
  headers: this.prepareFirstPartyHeaders(url, requestData, vid),
153
162
  body: requestData.request.body,
@@ -173,8 +182,7 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
173
182
  return headers;
174
183
  };
175
184
  DefaultBotDefenderFirstParty.prototype.setHostHeader = function (headers, url) {
176
- var host = this.urlUtils.createUrl(url).host;
177
- headers[http_1.HOST_HEADER_NAME] = [host];
185
+ headers[http_1.HOST_HEADER_NAME] = [url.host];
178
186
  };
179
187
  DefaultBotDefenderFirstParty.prototype.setXffHeader = function (headers, ip) {
180
188
  var xffValue = headers[http_1.X_FORWARDED_FOR_HEADER_NAME] || [];
@@ -185,17 +193,44 @@ var DefaultBotDefenderFirstParty = /** @class */ (function () {
185
193
  headers[constants_1.X_PX_ENFORCER_TRUE_IP_HEADER_NAME] = [ip];
186
194
  };
187
195
  DefaultBotDefenderFirstParty.prototype.getThirdPartySensorScriptUrl = function () {
188
- return "".concat(this.config.backendClientUrl, "/").concat(this.config.appId, "/main.min.js");
196
+ try {
197
+ return this.urlUtils.createUrl("".concat(this.config.backendClientUrl, "/").concat(this.config.appId, "/main.min.js"));
198
+ }
199
+ catch (e) {
200
+ this.config.logger.debug("unable to create third party sensor URL: ".concat(e));
201
+ return null;
202
+ }
189
203
  };
190
204
  DefaultBotDefenderFirstParty.prototype.getThirdPartyCaptchaScriptUrl = function (context) {
191
- var originalUrl = context.requestData.url;
192
- var _a = this.config, appId = _a.appId, backendCaptchaUrl = _a.backendCaptchaUrl;
193
- return "".concat(backendCaptchaUrl, "/").concat(appId).concat(FirstPartySuffix_1.FirstPartySuffix.CAPTCHA, ".js").concat(originalUrl.search);
205
+ try {
206
+ var originalUrl = context.requestData.url;
207
+ var _a = this.config, appId = _a.appId, backendCaptchaUrl = _a.backendCaptchaUrl;
208
+ return this.urlUtils.createUrl("".concat(backendCaptchaUrl, "/").concat(appId).concat(FirstPartySuffix_1.FirstPartySuffix.CAPTCHA, ".js").concat(originalUrl.search));
209
+ }
210
+ catch (e) {
211
+ this.config.logger.debug("unable to create third party captcha URL: ".concat(e));
212
+ return null;
213
+ }
194
214
  };
195
215
  DefaultBotDefenderFirstParty.prototype.getThirdPartyXhrUrl = function (context, prefix) {
196
- var originalUrl = context.requestData.url;
197
- var backendCollectorUrl = this.config.backendCollectorUrl;
198
- return "".concat(backendCollectorUrl).concat(originalUrl.pathname.replace(prefix, '')).concat(originalUrl.search);
216
+ try {
217
+ var originalUrl = context.requestData.url;
218
+ var pathname = originalUrl.pathname.replace(prefix, '');
219
+ var thirdPartyUrl = this.urlUtils.createUrl("".concat(this.config.backendCollectorUrl).concat(pathname).concat(originalUrl.search));
220
+ var host = this.urlUtils.createUrl(this.config.backendCollectorUrl).host;
221
+ if (!this.isValidThirdPartyUrl(thirdPartyUrl, host, pathname)) {
222
+ this.config.logger.debug("invalid third party url: ".concat(thirdPartyUrl));
223
+ return null;
224
+ }
225
+ return thirdPartyUrl;
226
+ }
227
+ catch (e) {
228
+ this.config.logger.debug("unable to create third party XHR URL: ".concat(e));
229
+ return null;
230
+ }
231
+ };
232
+ DefaultBotDefenderFirstParty.prototype.isValidThirdPartyUrl = function (url, expectedHost, expectedPath) {
233
+ return url.host.toLowerCase() === expectedHost.toLowerCase() && url.pathname.startsWith(expectedPath);
199
234
  };
200
235
  return DefaultBotDefenderFirstParty;
201
236
  }());
@@ -7,25 +7,26 @@ var PXHDUtils;
7
7
  (function (PXHDUtils) {
8
8
  PXHDUtils.PXHD_SAMESITE_VALUE = 'Lax';
9
9
  PXHDUtils.PXHD_PATH_VALUE = '/';
10
- PXHDUtils.addPxhdToOutgoingResponse = function (context, response) {
10
+ PXHDUtils.addPxhdToOutgoingResponse = function (config, context, response) {
11
11
  if (!(context === null || context === void 0 ? void 0 : context.pxhd)) {
12
12
  return;
13
13
  }
14
- var setPxhdCookie = PXHDUtils.getPxhdCookieValue(context.pxhd);
14
+ var setPxhdCookie = PXHDUtils.getPxhdCookieValue(context.pxhd, config.securedPxhdEnabled);
15
15
  response.headers.append(http_1.SET_COOKIE_HEADER_NAME, setPxhdCookie);
16
16
  };
17
- PXHDUtils.addPxhdToMinimalResponse = function (context, response) {
17
+ PXHDUtils.addPxhdToMinimalResponse = function (config, context, response) {
18
18
  if (context === null || context === void 0 ? void 0 : context.pxhd) {
19
- var setPxhdCookie = PXHDUtils.getPxhdCookieValue(context.pxhd);
19
+ var setPxhdCookie = PXHDUtils.getPxhdCookieValue(context.pxhd, config.securedPxhdEnabled);
20
20
  return http_1.MinimalResponseUtils.appendHeader(response, http_1.SET_COOKIE_HEADER_NAME, setPxhdCookie);
21
21
  }
22
22
  return response;
23
23
  };
24
- PXHDUtils.getPxhdCookieValue = function (pxhd) {
24
+ PXHDUtils.getPxhdCookieValue = function (pxhd, isSecure) {
25
25
  var value = "".concat(utils_1.PXHD_COOKIE_NAME, "=").concat(pxhd.value);
26
+ var secure = isSecure ? 'Secure' : '';
26
27
  var domain = pxhd.domain && "domain=".concat(pxhd.domain);
27
28
  var path = "path=".concat(PXHDUtils.PXHD_PATH_VALUE);
28
29
  var sameSite = "SameSite=".concat(PXHDUtils.PXHD_SAMESITE_VALUE);
29
- return [value, domain, path, sameSite].filter(Boolean).join('; ');
30
+ return [value, secure, domain, path, sameSite].filter(Boolean).join('; ');
30
31
  };
31
32
  })(PXHDUtils || (exports.PXHDUtils = PXHDUtils = {}));
@@ -12,5 +12,5 @@ exports.X_PX_BYPASS_REASON_HEADER_NAME = 'x-px-bypass-reason';
12
12
  exports.PUSH_DATA_HMAC_HEADER_NAME = 'x-px-pushdata';
13
13
  exports.PUSH_DATA_FEATURE_HEADER_NAME = 'x-px-feature';
14
14
  exports.EMAIL_ADDRESS_REGEX = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/;
15
- exports.URL_REGEX = /^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/;
16
- exports.CORE_MODULE_VERSION = 'JS Core 0.12.1';
15
+ exports.URL_REGEX = /^(https?\:)\/\/(([^@\s:]+):?([^@\s]*)@)?(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/;
16
+ exports.CORE_MODULE_VERSION = 'JS Core 0.14.0';
@@ -124,6 +124,9 @@ export class ConfigurationBase {
124
124
  get customFirstPartyCaptchaEndpoint() {
125
125
  return this.configParams.px_custom_first_party_captcha_endpoint;
126
126
  }
127
+ get firstPartyTimeoutMs() {
128
+ return this.configParams.px_first_party_timeout_ms;
129
+ }
127
130
  get loggerSeverity() {
128
131
  return this.logger.getLoggerSeverity();
129
132
  }
@@ -301,4 +304,7 @@ export class ConfigurationBase {
301
304
  get urlDecodeReservedCharacters() {
302
305
  return this.configParams.px_url_decode_reserved_characters;
303
306
  }
307
+ get securedPxhdEnabled() {
308
+ return this.configParams.px_secured_pxhd_enabled;
309
+ }
304
310
  }
@@ -10,7 +10,6 @@ export const DEFAULT_COMMON_CONFIGURATION_PARAMS = {
10
10
  px_risk_cookie_max_iterations: 5000,
11
11
  px_logger_severity: LoggerSeverity.ERROR,
12
12
  px_ip_headers: [],
13
- px_extract_ip: null,
14
13
  px_module_enabled: true,
15
14
  px_module_mode: ModuleMode.MONITOR,
16
15
  px_additional_activity_handler: null,
@@ -18,15 +17,13 @@ export const DEFAULT_COMMON_CONFIGURATION_PARAMS = {
18
17
  px_max_activity_batch_size: 0,
19
18
  px_batch_activities_timeout_ms: 1000,
20
19
  px_bypass_monitor_header: '',
21
- px_csp_enabled: false,
22
- px_csp_no_updates_max_interval_minutes: 60,
23
- px_csp_policy_refresh_interval_minutes: 5,
24
20
  px_enforced_routes: [],
25
21
  px_first_party_enabled: true,
26
22
  px_custom_first_party_prefix: '',
27
23
  px_custom_first_party_sensor_endpoint: '',
28
24
  px_custom_first_party_xhr_endpoint: '',
29
25
  px_custom_first_party_captcha_endpoint: '',
26
+ px_first_party_timeout_ms: 4000,
30
27
  px_backend_url: '',
31
28
  px_backend_collector_url: '',
32
29
  px_backend_captcha_url: 'https://captcha.px-cdn.net',
@@ -100,7 +97,6 @@ export const DEFAULT_COMMON_CONFIGURATION_PARAMS = {
100
97
  px_sensitive_graphql_operation_names: [],
101
98
  px_sensitive_graphql_operation_types: [],
102
99
  px_enrich_custom_parameters: null,
103
- px_proxy_url: '',
104
100
  px_jwt_cookie_name: '',
105
101
  px_jwt_cookie_user_id_field_name: '',
106
102
  px_jwt_cookie_additional_field_names: [],
@@ -114,4 +110,5 @@ export const DEFAULT_COMMON_CONFIGURATION_PARAMS = {
114
110
  px_remote_config_max_fetch_attempts: 5,
115
111
  px_remote_config_retry_interval_ms: 1000,
116
112
  px_url_decode_reserved_characters: false,
113
+ px_secured_pxhd_enabled: false,
117
114
  };
@@ -7,21 +7,27 @@ export class UrlImpl {
7
7
  pathname;
8
8
  search;
9
9
  hash;
10
+ username;
11
+ password;
10
12
  _port;
13
+ urlUtils;
11
14
  constructor(rawUrl) {
12
15
  const match = rawUrl.match(URL_REGEX);
13
16
  if (!match) {
14
17
  throw new Error(`Invalid UrlImpl: ${rawUrl}`);
15
18
  }
16
19
  this.protocol = match[1];
17
- this.hostname = match[3];
18
- this.port = match[4] || '';
19
- this.pathname = match[5] || '/';
20
- this.search = match[6] || '';
21
- this.hash = match[7] || '';
20
+ this.username = match[3] || '';
21
+ this.password = match[4] || '';
22
+ this.hostname = match[6];
23
+ this.port = match[7] || '';
24
+ this.pathname = match[8] || '/';
25
+ this.search = match[9] || '';
26
+ this.hash = match[10] || '';
27
+ this.urlUtils = new CustomImplUrlUtils();
22
28
  }
23
29
  get href() {
24
- return `${this.origin}${this.pathname}${this.search}${this.hash}`;
30
+ return `${this.protocol}//${this.credentials}${this.host}${this.pathname}${this.search}${this.hash}`;
25
31
  }
26
32
  get origin() {
27
33
  return `${this.protocol}//${this.host}`;
@@ -43,7 +49,7 @@ export class UrlImpl {
43
49
  }
44
50
  }
45
51
  get searchParams() {
46
- return new UrlSearchParamsImpl(new CustomImplUrlUtils(), this.search);
52
+ return new UrlSearchParamsImpl(this.urlUtils, this.search);
47
53
  }
48
54
  isDefaultPort(port) {
49
55
  const PROTOCOL_TO_DEFAULT_PORT = {
@@ -52,4 +58,17 @@ export class UrlImpl {
52
58
  };
53
59
  return PROTOCOL_TO_DEFAULT_PORT[this.protocol] === port;
54
60
  }
61
+ get credentials() {
62
+ if (!this.username && !this.password) {
63
+ return '';
64
+ }
65
+ let credentials = '';
66
+ if (this.username) {
67
+ credentials += this.urlUtils.encodeUriComponent(this.username);
68
+ }
69
+ if (this.password) {
70
+ credentials += `:${this.urlUtils.encodeUriComponent(this.password)}`;
71
+ }
72
+ return `${credentials}@`;
73
+ }
55
74
  }
@@ -45,4 +45,7 @@ export class LoggerBase {
45
45
  };
46
46
  this.logs.push(logRecord);
47
47
  }
48
+ clearLogs() {
49
+ this.logs = [];
50
+ }
48
51
  }
@@ -3,7 +3,7 @@ export class PostEnforceFlow extends CompositePhase {
3
3
  constructor(config, { products, activityClient }) {
4
4
  super([
5
5
  new EnrichContextFromResponsePhase(config, products),
6
- new ModifyOutgoingResponsePhase(Object.values(products)),
6
+ new ModifyOutgoingResponsePhase(config, Object.values(products)),
7
7
  new SendAsyncActivitiesOnResponsePhase(activityClient),
8
8
  ]);
9
9
  }
@@ -39,7 +39,7 @@ export class CreateBlockResponsePhase {
39
39
  }
40
40
  async addHeadersToResponse(response, context) {
41
41
  if (!context.isMobile && context.pxhd?.source === PXHDSource.RISK) {
42
- response = PXHDUtils.addPxhdToMinimalResponse(context, response);
42
+ response = PXHDUtils.addPxhdToMinimalResponse(this.config, context, response);
43
43
  }
44
44
  if (this.config.corsSupportEnabled && this.cors?.isCorsRequest(context)) {
45
45
  const corsHeaders = await this.cors.getCorsBlockHeaders(context);
@@ -24,7 +24,7 @@ export class FirstPartyPhase {
24
24
  return defaultResponse;
25
25
  }
26
26
  try {
27
- const response = await this.httpClient.send(request);
27
+ const response = await this.httpClient.send(request, { timeoutMs: this.config.firstPartyTimeoutMs });
28
28
  return MinimalResponseUtils.from(response);
29
29
  }
30
30
  catch (e) {
@@ -1,13 +1,15 @@
1
1
  import { PXHDSource, PXHDUtils } from '../../pxhd';
2
2
  export class ModifyOutgoingResponsePhase {
3
+ config;
3
4
  products;
4
- constructor(products) {
5
+ constructor(config, products) {
6
+ this.config = config;
5
7
  this.products = products;
6
8
  }
7
9
  async execute(context) {
8
10
  await Promise.all(this.products.map((product) => product?.modifyOutgoingResponse(context)));
9
11
  if (context.pxhd?.source === PXHDSource.RISK) {
10
- PXHDUtils.addPxhdToOutgoingResponse(context, context.response);
12
+ PXHDUtils.addPxhdToOutgoingResponse(this.config, context, context.response);
11
13
  }
12
14
  return { done: false };
13
15
  }
@@ -9,6 +9,7 @@ export class SendLogsPhase {
9
9
  if (context.shouldSendLogs) {
10
10
  await this.logServiceClient.sendLogs(context, this.config.logger.getLogs());
11
11
  }
12
+ this.config.logger.clearLogs();
12
13
  return { done: false };
13
14
  }
14
15
  }