perimeterx-js-core 0.24.4 → 0.25.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 (92) hide show
  1. package/lib/cjs/config/ConfigurationBase.js +9 -6
  2. package/lib/cjs/config/index.js +0 -1
  3. package/lib/cjs/config/remote_config/RemoteConfigUtils.js +12 -2
  4. package/lib/cjs/config/remote_config/index.js +2 -2
  5. package/lib/cjs/config/remote_config/manager/DefaultRemoteConfigManager.js +191 -0
  6. package/lib/cjs/config/remote_config/manager/index.js +18 -0
  7. package/lib/cjs/config/remote_config/model/index.js +1 -1
  8. package/lib/cjs/config/remote_config/update_parser/DefaultNotifyRemoteConfigUpdateParser.js +139 -0
  9. package/lib/cjs/config/remote_config/update_parser/IRemoteConfigUpdateParser.js +2 -0
  10. package/lib/cjs/config/remote_config/update_parser/index.js +18 -0
  11. package/lib/cjs/context/DefaultContext.js +22 -4
  12. package/lib/cjs/context/SerializedContext.js +1 -1
  13. package/lib/cjs/context/interfaces/RemoteConfigUpdateData.js +2 -0
  14. package/lib/cjs/context/interfaces/index.js +1 -0
  15. package/lib/cjs/enforcer/EnforcerBase.js +16 -10
  16. package/lib/cjs/enforcer/utils.js +34 -38
  17. package/lib/cjs/phase/flow/EndEnforcerFlow.js +6 -4
  18. package/lib/cjs/phase/flow/FilterFlow.js +3 -4
  19. package/lib/cjs/phase/impl/IdentifyRemoteConfigNotifyRequestPhase.js +75 -0
  20. package/lib/cjs/phase/impl/UpdateRemoteConfigPhase.js +7 -14
  21. package/lib/cjs/phase/impl/index.js +2 -1
  22. package/lib/cjs/utils/constants.js +1 -1
  23. package/lib/esm/config/ConfigurationBase.js +10 -8
  24. package/lib/esm/config/index.js +0 -1
  25. package/lib/esm/config/remote_config/RemoteConfigUtils.js +11 -2
  26. package/lib/esm/config/remote_config/index.js +2 -2
  27. package/lib/esm/config/remote_config/manager/DefaultRemoteConfigManager.js +87 -0
  28. package/lib/esm/config/remote_config/manager/index.js +2 -0
  29. package/lib/esm/config/remote_config/model/index.js +1 -1
  30. package/lib/esm/config/remote_config/update_parser/DefaultNotifyRemoteConfigUpdateParser.js +60 -0
  31. package/lib/esm/config/remote_config/update_parser/IRemoteConfigUpdateParser.js +1 -0
  32. package/lib/esm/config/remote_config/update_parser/index.js +2 -0
  33. package/lib/esm/context/DefaultContext.js +19 -6
  34. package/lib/esm/context/SerializedContext.js +2 -2
  35. package/lib/esm/context/interfaces/RemoteConfigUpdateData.js +1 -0
  36. package/lib/esm/context/interfaces/index.js +1 -0
  37. package/lib/esm/enforcer/EnforcerBase.js +3 -0
  38. package/lib/esm/enforcer/utils.js +32 -17
  39. package/lib/esm/logger/LoggerBase.js +1 -1
  40. package/lib/esm/phase/flow/EndEnforcerFlow.js +5 -3
  41. package/lib/esm/phase/flow/FilterFlow.js +4 -5
  42. package/lib/esm/phase/impl/IdentifyRemoteConfigNotifyRequestPhase.js +24 -0
  43. package/lib/esm/phase/impl/UpdateRemoteConfigPhase.js +6 -13
  44. package/lib/esm/phase/impl/index.js +2 -1
  45. package/lib/esm/utils/constants.js +1 -1
  46. package/lib/types/config/ConfigurationBase.d.ts +3 -2
  47. package/lib/types/config/IConfiguration.d.ts +3 -2
  48. package/lib/types/config/index.d.ts +0 -1
  49. package/lib/types/config/params/CoreConfigurationParams.d.ts +1 -1
  50. package/lib/types/config/remote_config/RemoteConfigUtils.d.ts +2 -1
  51. package/lib/types/config/remote_config/index.d.ts +2 -2
  52. package/lib/types/config/remote_config/manager/DefaultRemoteConfigManager.d.ts +23 -0
  53. package/lib/types/config/remote_config/manager/IRemoteConfigManager.d.ts +7 -0
  54. package/lib/types/config/remote_config/manager/index.d.ts +2 -0
  55. package/lib/types/config/remote_config/model/RemoteConfigNotifyRequestPayload.d.ts +3 -0
  56. package/lib/types/config/remote_config/model/index.d.ts +1 -1
  57. package/lib/types/config/remote_config/service_client/HttpRemoteConfigServiceClient.d.ts +2 -2
  58. package/lib/types/config/remote_config/service_client/IRemoteConfigServiceClient.d.ts +2 -2
  59. package/lib/types/config/remote_config/storage_client/IRemoteConfigStorageClient.d.ts +1 -1
  60. package/lib/types/config/remote_config/update_parser/DefaultNotifyRemoteConfigUpdateParser.d.ts +22 -0
  61. package/lib/types/config/remote_config/update_parser/IRemoteConfigUpdateParser.d.ts +5 -0
  62. package/lib/types/config/remote_config/update_parser/index.d.ts +2 -0
  63. package/lib/types/context/ContextJson.d.ts +2 -2
  64. package/lib/types/context/DefaultContext.d.ts +5 -3
  65. package/lib/types/context/SerializedContext.d.ts +2 -2
  66. package/lib/types/context/interfaces/IContext.d.ts +4 -3
  67. package/lib/types/context/interfaces/RemoteConfigUpdateData.d.ts +4 -0
  68. package/lib/types/context/interfaces/index.d.ts +1 -0
  69. package/lib/types/enforcer/EnforcerBase.d.ts +2 -1
  70. package/lib/types/enforcer/EnforcerOptions.d.ts +3 -2
  71. package/lib/types/enforcer/utils.d.ts +7 -1
  72. package/lib/types/logger/ILogger.d.ts +4 -0
  73. package/lib/types/logger/LoggerBase.d.ts +1 -1
  74. package/lib/types/phase/flow/EndEnforcerFlow.d.ts +2 -2
  75. package/lib/types/phase/flow/FilterFlow.d.ts +1 -1
  76. package/lib/types/phase/impl/IdentifyRemoteConfigNotifyRequestPhase.d.ts +9 -0
  77. package/lib/types/phase/impl/UpdateRemoteConfigPhase.d.ts +3 -5
  78. package/lib/types/phase/impl/index.d.ts +2 -1
  79. package/lib/types/utils/constants.d.ts +1 -1
  80. package/package.json +13 -13
  81. package/lib/cjs/config/ConfigurationBuilderBase.js +0 -135
  82. package/lib/cjs/config/remote_config/DefaultRemoteConfigUpdater.js +0 -200
  83. package/lib/esm/config/ConfigurationBuilderBase.js +0 -66
  84. package/lib/esm/config/remote_config/DefaultRemoteConfigUpdater.js +0 -99
  85. package/lib/types/config/ConfigurationBuilderBase.d.ts +0 -13
  86. package/lib/types/config/remote_config/DefaultRemoteConfigUpdater.d.ts +0 -34
  87. package/lib/types/config/remote_config/IRemoteConfigUpdater.d.ts +0 -6
  88. package/lib/types/config/remote_config/model/RemoteConfigUpdateRequestData.d.ts +0 -3
  89. /package/lib/cjs/config/remote_config/{IRemoteConfigUpdater.js → manager/IRemoteConfigManager.js} +0 -0
  90. /package/lib/cjs/config/remote_config/model/{RemoteConfigUpdateRequestData.js → RemoteConfigNotifyRequestPayload.js} +0 -0
  91. /package/lib/esm/config/remote_config/{IRemoteConfigUpdater.js → manager/IRemoteConfigManager.js} +0 -0
  92. /package/lib/esm/config/remote_config/model/{RemoteConfigUpdateRequestData.js → RemoteConfigNotifyRequestPayload.js} +0 -0
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.createEnforcerProducts = exports.createEnforcerInitializationBlock = void 0;
14
+ exports.createRemoteConfigClients = exports.createEnforcerProducts = exports.createEnforcerInitializationBlock = void 0;
15
15
  var risk_token_1 = require("../risk_token/index.js");
16
16
  var config_1 = require("../config/index.js");
17
17
  var cors_1 = require("../cors/index.js");
@@ -25,14 +25,14 @@ var products_1 = require("../products/index.js");
25
25
  var utils_1 = require("../utils/index.js");
26
26
  var snippet_injection_1 = require("../snippet_injection/index.js");
27
27
  var createEnforcerInitializationBlock = function (config, options) {
28
- var _a, _b, _c;
28
+ var _a, _b;
29
29
  var tokenVersion = config.tokenVersion;
30
30
  if (!(0, utils_1.isValidTokenVersion)(tokenVersion)) {
31
31
  throw new utils_1.EnforcerError("error initializing enforcer: token version ".concat(tokenVersion, " is invalid (must be one of ").concat(Object.values(risk_token_1.TokenVersion)
32
32
  .map(function (v) { return "\"".concat(v, "\""); })
33
33
  .join(', '), ")"));
34
34
  }
35
- var cipherUtils = tokenVersion === risk_token_1.TokenVersion.V2 ? null : (_a = options.cipherUtils) !== null && _a !== void 0 ? _a : null;
35
+ var cipherUtils = tokenVersion === risk_token_1.TokenVersion.V2 ? null : ((_a = options.cipherUtils) !== null && _a !== void 0 ? _a : null);
36
36
  if (tokenVersion === risk_token_1.TokenVersion.V3 && !cipherUtils) {
37
37
  throw new utils_1.EnforcerError('error initializing enforcer: token v3 requires cipherUtils');
38
38
  }
@@ -54,42 +54,10 @@ var createEnforcerInitializationBlock = function (config, options) {
54
54
  ? new activities_1.HttpBatchedActivityClient(config, httpClient)
55
55
  : new activities_1.HttpActivityClient(config, httpClient));
56
56
  var logServiceClient = options.logServiceClient || (config.loggerAuthToken ? new logger_1.HttpLogServiceClient(config, httpClient) : null);
57
- var remoteConfigStorageClient = (_b = options.remoteConfigStorageClient) !== null && _b !== void 0 ? _b : null;
58
- var remoteConfigServiceClient = options.remoteConfigServiceClient ||
59
- (config.remoteConfigAuthToken ? new config_1.HttpRemoteConfigServiceClient(config, httpClient) : null);
60
- var remoteConfigUpdater = options.remoteConfigUpdater ||
61
- (remoteConfigStorageClient && remoteConfigServiceClient
62
- ? new config_1.DefaultRemoteConfigUpdater(config, {
63
- serviceClient: remoteConfigServiceClient,
64
- storageClient: remoteConfigStorageClient,
65
- base64Utils: base64Utils,
66
- hmacUtils: hmacUtils,
67
- })
68
- : null);
69
- var snippetInjector = (_c = options.snippetInjector) !== null && _c !== void 0 ? _c : null;
57
+ var snippetInjector = (_b = options.snippetInjector) !== null && _b !== void 0 ? _b : null;
70
58
  var snippetRetriever = options.snippetRetriever || (snippetInjector ? new snippet_injection_1.DefaultSnippetRetriever(config) : null);
71
- var allOptions = {
72
- httpClient: httpClient,
73
- base64Utils: base64Utils,
74
- hmacUtils: hmacUtils,
75
- hashUtils: hashUtils,
76
- urlUtils: urlUtils,
77
- ipRangeChecker: ipRangeChecker,
78
- cipherUtils: cipherUtils,
79
- cors: cors,
80
- telemetry: telemetry,
81
- dataEnrichment: dataEnrichment,
82
- graphQLParser: graphQLParser,
83
- tokenParser: tokenParser,
84
- riskApiClient: riskApiClient,
85
- activityClient: activityClient,
86
- logServiceClient: logServiceClient,
87
- remoteConfigStorageClient: remoteConfigStorageClient,
88
- remoteConfigServiceClient: remoteConfigServiceClient,
89
- remoteConfigUpdater: remoteConfigUpdater,
90
- snippetInjector: snippetInjector,
91
- snippetRetriever: snippetRetriever,
92
- };
59
+ var remoteConfigClients = (0, exports.createRemoteConfigClients)(config, options);
60
+ var allOptions = __assign({ httpClient: httpClient, base64Utils: base64Utils, hmacUtils: hmacUtils, hashUtils: hashUtils, urlUtils: urlUtils, ipRangeChecker: ipRangeChecker, cipherUtils: cipherUtils, cors: cors, telemetry: telemetry, dataEnrichment: dataEnrichment, graphQLParser: graphQLParser, tokenParser: tokenParser, riskApiClient: riskApiClient, activityClient: activityClient, logServiceClient: logServiceClient, snippetInjector: snippetInjector, snippetRetriever: snippetRetriever }, remoteConfigClients);
93
61
  var products = (0, exports.createEnforcerProducts)(config, options.products, base64Utils, hashUtils, urlUtils, ipRangeChecker);
94
62
  return __assign({ products: products }, allOptions);
95
63
  };
@@ -111,3 +79,31 @@ var createEnforcerProducts = function (config, products, base64Utils, hashUtils,
111
79
  _a;
112
80
  };
113
81
  exports.createEnforcerProducts = createEnforcerProducts;
82
+ var createRemoteConfigClients = function (config, options) {
83
+ var _a, _b, _c, _d;
84
+ var remoteConfigStorageClient = (_a = options.remoteConfigStorageClient) !== null && _a !== void 0 ? _a : null;
85
+ var remoteConfigServiceClient = null;
86
+ var remoteConfigManager = null;
87
+ var remoteConfigUpdateParser = null;
88
+ if (remoteConfigStorageClient) {
89
+ remoteConfigServiceClient =
90
+ (_b = options.remoteConfigServiceClient) !== null && _b !== void 0 ? _b : new config_1.HttpRemoteConfigServiceClient(config, options.httpClient);
91
+ remoteConfigManager =
92
+ (_c = options.remoteConfigManager) !== null && _c !== void 0 ? _c : new config_1.DefaultRemoteConfigManager(config, {
93
+ serviceClient: remoteConfigServiceClient,
94
+ storageClient: remoteConfigStorageClient,
95
+ });
96
+ remoteConfigUpdateParser =
97
+ (_d = options.remoteConfigUpdateParser) !== null && _d !== void 0 ? _d : new config_1.DefaultNotifyRemoteConfigUpdateParser(config, {
98
+ base64Utils: options.base64Utils,
99
+ hmacUtils: options.hmacUtils,
100
+ });
101
+ }
102
+ return {
103
+ remoteConfigServiceClient: remoteConfigServiceClient,
104
+ remoteConfigManager: remoteConfigManager,
105
+ remoteConfigUpdateParser: remoteConfigUpdateParser,
106
+ remoteConfigStorageClient: remoteConfigStorageClient,
107
+ };
108
+ };
109
+ exports.createRemoteConfigClients = createRemoteConfigClients;
@@ -17,16 +17,18 @@ var __extends = (this && this.__extends) || (function () {
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.EndEnforcerFlow = void 0;
19
19
  var impl_1 = require("../impl/index.js");
20
- var impl_2 = require("../impl/index.js");
21
20
  var EndEnforcerFlow = /** @class */ (function (_super) {
22
21
  __extends(EndEnforcerFlow, _super);
23
22
  function EndEnforcerFlow(config, _a) {
24
- var logServiceClient = _a.logServiceClient, telemetry = _a.telemetry;
25
- var phases = [new impl_2.SendTelemetryActivityPhase(telemetry)];
23
+ var logServiceClient = _a.logServiceClient, telemetry = _a.telemetry, remoteConfigManager = _a.remoteConfigManager;
24
+ var phases = [new impl_1.SendTelemetryActivityPhase(telemetry)];
25
+ if (remoteConfigManager) {
26
+ phases.push(new impl_1.UpdateRemoteConfigPhase(config, remoteConfigManager));
27
+ }
26
28
  if (logServiceClient) {
27
29
  phases.push(new impl_1.SendLogsPhase(config, logServiceClient));
28
30
  }
29
- phases.push(new impl_2.ClearLogsPhase());
31
+ phases.push(new impl_1.ClearLogsPhase());
30
32
  return _super.call(this, phases) || this;
31
33
  }
32
34
  return EndEnforcerFlow;
@@ -22,7 +22,7 @@ var impl_1 = require("../impl/index.js");
22
22
  var FilterFlow = /** @class */ (function (_super) {
23
23
  __extends(FilterFlow, _super);
24
24
  function FilterFlow(config, _a) {
25
- var httpClient = _a.httpClient, products = _a.products, cors = _a.cors, telemetry = _a.telemetry, remoteConfigUpdater = _a.remoteConfigUpdater;
25
+ var httpClient = _a.httpClient, products = _a.products, cors = _a.cors, telemetry = _a.telemetry, remoteConfigUpdateParser = _a.remoteConfigUpdateParser;
26
26
  var phases = [];
27
27
  var firstPartyProducts = FilterFlow.getFirstPartyProducts(products);
28
28
  if ((firstPartyProducts === null || firstPartyProducts === void 0 ? void 0 : firstPartyProducts.length) > 0) {
@@ -34,9 +34,8 @@ var FilterFlow = /** @class */ (function (_super) {
34
34
  }
35
35
  phases.push(new impl_1.PreflightPhase(config, cors));
36
36
  phases.push(new impl_1.IdentifyTelemetryRequestPhase(telemetry));
37
- if (remoteConfigUpdater) {
38
- var updateRemoteConfigPhase = new impl_1.UpdateRemoteConfigPhase(config, remoteConfigUpdater);
39
- phases.push(updateRemoteConfigPhase);
37
+ if (remoteConfigUpdateParser) {
38
+ phases.push(new impl_1.IdentifyRemoteConfigNotifyRequestPhase(remoteConfigUpdateParser));
40
39
  }
41
40
  return _super.call(this, phases) || this;
42
41
  }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.IdentifyRemoteConfigNotifyRequestPhase = void 0;
40
+ var http_1 = require("../../http/index.js");
41
+ var IdentifyRemoteConfigNotifyRequestPhase = /** @class */ (function () {
42
+ function IdentifyRemoteConfigNotifyRequestPhase(remoteConfigUpdateParser) {
43
+ this.remoteConfigUpdateParser = remoteConfigUpdateParser;
44
+ }
45
+ IdentifyRemoteConfigNotifyRequestPhase.prototype.execute = function (context) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var _a, shouldUpdate, desiredVersion;
48
+ return __generator(this, function (_b) {
49
+ switch (_b.label) {
50
+ case 0: return [4 /*yield*/, this.remoteConfigUpdateParser.isUpdateRequest(context)];
51
+ case 1:
52
+ if (!(_b.sent())) {
53
+ return [2 /*return*/, { done: false }];
54
+ }
55
+ context.shouldSendLogs = true;
56
+ return [4 /*yield*/, this.remoteConfigUpdateParser.parseUpdate(context)];
57
+ case 2:
58
+ _a = _b.sent(), shouldUpdate = _a.shouldUpdate, desiredVersion = _a.desiredVersion;
59
+ context.remoteConfigUpdateData.shouldUpdate = shouldUpdate;
60
+ context.remoteConfigUpdateData.desiredVersion = desiredVersion;
61
+ return [2 /*return*/, {
62
+ done: true,
63
+ response: new http_1.MinimalResponseImpl({
64
+ status: shouldUpdate ? 200 : 400,
65
+ body: shouldUpdate ? 'OK' : 'Bad Request',
66
+ headers: {},
67
+ }),
68
+ }];
69
+ }
70
+ });
71
+ });
72
+ };
73
+ return IdentifyRemoteConfigNotifyRequestPhase;
74
+ }());
75
+ exports.IdentifyRemoteConfigNotifyRequestPhase = IdentifyRemoteConfigNotifyRequestPhase;
@@ -38,33 +38,26 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.UpdateRemoteConfigPhase = void 0;
40
40
  var UpdateRemoteConfigPhase = /** @class */ (function () {
41
- function UpdateRemoteConfigPhase(config, remoteConfigUpdater) {
41
+ function UpdateRemoteConfigPhase(config, remoteConfigManager) {
42
42
  this.config = config;
43
- this.remoteConfigUpdater = remoteConfigUpdater;
43
+ this.remoteConfigManager = remoteConfigManager;
44
44
  }
45
45
  UpdateRemoteConfigPhase.prototype.execute = function (context) {
46
46
  return __awaiter(this, void 0, void 0, function () {
47
- var isSuccessful;
48
47
  return __generator(this, function (_a) {
49
48
  switch (_a.label) {
50
49
  case 0:
51
- if (!this.remoteConfigUpdater.isUpdateRemoteConfigRequest(context)) return [3 /*break*/, 2];
52
- return [4 /*yield*/, this.remoteConfigUpdater.updateRemoteConfig(context)];
50
+ if (!this.remoteConfigManager.shouldUpdateRemoteConfig(context)) return [3 /*break*/, 2];
51
+ context.shouldSendLogs = true;
52
+ return [4 /*yield*/, this.remoteConfigManager.updateRemoteConfig(context)];
53
53
  case 1:
54
- isSuccessful = _a.sent();
55
- return [2 /*return*/, { done: true, response: this.getUpdateConfigResponse(isSuccessful) }];
54
+ _a.sent();
55
+ _a.label = 2;
56
56
  case 2: return [2 /*return*/, { done: false }];
57
57
  }
58
58
  });
59
59
  });
60
60
  };
61
- UpdateRemoteConfigPhase.prototype.getUpdateConfigResponse = function (isSuccessful) {
62
- return {
63
- status: isSuccessful ? 200 : 400,
64
- body: isSuccessful ? 'OK' : 'Bad Request',
65
- headers: {},
66
- };
67
- };
68
61
  return UpdateRemoteConfigPhase;
69
62
  }());
70
63
  exports.UpdateRemoteConfigPhase = UpdateRemoteConfigPhase;
@@ -30,7 +30,8 @@ __exportStar(require("./SendAsyncActivitiesOnResponsePhase.js"), exports);
30
30
  __exportStar(require("./AdditionalActivityHandlerPhase.js"), exports);
31
31
  __exportStar(require("./CompositePhase.js"), exports);
32
32
  __exportStar(require("./SendLogsPhase.js"), exports);
33
- __exportStar(require("./UpdateRemoteConfigPhase.js"), exports);
34
33
  __exportStar(require("./ClearLogsPhase.js"), exports);
34
+ __exportStar(require("./IdentifyRemoteConfigNotifyRequestPhase.js"), exports);
35
+ __exportStar(require("./UpdateRemoteConfigPhase.js"), exports);
35
36
  __exportStar(require("./IdentifyTelemetryRequestPhase.js"), exports);
36
37
  __exportStar(require("./SendTelemetryActivityPhase.js"), exports);
@@ -14,4 +14,4 @@ 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
15
  exports.URL_REGEX = /^(https?:)\/\/(([^@\s:\/]+):?([^@\s\/]*)@)?(([^:\/?#]*)(?:\:([0-9]+))?)(\/?[^?#]*)(\?[^#]*|)(#.*|)$/;
16
16
  exports.REGEX_STRUCTURE = /^\/(.+?)\/([gimsuyvd]*)$/;
17
- exports.CORE_MODULE_VERSION = 'JS Core 0.24.4';
17
+ exports.CORE_MODULE_VERSION = 'JS Core 0.25.0';
@@ -6,7 +6,7 @@ import { TokenVersion } from '../risk_token/index.js';
6
6
  export class ConfigurationBase {
7
7
  configParams;
8
8
  staticConfigParams;
9
- remoteConfigParams;
9
+ remoteConfigData;
10
10
  defaultConfigParams;
11
11
  removedParams;
12
12
  // Logger is initialized at `createActiveConfiguration`
@@ -75,15 +75,15 @@ export class ConfigurationBase {
75
75
  }
76
76
  }
77
77
  createInternalLogger(params) {
78
- return new DefaultLogger(params.px_logger_severity, false);
78
+ return new DefaultLogger(params.px_logger_severity, false, this.logger?.getLogs());
79
79
  }
80
- addRemoteConfig(remoteConfigParams) {
81
- this.remoteConfigParams = remoteConfigParams;
82
- const mergedParams = {
80
+ setRemoteConfigData(remoteConfigData) {
81
+ this.remoteConfigData = remoteConfigData;
82
+ const params = {
83
83
  ...this.staticConfigParams,
84
- ...RemoteConfigUtils.prepareRemoteConfigParams(remoteConfigParams, this.logger),
84
+ ...RemoteConfigUtils.prepareRemoteConfigParams(remoteConfigData, this.logger),
85
85
  };
86
- this.configParams = this.createActiveConfiguration(mergedParams, this.defaultConfigParams);
86
+ this.configParams = this.createActiveConfiguration(params, this.defaultConfigParams);
87
87
  }
88
88
  getActiveConfig() {
89
89
  const activeConfig = Object.assign({}, this.configParams);
@@ -97,7 +97,9 @@ export class ConfigurationBase {
97
97
  return Object.assign({}, this.staticConfigParams);
98
98
  }
99
99
  getRemoteConfig() {
100
- return Object.assign({}, this.remoteConfigParams);
100
+ return this.remoteConfigData
101
+ ? RemoteConfigUtils.prepareRemoteConfigParams(this.remoteConfigData, this.logger)
102
+ : {};
101
103
  }
102
104
  get moduleVersion() {
103
105
  return `${this.getModuleVersion()} (${CORE_MODULE_VERSION})`;
@@ -1,6 +1,5 @@
1
1
  export * from './IConfiguration.js';
2
2
  export * from './ConfigurationBase.js';
3
- export * from './ConfigurationBuilderBase.js';
4
3
  export * from './CustomRequestFunction.js';
5
4
  export * from './remote_config/index.js';
6
5
  export * from './params/index.js';
@@ -6,8 +6,17 @@ export var RemoteConfigUtils;
6
6
  RemoteConfigUtils.isRemoteConfigUpdateRequest = (request) => request.method === HttpMethod.POST &&
7
7
  request.headers.get(PUSH_DATA_FEATURE_HEADER_NAME) === REMOTE_CONFIG_PUSH_DATA_FEATURE_NAME &&
8
8
  !!request.headers.get(PUSH_DATA_HMAC_HEADER_NAME);
9
- RemoteConfigUtils.prepareRemoteConfigParams = (remoteConfigParams, logger) => {
10
- const remoteConfig = Object.assign({}, remoteConfigParams);
9
+ RemoteConfigUtils.prepareRemoteConfigParams = ({ version, configValue }, logger) => {
10
+ const remoteConfig = {
11
+ px_remote_config_version: version,
12
+ px_remote_config_enabled: configValue.px_remote_config_enabled,
13
+ };
14
+ if (!configValue.px_remote_config_enabled) {
15
+ // returning only the version and the fact that remote config is disabled
16
+ // so we can report the version on async activities without merging the rest of the remote configs
17
+ return remoteConfig;
18
+ }
19
+ Object.assign(remoteConfig, configValue);
11
20
  // Remote config receives strings and regexes in separate fields (px_sensitive_routes, px_sensitive_routes_regex)
12
21
  // Before initializing a new active configuration, we merge the two into the more generic field (px_sensitive_routes)
13
22
  CONFIG_KEYS_WITH_REGEX_EQUIVALENT_IN_REMOTE_CONFIG.forEach((k) => {
@@ -2,6 +2,6 @@ export * from './constants.js';
2
2
  export * from './model/index.js';
3
3
  export * from './service_client/index.js';
4
4
  export * from './storage_client/index.js';
5
- export * from './DefaultRemoteConfigUpdater.js';
6
- export * from './IRemoteConfigUpdater.js';
5
+ export * from './manager/index.js';
6
+ export * from './update_parser/index.js';
7
7
  export * from './RemoteConfigUtils.js';
@@ -0,0 +1,87 @@
1
+ import { sleep } from '../../../utils/index.js';
2
+ import { WRITE_REMOTE_CONFIG_ERROR_NAME } from '../constants.js';
3
+ export class DefaultRemoteConfigManager {
4
+ config;
5
+ serviceClient;
6
+ storageClient;
7
+ constructor(config, options) {
8
+ this.config = config;
9
+ this.serviceClient = options.serviceClient;
10
+ this.storageClient = options.storageClient;
11
+ }
12
+ async loadRemoteConfig() {
13
+ if (!this.config.remoteConfigId || !this.config.remoteConfigAuthToken) {
14
+ this.config.logger.debug('no remote config id or auth token provided, skipping remote config load');
15
+ return;
16
+ }
17
+ try {
18
+ const remoteConfigData = await this.loadRemoteConfigData();
19
+ if (!!remoteConfigData?.version && remoteConfigData.version > this.config.remoteConfigVersion) {
20
+ this.config.setRemoteConfigData(remoteConfigData);
21
+ }
22
+ }
23
+ catch (e) {
24
+ this.config.logger.debug(`caught error loading remote config: ${e}`);
25
+ }
26
+ }
27
+ async loadRemoteConfigData() {
28
+ const remoteConfigData = await this.storageClient.load();
29
+ if (!remoteConfigData) {
30
+ this.config.logger.debug('unable to load remote config from storage');
31
+ return null;
32
+ }
33
+ if (!this.isValidRemoteConfigId(remoteConfigData.id)) {
34
+ this.config.logger.debug(`remote config ID in static config does not match ID found in storage ${remoteConfigData.id}`);
35
+ return null;
36
+ }
37
+ return remoteConfigData;
38
+ }
39
+ isValidRemoteConfigId(remoteConfigId) {
40
+ return remoteConfigId === this.config.remoteConfigId;
41
+ }
42
+ shouldUpdateRemoteConfig(context) {
43
+ return context.remoteConfigUpdateData.shouldUpdate;
44
+ }
45
+ async updateRemoteConfig(context) {
46
+ const desiredVersion = context.remoteConfigUpdateData.desiredVersion ?? 0;
47
+ const remoteConfigData = await this.fetchRemoteConfigData(desiredVersion, context);
48
+ if (!remoteConfigData) {
49
+ return;
50
+ }
51
+ try {
52
+ await this.storageClient.save(remoteConfigData);
53
+ context.logger.debug(`successfully updated remote config to version ${remoteConfigData.version}`);
54
+ }
55
+ catch (e) {
56
+ context.logger.debug(`unable to save remote config version ${remoteConfigData.version} to storage: ${e}`, {
57
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
58
+ });
59
+ }
60
+ }
61
+ async fetchRemoteConfigData(desiredVersion, context) {
62
+ try {
63
+ const { remoteConfigMaxFetchAttempts, remoteConfigRetryIntervalMs } = this.config;
64
+ for (let i = 0; i < remoteConfigMaxFetchAttempts; i++) {
65
+ const remoteConfigData = await this.serviceClient.fetch({ version: desiredVersion });
66
+ if (!!remoteConfigData && remoteConfigData.version >= desiredVersion) {
67
+ return remoteConfigData;
68
+ }
69
+ else {
70
+ await this.sleepBetweenFetchAttempts(remoteConfigRetryIntervalMs);
71
+ }
72
+ }
73
+ context.logger.debug(`unable to fetch remote config version ${desiredVersion} or higher: reached ${remoteConfigMaxFetchAttempts} fetch attempts`, {
74
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
75
+ });
76
+ }
77
+ catch (e) {
78
+ context.logger.debug(`unable to fetch remote config version ${desiredVersion} or higher: ${e}`, {
79
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
80
+ });
81
+ }
82
+ return null;
83
+ }
84
+ async sleepBetweenFetchAttempts(ms) {
85
+ await sleep(ms);
86
+ }
87
+ }
@@ -0,0 +1,2 @@
1
+ export * from './IRemoteConfigManager.js';
2
+ export * from './DefaultRemoteConfigManager.js';
@@ -1,2 +1,2 @@
1
1
  export * from './RemoteConfigData.js';
2
- export * from './RemoteConfigUpdateRequestData.js';
2
+ export * from './RemoteConfigNotifyRequestPayload.js';
@@ -0,0 +1,60 @@
1
+ import { DefaultTimestampHmacHeaderValidator, PUSH_DATA_FEATURE_HEADER_NAME, PUSH_DATA_HMAC_HEADER_NAME, } from '../../../utils/index.js';
2
+ import { REMOTE_CONFIG_PUSH_DATA_FEATURE_NAME, WRITE_REMOTE_CONFIG_ERROR_NAME } from '../constants.js';
3
+ import { HttpMethod } from '../../../http/index.js';
4
+ export class DefaultNotifyRemoteConfigUpdateParser {
5
+ config;
6
+ timestampHmacHeaderValidator;
7
+ constructor(config, options) {
8
+ this.config = config;
9
+ this.timestampHmacHeaderValidator =
10
+ options.timestampHmacHeaderValidator ??
11
+ new DefaultTimestampHmacHeaderValidator(config, config.remoteConfigAuthToken, options.base64Utils, options.hmacUtils);
12
+ }
13
+ async isUpdateRequest({ requestData: { request } }) {
14
+ return (request.method === HttpMethod.POST &&
15
+ request.headers.get(PUSH_DATA_FEATURE_HEADER_NAME) === REMOTE_CONFIG_PUSH_DATA_FEATURE_NAME &&
16
+ !!request.headers.get(PUSH_DATA_HMAC_HEADER_NAME));
17
+ }
18
+ async parseUpdate(context) {
19
+ if (!(await this.isNotifyRequestValid(context))) {
20
+ return { shouldUpdate: false };
21
+ }
22
+ const updateData = { shouldUpdate: true };
23
+ const desiredVersion = await this.getDesiredRemoteConfigVersion(context);
24
+ context.logger.debug(`got notify request for remote config version ${desiredVersion}`);
25
+ if (desiredVersion) {
26
+ updateData.desiredVersion = desiredVersion;
27
+ }
28
+ return updateData;
29
+ }
30
+ async isNotifyRequestValid(context) {
31
+ const timestampHmacHeader = context.requestData.request.headers.get(PUSH_DATA_HMAC_HEADER_NAME);
32
+ const isValid = !!timestampHmacHeader &&
33
+ (await this.timestampHmacHeaderValidator.isValid(timestampHmacHeader, context.logger));
34
+ if (!isValid) {
35
+ context.logger.debug(`invalid remote config notify request hmac header received: ${timestampHmacHeader}`, {
36
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
37
+ });
38
+ }
39
+ return isValid;
40
+ }
41
+ async getDesiredRemoteConfigVersion(context) {
42
+ let notifyRequestPayload;
43
+ try {
44
+ notifyRequestPayload = await context.requestData.request.json();
45
+ }
46
+ catch (e) {
47
+ context.logger.debug(`could not parse update request body: ${e}`, {
48
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
49
+ });
50
+ return null;
51
+ }
52
+ if (!notifyRequestPayload?.version) {
53
+ context.logger.debug(`no version on update request body: ${notifyRequestPayload}`, {
54
+ errorType: WRITE_REMOTE_CONFIG_ERROR_NAME,
55
+ });
56
+ return null;
57
+ }
58
+ return notifyRequestPayload.version;
59
+ }
60
+ }
@@ -0,0 +1,2 @@
1
+ export * from './DefaultNotifyRemoteConfigUpdateParser.js';
2
+ export * from './IRemoteConfigUpdateParser.js';
@@ -1,4 +1,3 @@
1
- import { RemoteConfigUtils } from '../config/index.js';
2
1
  import { BlockAction } from '../blocker/index.js';
3
2
  import { PXHDSource } from '../pxhd/index.js';
4
3
  import { TokenOrigin, TokenParseResult } from '../risk_token/index.js';
@@ -10,8 +9,7 @@ import { DefaultLogger, X_PX_ENFORCER_LOG_HEADER } from '../logger/index.js';
10
9
  export class DefaultContext {
11
10
  requestId;
12
11
  tokenOrigin;
13
- isRemoteConfigUpdateRequest;
14
- shouldSendLogs;
12
+ remoteConfigUpdateData;
15
13
  requestData;
16
14
  tokenData;
17
15
  riskApiData;
@@ -35,6 +33,7 @@ export class DefaultContext {
35
33
  logger;
36
34
  usedCookieSecret;
37
35
  shouldSendTelemetry;
36
+ _shouldSendLogs = false;
38
37
  config;
39
38
  urlUtils;
40
39
  constructor(config, request, options) {
@@ -55,8 +54,10 @@ export class DefaultContext {
55
54
  this.pxdeVerified = false;
56
55
  this.action = Action.TRIGGER_RISK_API;
57
56
  this.reasons = {};
58
- this.isRemoteConfigUpdateRequest = RemoteConfigUtils.isRemoteConfigUpdateRequest(request);
59
- this.shouldSendLogs = this.isRemoteConfigUpdateRequest || this.isHeaderBasedLoggerRequest(config, request);
57
+ this.remoteConfigUpdateData = {
58
+ shouldUpdate: false,
59
+ };
60
+ this.shouldSendLogs = this.isHeaderBasedLoggerRequest(config, request);
60
61
  this.logger = this.createContextLogger(config, this.shouldSendLogs);
61
62
  this.requestData = this.createRequestData(config, request, options.cookieParser);
62
63
  this.tokenOrigin = this.getTokenOrigin(request);
@@ -65,6 +66,18 @@ export class DefaultContext {
65
66
  }
66
67
  this.shouldSendTelemetry = false;
67
68
  }
69
+ get shouldSendLogs() {
70
+ return this._shouldSendLogs;
71
+ }
72
+ set shouldSendLogs(shouldSendLogs) {
73
+ if (this._shouldSendLogs === shouldSendLogs) {
74
+ return;
75
+ }
76
+ this._shouldSendLogs = shouldSendLogs;
77
+ if (this.logger) {
78
+ this.logger.shouldSaveLogs = shouldSendLogs;
79
+ }
80
+ }
68
81
  get isMobile() {
69
82
  return this.tokenOrigin === TokenOrigin.HEADER;
70
83
  }
@@ -152,7 +165,7 @@ export class DefaultContext {
152
165
  action: this.action,
153
166
  reasons: this.reasons,
154
167
  isMobile: this.isMobile,
155
- isRemoteConfigUpdateRequest: this.isRemoteConfigUpdateRequest,
168
+ remoteConfigUpdateData: this.remoteConfigUpdateData,
156
169
  productData: this.productData,
157
170
  requestData: {
158
171
  ...this.requestData,
@@ -3,7 +3,7 @@ import { SerializedToken } from '../risk_token/index.js';
3
3
  import { SerializedRiskResponse } from '../risk_api/index.js';
4
4
  export class SerializedContext {
5
5
  isMobile;
6
- isRemoteConfigUpdateRequest;
6
+ remoteConfigUpdateData;
7
7
  logger;
8
8
  productData;
9
9
  requestData;
@@ -33,7 +33,7 @@ export class SerializedContext {
33
33
  this.reasons = contextJson.reasons;
34
34
  this.isMobile = contextJson.isMobile;
35
35
  this.requestId = contextJson.requestId;
36
- this.isRemoteConfigUpdateRequest = contextJson.isRemoteConfigUpdateRequest;
36
+ this.remoteConfigUpdateData = contextJson.remoteConfigUpdateData;
37
37
  this.logger = this.createLogger(config, contextJson.shouldSendLogs, contextJson.logger?.logs);
38
38
  this.productData = contextJson.productData;
39
39
  this.requestData = this.createRequestData(contextJson, request, urlUtils);
@@ -4,5 +4,6 @@ export * from './MobileData.js';
4
4
  export * from './TokenData.js';
5
5
  export * from './TlsData.js';
6
6
  export * from './ServerData.js';
7
+ export * from './RemoteConfigUpdateData.js';
7
8
  export * from './IContext.js';
8
9
  export * from './ReadonlyContext.js';
@@ -7,6 +7,7 @@ export class EnforcerBase {
7
7
  postEnforceFlow;
8
8
  endEnforcerFlow;
9
9
  activityClient;
10
+ remoteConfigManager;
10
11
  /**
11
12
  * The EnforcerBase constructor.
12
13
  * @param config - The enforcer configuration.
@@ -17,6 +18,7 @@ export class EnforcerBase {
17
18
  this.config = config;
18
19
  const initializationBlock = createEnforcerInitializationBlock(config, options);
19
20
  this.activityClient = initializationBlock.activityClient;
21
+ this.remoteConfigManager = initializationBlock.remoteConfigManager;
20
22
  this.filterFlow = this.createFilterFlow(config, initializationBlock);
21
23
  this.enforceFlow = this.createEnforceFlow(config, initializationBlock);
22
24
  this.postEnforceFlow = this.createPostEnforceFlow(config, initializationBlock);
@@ -43,6 +45,7 @@ export class EnforcerBase {
43
45
  * @returns Promise<Res|null> - A Promise resolving to a Res or null depending on the action that should be taken.
44
46
  */
45
47
  async enforce(...args) {
48
+ await this.remoteConfigManager?.loadRemoteConfig();
46
49
  let context;
47
50
  try {
48
51
  if (!this.config.moduleEnabled) {