perimeterx-js-core 0.23.1 → 0.23.3
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/lib/cjs/context/DefaultContext.js +5 -0
- package/lib/cjs/context/SerializedContext.js +4 -3
- package/lib/cjs/graphql/DefaultGraphQLParser.js +1 -1
- package/lib/cjs/logger/DefaultLogger.js +2 -2
- package/lib/cjs/monitored_request/MonitoredRequestUtils.js +2 -2
- package/lib/cjs/products/bot_defender/filter/DefaultBotDefenderFilter.js +2 -2
- package/lib/cjs/sensitive_request/SensitiveRequestUtils.js +1 -1
- package/lib/cjs/utils/constants.js +2 -2
- package/lib/cjs/utils/error/EnforcerConfigurationError.js +8 -1
- package/lib/cjs/utils/utils.js +30 -14
- package/lib/esm/context/DefaultContext.js +5 -0
- package/lib/esm/context/SerializedContext.js +3 -3
- package/lib/esm/graphql/DefaultGraphQLParser.js +2 -2
- package/lib/esm/logger/DefaultLogger.js +2 -2
- package/lib/esm/monitored_request/MonitoredRequestUtils.js +3 -3
- package/lib/esm/products/bot_defender/filter/DefaultBotDefenderFilter.js +3 -3
- package/lib/esm/sensitive_request/SensitiveRequestUtils.js +2 -2
- package/lib/esm/utils/constants.js +2 -2
- package/lib/esm/utils/error/EnforcerConfigurationError.js +8 -1
- package/lib/esm/utils/utils.js +27 -11
- package/lib/types/config/ConfigurationBase.d.ts +1 -1
- package/lib/types/config/IConfiguration.d.ts +1 -1
- package/lib/types/config/params/CoreConfigurationParams.d.ts +1 -1
- package/lib/types/context/ContextJson.d.ts +4 -0
- package/lib/types/context/SerializedContext.d.ts +2 -2
- package/lib/types/logger/DefaultLogger.d.ts +2 -1
- package/lib/types/utils/constants.d.ts +1 -1
- package/lib/types/utils/utils.d.ts +2 -2
- package/package.json +1 -1
|
@@ -165,6 +165,11 @@ var DefaultContext = /** @class */ (function () {
|
|
|
165
165
|
enforcerStartTime: this.enforcerStartTime,
|
|
166
166
|
blockAction: this.blockAction,
|
|
167
167
|
pxdeVerified: this.pxdeVerified,
|
|
168
|
+
logger: this.shouldSendLogs
|
|
169
|
+
? {
|
|
170
|
+
logs: this.logger.getLogs(),
|
|
171
|
+
}
|
|
172
|
+
: undefined,
|
|
168
173
|
};
|
|
169
174
|
};
|
|
170
175
|
return DefaultContext;
|
|
@@ -17,12 +17,13 @@ var risk_token_1 = require("../risk_token");
|
|
|
17
17
|
var risk_api_1 = require("../risk_api");
|
|
18
18
|
var SerializedContext = /** @class */ (function () {
|
|
19
19
|
function SerializedContext(config, contextJson, request, urlUtils) {
|
|
20
|
+
var _a;
|
|
20
21
|
this.action = contextJson.action;
|
|
21
22
|
this.reasons = contextJson.reasons;
|
|
22
23
|
this.isMobile = contextJson.isMobile;
|
|
23
24
|
this.requestId = contextJson.requestId;
|
|
24
25
|
this.isRemoteConfigUpdateRequest = contextJson.isRemoteConfigUpdateRequest;
|
|
25
|
-
this.logger = this.createLogger(config, contextJson.shouldSendLogs);
|
|
26
|
+
this.logger = this.createLogger(config, contextJson.shouldSendLogs, (_a = contextJson.logger) === null || _a === void 0 ? void 0 : _a.logs);
|
|
26
27
|
this.productData = contextJson.productData;
|
|
27
28
|
this.requestData = this.createRequestData(contextJson, request, urlUtils);
|
|
28
29
|
this.riskApiData = this.createRiskApiData(contextJson);
|
|
@@ -58,8 +59,8 @@ var SerializedContext = /** @class */ (function () {
|
|
|
58
59
|
var riskApiData = _a.riskApiData;
|
|
59
60
|
return __assign(__assign({}, riskApiData), { riskResponse: riskApiData.riskResponse ? new risk_api_1.SerializedRiskResponse(riskApiData.riskResponse) : undefined });
|
|
60
61
|
};
|
|
61
|
-
SerializedContext.prototype.createLogger = function (config, shouldSendLogs) {
|
|
62
|
-
return new logger_1.DefaultLogger(config.loggerSeverity, shouldSendLogs);
|
|
62
|
+
SerializedContext.prototype.createLogger = function (config, shouldSendLogs, logs) {
|
|
63
|
+
return new logger_1.DefaultLogger(config.loggerSeverity, shouldSendLogs, logs);
|
|
63
64
|
};
|
|
64
65
|
return SerializedContext;
|
|
65
66
|
}());
|
|
@@ -49,7 +49,7 @@ var DefaultGraphQLParser = /** @class */ (function () {
|
|
|
49
49
|
DefaultGraphQLParser.prototype.isGraphQLRequest = function (_a) {
|
|
50
50
|
var requestData = _a.requestData;
|
|
51
51
|
return (requestData.method === http_1.HttpMethod.POST &&
|
|
52
|
-
(0, utils_1.
|
|
52
|
+
(0, utils_1.isStringInPatterns)(requestData.url.pathname, this.config.graphqlRoutes));
|
|
53
53
|
};
|
|
54
54
|
DefaultGraphQLParser.prototype.parseGraphQLRequest = function (context) {
|
|
55
55
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -19,8 +19,8 @@ exports.DefaultLogger = void 0;
|
|
|
19
19
|
var LoggerBase_1 = require("./LoggerBase");
|
|
20
20
|
var DefaultLogger = /** @class */ (function (_super) {
|
|
21
21
|
__extends(DefaultLogger, _super);
|
|
22
|
-
function DefaultLogger(loggerSeverity, shouldSaveLogs) {
|
|
23
|
-
return _super.call(this, loggerSeverity, shouldSaveLogs) || this;
|
|
22
|
+
function DefaultLogger(loggerSeverity, shouldSaveLogs, logs) {
|
|
23
|
+
return _super.call(this, loggerSeverity, shouldSaveLogs, logs) || this;
|
|
24
24
|
}
|
|
25
25
|
DefaultLogger.prototype.log = function (message) {
|
|
26
26
|
/* eslint-disable no-console */
|
|
@@ -74,10 +74,10 @@ var MonitoredRequestUtils;
|
|
|
74
74
|
});
|
|
75
75
|
}); };
|
|
76
76
|
MonitoredRequestUtils.isMonitoredRoute = function (url, isMonitoredRoute) {
|
|
77
|
-
return (0, utils_1.
|
|
77
|
+
return (0, utils_1.isStringInPatterns)(url.pathname, isMonitoredRoute);
|
|
78
78
|
};
|
|
79
79
|
MonitoredRequestUtils.isEnforcedRoute = function (url, enforcedRoutes) {
|
|
80
|
-
return (0, utils_1.
|
|
80
|
+
return (0, utils_1.isStringInPatterns)(url.pathname, enforcedRoutes);
|
|
81
81
|
};
|
|
82
82
|
MonitoredRequestUtils.invokeCustomIsEnforcedRequest = function (config, context) { return __awaiter(_this, void 0, void 0, function () {
|
|
83
83
|
var err_1;
|
|
@@ -109,10 +109,10 @@ var DefaultBotDefenderFilter = /** @class */ (function () {
|
|
|
109
109
|
return this.config.filteredIps.some(function (range) { return _this.ipRangeChecker.isIpInRange(ip, range); });
|
|
110
110
|
};
|
|
111
111
|
DefaultBotDefenderFilter.prototype.shouldFilterByRoute = function (route) {
|
|
112
|
-
return (0, utils_1.
|
|
112
|
+
return (0, utils_1.isStringInPatterns)(route, this.config.filteredRoutes);
|
|
113
113
|
};
|
|
114
114
|
DefaultBotDefenderFilter.prototype.shouldFilterByUserAgent = function (userAgent) {
|
|
115
|
-
return this.config.filteredUserAgents
|
|
115
|
+
return (0, utils_1.isStringInPatterns)(userAgent, this.config.filteredUserAgents);
|
|
116
116
|
};
|
|
117
117
|
DefaultBotDefenderFilter.prototype.shouldFilterByCustomFunction = function (context) {
|
|
118
118
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -58,7 +58,7 @@ var SensitiveRequestUtils;
|
|
|
58
58
|
});
|
|
59
59
|
}); };
|
|
60
60
|
SensitiveRequestUtils.isSensitiveRoute = function (url, sensitiveRoutes) {
|
|
61
|
-
return (0, utils_1.
|
|
61
|
+
return (0, utils_1.isStringInPatterns)(url.pathname, sensitiveRoutes);
|
|
62
62
|
};
|
|
63
63
|
SensitiveRequestUtils.isSensitiveGraphqlOperation = function (graphQLData) {
|
|
64
64
|
return !!(graphQLData === null || graphQLData === void 0 ? void 0 : graphQLData.some(function (operation) { return operation.sensitive; }));
|
|
@@ -12,6 +12,6 @@ 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
|
|
15
|
+
exports.URL_REGEX = /^(https?:)\/\/(([^@\s:\/]+):?([^@\s\/]*)@)?(([^:\/?#]*)(?:\:([0-9]+))?)(\/?[^?#]*)(\?[^#]*|)(#.*|)$/;
|
|
16
16
|
exports.REGEX_STRUCTURE = /^\/(.+?)\/([gimsuyvd]*)$/;
|
|
17
|
-
exports.CORE_MODULE_VERSION = 'JS Core 0.23.
|
|
17
|
+
exports.CORE_MODULE_VERSION = 'JS Core 0.23.3';
|
|
@@ -22,7 +22,14 @@ var EnforcerConfigurationError = /** @class */ (function (_super) {
|
|
|
22
22
|
__extends(EnforcerConfigurationError, _super);
|
|
23
23
|
function EnforcerConfigurationError(configName, invalidConfigValue, possibleValues) {
|
|
24
24
|
var _this = this;
|
|
25
|
-
var
|
|
25
|
+
var value = invalidConfigValue === null
|
|
26
|
+
? 'null'
|
|
27
|
+
: invalidConfigValue === undefined
|
|
28
|
+
? 'undefined'
|
|
29
|
+
: typeof invalidConfigValue === 'string'
|
|
30
|
+
? "\"".concat(invalidConfigValue, "\"")
|
|
31
|
+
: invalidConfigValue;
|
|
32
|
+
var message = "configuration ".concat(configName, " cannot be type ").concat(typeof invalidConfigValue, " with value ").concat(value);
|
|
26
33
|
if (possibleValues) {
|
|
27
34
|
message += ", possible values: ".concat(possibleValues.join(', '));
|
|
28
35
|
}
|
package/lib/cjs/utils/utils.js
CHANGED
|
@@ -36,7 +36,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.isNullOrUndefined = exports.isValidTokenVersion = exports.telemetryConfigReplacer = exports.convertRegexStringToRegex = exports.algoToCryptoString = exports.algoToSubtleCryptoString = exports.sleep = exports.getPropertyFromObject = exports.rejectOnTimeout = exports.transferExistingProperties = exports.
|
|
39
|
+
exports.isNullOrUndefined = exports.isValidTokenVersion = exports.telemetryConfigReplacer = exports.convertRegexStringToRegex = exports.algoToCryptoString = exports.algoToSubtleCryptoString = exports.sleep = exports.getPropertyFromObject = exports.rejectOnTimeout = exports.transferExistingProperties = exports.isStringMatch = exports.isStringInPatterns = exports.removeSensitiveHeaders = exports.redactSensitiveFields = exports.getExtension = exports.getAuthorizationHeader = exports.getCollectorDomain = exports.getScoreApiDomain = exports.isEmailAddress = exports.isValidUuid = exports.isValidEnumValue = void 0;
|
|
40
40
|
var http_1 = require("../http");
|
|
41
41
|
var error_1 = require("./error");
|
|
42
42
|
var constants_1 = require("./constants");
|
|
@@ -80,21 +80,37 @@ var getExtension = function (route) {
|
|
|
80
80
|
};
|
|
81
81
|
exports.getExtension = getExtension;
|
|
82
82
|
var redactSensitiveFields = function (object, sensitiveFields) {
|
|
83
|
-
var NUMBER_OF_TRAILING_CHARS_TO_EXPOSE = 5;
|
|
84
|
-
var SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS = NUMBER_OF_TRAILING_CHARS_TO_EXPOSE * 10;
|
|
85
83
|
var newObj = Object.assign({}, object);
|
|
86
84
|
sensitiveFields.forEach(function (fieldName) {
|
|
87
85
|
var sensitiveValue = object[fieldName];
|
|
88
86
|
if (!sensitiveValue) {
|
|
89
87
|
return;
|
|
90
88
|
}
|
|
91
|
-
|
|
92
|
-
var trailingChars = sensitiveValue.substring(sensitiveValue.length - (trailingCharsExposed ? NUMBER_OF_TRAILING_CHARS_TO_EXPOSE : 0));
|
|
93
|
-
newObj[fieldName] = "***REDACTED***".concat(trailingChars);
|
|
89
|
+
newObj[fieldName] = redactUnknownValue(sensitiveValue);
|
|
94
90
|
});
|
|
95
91
|
return newObj;
|
|
96
92
|
};
|
|
97
93
|
exports.redactSensitiveFields = redactSensitiveFields;
|
|
94
|
+
var redactUnknownValue = function (value) {
|
|
95
|
+
switch (typeof value) {
|
|
96
|
+
case 'string':
|
|
97
|
+
return redactSensitiveString(value);
|
|
98
|
+
case 'object':
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
return value.flatMap(redactUnknownValue).filter(function (v) { return !(0, exports.isNullOrUndefined)(v); });
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
default:
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var redactSensitiveString = function (sensitiveValue) {
|
|
108
|
+
var NUMBER_OF_TRAILING_CHARS_TO_EXPOSE = 5;
|
|
109
|
+
var SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS = NUMBER_OF_TRAILING_CHARS_TO_EXPOSE * 10;
|
|
110
|
+
var trailingCharsExposed = sensitiveValue.length >= SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS;
|
|
111
|
+
var trailingChars = sensitiveValue.substring(sensitiveValue.length - (trailingCharsExposed ? NUMBER_OF_TRAILING_CHARS_TO_EXPOSE : 0));
|
|
112
|
+
return "***REDACTED***".concat(trailingChars);
|
|
113
|
+
};
|
|
98
114
|
var removeSensitiveHeaders = function (headers, sensitiveHeaderNames) {
|
|
99
115
|
var ret = (0, http_1.toMutableHeaders)(headers);
|
|
100
116
|
sensitiveHeaderNames.forEach(function (name) {
|
|
@@ -103,23 +119,23 @@ var removeSensitiveHeaders = function (headers, sensitiveHeaderNames) {
|
|
|
103
119
|
return ret;
|
|
104
120
|
};
|
|
105
121
|
exports.removeSensitiveHeaders = removeSensitiveHeaders;
|
|
106
|
-
var
|
|
107
|
-
return patterns.some(function (pattern) { return (0, exports.
|
|
122
|
+
var isStringInPatterns = function (str, patterns) {
|
|
123
|
+
return patterns.some(function (pattern) { return (0, exports.isStringMatch)(str, pattern); });
|
|
108
124
|
};
|
|
109
|
-
exports.
|
|
110
|
-
var
|
|
111
|
-
if (!
|
|
125
|
+
exports.isStringInPatterns = isStringInPatterns;
|
|
126
|
+
var isStringMatch = function (str, pattern) {
|
|
127
|
+
if (!str || !pattern) {
|
|
112
128
|
return false;
|
|
113
129
|
}
|
|
114
|
-
if (pattern instanceof RegExp && !!
|
|
130
|
+
if (pattern instanceof RegExp && !!str.match(pattern)) {
|
|
115
131
|
return true;
|
|
116
132
|
}
|
|
117
|
-
if (typeof pattern === 'string' &&
|
|
133
|
+
if (typeof pattern === 'string' && str.startsWith(pattern)) {
|
|
118
134
|
return true;
|
|
119
135
|
}
|
|
120
136
|
return false;
|
|
121
137
|
};
|
|
122
|
-
exports.
|
|
138
|
+
exports.isStringMatch = isStringMatch;
|
|
123
139
|
/**
|
|
124
140
|
* @deprecated this method is not typesafe. Copy the fields manually instead,
|
|
125
141
|
* unsafe - ignores compilerOptions.strictNullChecks
|
|
@@ -175,6 +175,11 @@ export class DefaultContext {
|
|
|
175
175
|
enforcerStartTime: this.enforcerStartTime,
|
|
176
176
|
blockAction: this.blockAction,
|
|
177
177
|
pxdeVerified: this.pxdeVerified,
|
|
178
|
+
logger: this.shouldSendLogs
|
|
179
|
+
? {
|
|
180
|
+
logs: this.logger.getLogs(),
|
|
181
|
+
}
|
|
182
|
+
: undefined,
|
|
178
183
|
};
|
|
179
184
|
}
|
|
180
185
|
}
|
|
@@ -33,7 +33,7 @@ export class SerializedContext {
|
|
|
33
33
|
this.isMobile = contextJson.isMobile;
|
|
34
34
|
this.requestId = contextJson.requestId;
|
|
35
35
|
this.isRemoteConfigUpdateRequest = contextJson.isRemoteConfigUpdateRequest;
|
|
36
|
-
this.logger = this.createLogger(config, contextJson.shouldSendLogs);
|
|
36
|
+
this.logger = this.createLogger(config, contextJson.shouldSendLogs, contextJson.logger?.logs);
|
|
37
37
|
this.productData = contextJson.productData;
|
|
38
38
|
this.requestData = this.createRequestData(contextJson, request, urlUtils);
|
|
39
39
|
this.riskApiData = this.createRiskApiData(contextJson);
|
|
@@ -81,7 +81,7 @@ export class SerializedContext {
|
|
|
81
81
|
riskResponse: riskApiData.riskResponse ? new SerializedRiskResponse(riskApiData.riskResponse) : undefined,
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
createLogger(config, shouldSendLogs) {
|
|
85
|
-
return new DefaultLogger(config.loggerSeverity, shouldSendLogs);
|
|
84
|
+
createLogger(config, shouldSendLogs, logs) {
|
|
85
|
+
return new DefaultLogger(config.loggerSeverity, shouldSendLogs, logs);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNullOrUndefined,
|
|
1
|
+
import { isNullOrUndefined, isStringInPatterns } from '../utils';
|
|
2
2
|
import { HttpMethod } from '../http';
|
|
3
3
|
import { GraphQLOperationType } from './model';
|
|
4
4
|
export class DefaultGraphQLParser {
|
|
@@ -12,7 +12,7 @@ export class DefaultGraphQLParser {
|
|
|
12
12
|
}
|
|
13
13
|
isGraphQLRequest({ requestData }) {
|
|
14
14
|
return (requestData.method === HttpMethod.POST &&
|
|
15
|
-
|
|
15
|
+
isStringInPatterns(requestData.url.pathname, this.config.graphqlRoutes));
|
|
16
16
|
}
|
|
17
17
|
async parseGraphQLRequest(context) {
|
|
18
18
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LoggerBase } from './LoggerBase';
|
|
2
2
|
export class DefaultLogger extends LoggerBase {
|
|
3
|
-
constructor(loggerSeverity, shouldSaveLogs) {
|
|
4
|
-
super(loggerSeverity, shouldSaveLogs);
|
|
3
|
+
constructor(loggerSeverity, shouldSaveLogs, logs) {
|
|
4
|
+
super(loggerSeverity, shouldSaveLogs, logs);
|
|
5
5
|
}
|
|
6
6
|
log(message) {
|
|
7
7
|
/* eslint-disable no-console */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BYPASS_MONITOR_HEADER_VALUE,
|
|
1
|
+
import { BYPASS_MONITOR_HEADER_VALUE, isStringInPatterns, ModuleMode } from '../utils';
|
|
2
2
|
export var MonitoredRequestUtils;
|
|
3
3
|
(function (MonitoredRequestUtils) {
|
|
4
4
|
MonitoredRequestUtils.isMonitoredRequest = async (config, context) => {
|
|
@@ -10,10 +10,10 @@ export var MonitoredRequestUtils;
|
|
|
10
10
|
return (monitorMode || monitoredRoute) && !MonitoredRequestUtils.isAllowedToBypassMonitor(config.bypassMonitorHeader, request);
|
|
11
11
|
};
|
|
12
12
|
MonitoredRequestUtils.isMonitoredRoute = (url, isMonitoredRoute) => {
|
|
13
|
-
return
|
|
13
|
+
return isStringInPatterns(url.pathname, isMonitoredRoute);
|
|
14
14
|
};
|
|
15
15
|
MonitoredRequestUtils.isEnforcedRoute = (url, enforcedRoutes) => {
|
|
16
|
-
return
|
|
16
|
+
return isStringInPatterns(url.pathname, enforcedRoutes);
|
|
17
17
|
};
|
|
18
18
|
MonitoredRequestUtils.invokeCustomIsEnforcedRequest = async (config, context) => {
|
|
19
19
|
if (config.customIsEnforcedRequest && typeof config.customIsEnforcedRequest === 'function') {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HttpMethod } from '../../../http';
|
|
2
2
|
import { FilterReason } from '../../../filter';
|
|
3
|
-
import { getExtension,
|
|
3
|
+
import { getExtension, isStringInPatterns } from '../../../utils';
|
|
4
4
|
export class DefaultBotDefenderFilter {
|
|
5
5
|
config;
|
|
6
6
|
ipRangeChecker;
|
|
@@ -52,10 +52,10 @@ export class DefaultBotDefenderFilter {
|
|
|
52
52
|
return this.config.filteredIps.some((range) => this.ipRangeChecker.isIpInRange(ip, range));
|
|
53
53
|
}
|
|
54
54
|
shouldFilterByRoute(route) {
|
|
55
|
-
return
|
|
55
|
+
return isStringInPatterns(route, this.config.filteredRoutes);
|
|
56
56
|
}
|
|
57
57
|
shouldFilterByUserAgent(userAgent) {
|
|
58
|
-
return this.config.filteredUserAgents
|
|
58
|
+
return isStringInPatterns(userAgent, this.config.filteredUserAgents);
|
|
59
59
|
}
|
|
60
60
|
async shouldFilterByCustomFunction(context) {
|
|
61
61
|
if (this.config.customIsFilteredRequest && typeof this.config.customIsFilteredRequest === 'function') {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isStringInPatterns } from '../utils';
|
|
2
2
|
export var SensitiveRequestUtils;
|
|
3
3
|
(function (SensitiveRequestUtils) {
|
|
4
4
|
SensitiveRequestUtils.isSensitiveRequest = async (config, context) => {
|
|
@@ -7,7 +7,7 @@ export var SensitiveRequestUtils;
|
|
|
7
7
|
(await SensitiveRequestUtils.invokeCustomIsSensitiveRequest(config, context)));
|
|
8
8
|
};
|
|
9
9
|
SensitiveRequestUtils.isSensitiveRoute = (url, sensitiveRoutes) => {
|
|
10
|
-
return
|
|
10
|
+
return isStringInPatterns(url.pathname, sensitiveRoutes);
|
|
11
11
|
};
|
|
12
12
|
SensitiveRequestUtils.isSensitiveGraphqlOperation = (graphQLData) => {
|
|
13
13
|
return !!graphQLData?.some((operation) => operation.sensitive);
|
|
@@ -9,6 +9,6 @@ export const X_PX_BYPASS_REASON_HEADER_NAME = 'x-px-bypass-reason';
|
|
|
9
9
|
export const PUSH_DATA_HMAC_HEADER_NAME = 'x-px-pushdata';
|
|
10
10
|
export const PUSH_DATA_FEATURE_HEADER_NAME = 'x-px-feature';
|
|
11
11
|
export const EMAIL_ADDRESS_REGEX = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/;
|
|
12
|
-
export const URL_REGEX = /^(https
|
|
12
|
+
export const URL_REGEX = /^(https?:)\/\/(([^@\s:\/]+):?([^@\s\/]*)@)?(([^:\/?#]*)(?:\:([0-9]+))?)(\/?[^?#]*)(\?[^#]*|)(#.*|)$/;
|
|
13
13
|
export const REGEX_STRUCTURE = /^\/(.+?)\/([gimsuyvd]*)$/;
|
|
14
|
-
export const CORE_MODULE_VERSION = 'JS Core 0.23.
|
|
14
|
+
export const CORE_MODULE_VERSION = 'JS Core 0.23.3';
|
|
@@ -2,7 +2,14 @@ import { EnforcerError } from './EnforcerError';
|
|
|
2
2
|
import { EnforcerErrorName } from './EnforcerErrorName';
|
|
3
3
|
export class EnforcerConfigurationError extends EnforcerError {
|
|
4
4
|
constructor(configName, invalidConfigValue, possibleValues) {
|
|
5
|
-
|
|
5
|
+
const value = invalidConfigValue === null
|
|
6
|
+
? 'null'
|
|
7
|
+
: invalidConfigValue === undefined
|
|
8
|
+
? 'undefined'
|
|
9
|
+
: typeof invalidConfigValue === 'string'
|
|
10
|
+
? `"${invalidConfigValue}"`
|
|
11
|
+
: invalidConfigValue;
|
|
12
|
+
let message = `configuration ${configName} cannot be type ${typeof invalidConfigValue} with value ${value}`;
|
|
6
13
|
if (possibleValues) {
|
|
7
14
|
message += `, possible values: ${possibleValues.join(', ')}`;
|
|
8
15
|
}
|
package/lib/esm/utils/utils.js
CHANGED
|
@@ -33,20 +33,36 @@ export const getExtension = (route) => {
|
|
|
33
33
|
return endOfPath.substring(extensionIndex);
|
|
34
34
|
};
|
|
35
35
|
export const redactSensitiveFields = (object, sensitiveFields) => {
|
|
36
|
-
const NUMBER_OF_TRAILING_CHARS_TO_EXPOSE = 5;
|
|
37
|
-
const SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS = NUMBER_OF_TRAILING_CHARS_TO_EXPOSE * 10;
|
|
38
36
|
const newObj = Object.assign({}, object);
|
|
39
37
|
sensitiveFields.forEach((fieldName) => {
|
|
40
38
|
const sensitiveValue = object[fieldName];
|
|
41
39
|
if (!sensitiveValue) {
|
|
42
40
|
return;
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
const trailingChars = sensitiveValue.substring(sensitiveValue.length - (trailingCharsExposed ? NUMBER_OF_TRAILING_CHARS_TO_EXPOSE : 0));
|
|
46
|
-
newObj[fieldName] = `***REDACTED***${trailingChars}`;
|
|
42
|
+
newObj[fieldName] = redactUnknownValue(sensitiveValue);
|
|
47
43
|
});
|
|
48
44
|
return newObj;
|
|
49
45
|
};
|
|
46
|
+
const redactUnknownValue = (value) => {
|
|
47
|
+
switch (typeof value) {
|
|
48
|
+
case 'string':
|
|
49
|
+
return redactSensitiveString(value);
|
|
50
|
+
case 'object':
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
return value.flatMap(redactUnknownValue).filter((v) => !isNullOrUndefined(v));
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
default:
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const redactSensitiveString = (sensitiveValue) => {
|
|
60
|
+
const NUMBER_OF_TRAILING_CHARS_TO_EXPOSE = 5;
|
|
61
|
+
const SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS = NUMBER_OF_TRAILING_CHARS_TO_EXPOSE * 10;
|
|
62
|
+
const trailingCharsExposed = sensitiveValue.length >= SENSITIVE_VALUE_MINIMUM_LENGTH_TO_EXPOSE_TRAILING_CHARS;
|
|
63
|
+
const trailingChars = sensitiveValue.substring(sensitiveValue.length - (trailingCharsExposed ? NUMBER_OF_TRAILING_CHARS_TO_EXPOSE : 0));
|
|
64
|
+
return `***REDACTED***${trailingChars}`;
|
|
65
|
+
};
|
|
50
66
|
export const removeSensitiveHeaders = (headers, sensitiveHeaderNames) => {
|
|
51
67
|
const ret = toMutableHeaders(headers);
|
|
52
68
|
sensitiveHeaderNames.forEach((name) => {
|
|
@@ -54,17 +70,17 @@ export const removeSensitiveHeaders = (headers, sensitiveHeaderNames) => {
|
|
|
54
70
|
});
|
|
55
71
|
return ret;
|
|
56
72
|
};
|
|
57
|
-
export const
|
|
58
|
-
return patterns.some((pattern) =>
|
|
73
|
+
export const isStringInPatterns = (str, patterns) => {
|
|
74
|
+
return patterns.some((pattern) => isStringMatch(str, pattern));
|
|
59
75
|
};
|
|
60
|
-
export const
|
|
61
|
-
if (!
|
|
76
|
+
export const isStringMatch = (str, pattern) => {
|
|
77
|
+
if (!str || !pattern) {
|
|
62
78
|
return false;
|
|
63
79
|
}
|
|
64
|
-
if (pattern instanceof RegExp && !!
|
|
80
|
+
if (pattern instanceof RegExp && !!str.match(pattern)) {
|
|
65
81
|
return true;
|
|
66
82
|
}
|
|
67
|
-
if (typeof pattern === 'string' &&
|
|
83
|
+
if (typeof pattern === 'string' && str.startsWith(pattern)) {
|
|
68
84
|
return true;
|
|
69
85
|
}
|
|
70
86
|
return false;
|
|
@@ -43,7 +43,7 @@ export declare abstract class ConfigurationBase<Req, Res, Added, Removed extends
|
|
|
43
43
|
get filteredHttpMethods(): string[];
|
|
44
44
|
get filteredIps(): string[];
|
|
45
45
|
get filteredRoutes(): Array<string | RegExp>;
|
|
46
|
-
get filteredUserAgents(): string
|
|
46
|
+
get filteredUserAgents(): Array<string | RegExp>;
|
|
47
47
|
get firstPartyEnabled(): boolean;
|
|
48
48
|
get customIsFilteredRequest(): CustomRequestFunction<Req> | null;
|
|
49
49
|
get customFirstPartyPrefix(): string;
|
|
@@ -48,7 +48,7 @@ export interface IConfiguration<Req, Res, Added, Removed> {
|
|
|
48
48
|
/**
|
|
49
49
|
* An array of agents that should not go through the enforcer flow.
|
|
50
50
|
*/
|
|
51
|
-
readonly filteredUserAgents: string
|
|
51
|
+
readonly filteredUserAgents: Array<string | RegExp>;
|
|
52
52
|
/**
|
|
53
53
|
* An array of regular expressions or prefixes of routes that should not go through the enforcer flow.
|
|
54
54
|
*/
|
|
@@ -74,7 +74,7 @@ export type CommonConfigurationParams<Req, Res, Added, Removed> = TokenV3Configu
|
|
|
74
74
|
px_filter_by_http_method?: string[];
|
|
75
75
|
px_filter_by_ip?: string[];
|
|
76
76
|
px_filter_by_route?: Array<string | RegExp>;
|
|
77
|
-
px_filter_by_user_agent?: string
|
|
77
|
+
px_filter_by_user_agent?: Array<string | RegExp>;
|
|
78
78
|
px_css_ref?: string;
|
|
79
79
|
px_js_ref?: string;
|
|
80
80
|
px_custom_cookie_header?: string;
|
|
@@ -8,6 +8,7 @@ import { PXDE } from '../pxde';
|
|
|
8
8
|
import { CustomParameters } from '../custom_parameters';
|
|
9
9
|
import { GraphQLData } from '../graphql';
|
|
10
10
|
import { RequestData, RiskApiData, ServerData, TlsData, TokenData } from './interfaces';
|
|
11
|
+
import { LogRecord } from '../logger';
|
|
11
12
|
type RequestDataJson<Req> = Omit<RequestData<Req>, 'url' | 'request'> & {
|
|
12
13
|
url: string;
|
|
13
14
|
request: undefined;
|
|
@@ -37,5 +38,8 @@ export type ContextJson<Req = unknown, Res = unknown> = {
|
|
|
37
38
|
readonly shouldSendLogs: boolean;
|
|
38
39
|
readonly isRemoteConfigUpdateRequest: boolean;
|
|
39
40
|
readonly enforcerStartTime?: number;
|
|
41
|
+
logger?: {
|
|
42
|
+
logs: LogRecord[];
|
|
43
|
+
};
|
|
40
44
|
};
|
|
41
45
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IConfiguration } from '../config';
|
|
2
2
|
import { Action } from '../action';
|
|
3
|
-
import { ILogger } from '../logger';
|
|
3
|
+
import { ILogger, LogRecord } from '../logger';
|
|
4
4
|
import { ProductData, ProductName } from '../products';
|
|
5
5
|
import { TokenOrigin } from '../risk_token';
|
|
6
6
|
import { IIncomingRequest } from '../http';
|
|
@@ -42,5 +42,5 @@ export declare class SerializedContext<Req, Res, Added, Removed> implements ICon
|
|
|
42
42
|
protected createRequestData({ requestData }: ContextJson<Req, Res>, request: IIncomingRequest<Req>, urlUtils: IUrlUtils): RequestData<Req>;
|
|
43
43
|
protected createTokenData({ tokenData }: ContextJson<Req, Res>, config: IConfiguration<Req, Res, Added, Removed>): TokenData<Req, Res>;
|
|
44
44
|
protected createRiskApiData({ riskApiData }: ContextJson<Req, Res>): RiskApiData;
|
|
45
|
-
protected createLogger(config: IConfiguration<Req, Res, Added, Removed>, shouldSendLogs: boolean): ILogger;
|
|
45
|
+
protected createLogger(config: IConfiguration<Req, Res, Added, Removed>, shouldSendLogs: boolean, logs?: LogRecord[]): ILogger;
|
|
46
46
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LoggerSeverity } from './LoggerSeverity';
|
|
2
2
|
import { LoggerBase } from './LoggerBase';
|
|
3
3
|
import { ILogger } from './ILogger';
|
|
4
|
+
import { LogRecord } from './model';
|
|
4
5
|
export declare class DefaultLogger extends LoggerBase implements ILogger {
|
|
5
|
-
constructor(loggerSeverity: `${LoggerSeverity}`, shouldSaveLogs: boolean);
|
|
6
|
+
constructor(loggerSeverity: `${LoggerSeverity}`, shouldSaveLogs: boolean, logs?: LogRecord[]);
|
|
6
7
|
protected log(message: string): void;
|
|
7
8
|
}
|
|
@@ -11,4 +11,4 @@ export declare const PUSH_DATA_FEATURE_HEADER_NAME = "x-px-feature";
|
|
|
11
11
|
export declare const EMAIL_ADDRESS_REGEX: RegExp;
|
|
12
12
|
export declare const URL_REGEX: RegExp;
|
|
13
13
|
export declare const REGEX_STRUCTURE: RegExp;
|
|
14
|
-
export declare const CORE_MODULE_VERSION = "JS Core 0.23.
|
|
14
|
+
export declare const CORE_MODULE_VERSION = "JS Core 0.23.3";
|
|
@@ -11,8 +11,8 @@ export declare const getAuthorizationHeader: (authToken: string) => string;
|
|
|
11
11
|
export declare const getExtension: (route: string) => string;
|
|
12
12
|
export declare const redactSensitiveFields: <T extends Record<string, any>>(object: T, sensitiveFields: Array<keyof T | string>) => T;
|
|
13
13
|
export declare const removeSensitiveHeaders: (headers: ReadonlyHeaders, sensitiveHeaderNames: string[]) => Record<string, string[]>;
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const
|
|
14
|
+
export declare const isStringInPatterns: (str: string, patterns: Array<string | RegExp>) => boolean;
|
|
15
|
+
export declare const isStringMatch: (str: string, pattern: string | RegExp) => boolean;
|
|
16
16
|
/**
|
|
17
17
|
* @deprecated this method is not typesafe. Copy the fields manually instead,
|
|
18
18
|
* unsafe - ignores compilerOptions.strictNullChecks
|