perimeterx-js-core 0.7.0 → 0.8.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.
- package/lib/action/utils.js +1 -1
- package/lib/activities/HttpActivityClient.d.ts +5 -5
- package/lib/activities/HttpActivityClient.js +28 -39
- package/lib/activities/HttpBatchedActivityClient.d.ts +2 -2
- package/lib/activities/HttpBatchedActivityClient.js +19 -32
- package/lib/activities/model/AsyncActivity.d.ts +14 -0
- package/lib/activities/model/{ActivityDetails.d.ts → AsyncActivityDetails.d.ts} +6 -23
- package/lib/activities/model/CommonActivityDetails.d.ts +40 -0
- package/lib/activities/model/CommonActivityDetails.js +1 -0
- package/lib/activities/model/HeaderEntry.d.ts +4 -0
- package/lib/activities/model/HeaderEntry.js +1 -0
- package/lib/activities/model/index.d.ts +4 -2
- package/lib/activities/model/index.js +4 -2
- package/lib/activities/utils.d.ts +6071 -9
- package/lib/activities/utils.js +111 -35
- package/lib/additional_activity_handler/AdditionalActivityHandler.d.ts +1 -1
- package/lib/additional_activity_handler/AdditionalActivityHandlerUtils.js +4 -12
- package/lib/config/ConfigurationParams.d.ts +2 -1
- package/lib/config/DefaultConfigurations.js +1 -0
- package/lib/config/IConfiguration.d.ts +5 -1
- package/lib/config/StaticConfigurationBase.d.ts +2 -1
- package/lib/config/StaticConfigurationBase.js +6 -1
- package/lib/context/DefaultContext.d.ts +1 -1
- package/lib/context/DefaultContext.js +40 -8
- package/lib/context/interfaces/RiskApiData.d.ts +4 -0
- package/lib/cors/DefaultCors.js +21 -31
- package/lib/custom_parameters/CustomParametersUtils.js +3 -12
- package/lib/enforcer/EnforcerBase.d.ts +2 -1
- package/lib/enforcer/EnforcerBase.js +56 -57
- package/lib/enforcer/options/EnforcerBaseOptions.d.ts +2 -0
- package/lib/graphql/DefaultGraphQLParser.js +30 -39
- package/lib/http/index.d.ts +0 -1
- package/lib/http/index.js +0 -1
- package/lib/http/interfaces/IBody.d.ts +3 -2
- package/lib/http/interfaces/IIncomingRequest.d.ts +4 -0
- package/lib/http/interfaces/IURL.d.ts +3 -0
- package/lib/http/interfaces/IURLSearchParams.d.ts +9 -0
- package/lib/http/interfaces/IURLSearchParams.js +1 -0
- package/lib/http/interfaces/index.d.ts +1 -0
- package/lib/http/interfaces/index.js +1 -0
- package/lib/http/{impl → utils}/FormDataImpl.js +4 -4
- package/lib/http/{impl → utils}/MinimalResponseImpl.js +3 -0
- package/lib/http/utils/MinimalResponseUtils.js +5 -7
- package/lib/http/utils/MultipartFormDataUtils.js +4 -5
- package/lib/http/{impl → utils}/OutgoingRequestImpl.d.ts +1 -1
- package/lib/http/{impl → utils}/OutgoingRequestImpl.js +5 -1
- package/lib/http/utils/URLUtils.d.ts +7 -0
- package/lib/http/utils/URLUtils.js +62 -0
- package/lib/http/utils/UrlImpl.d.ts +18 -0
- package/lib/http/utils/UrlImpl.js +54 -0
- package/lib/http/utils/UrlSearchParamsImpl.d.ts +19 -0
- package/lib/http/utils/UrlSearchParamsImpl.js +116 -0
- package/lib/http/utils/index.d.ts +6 -0
- package/lib/http/utils/index.js +6 -0
- package/lib/{utils → impl}/base64/AtobBase64Utils.d.ts +1 -1
- package/lib/{utils → impl}/base64/BufferBase64Utils.d.ts +1 -1
- package/lib/{utils → impl}/base64/BufferBase64Utils.js +1 -1
- package/lib/{utils → impl}/base64/JSBase64Base64Utils.d.ts +1 -1
- package/lib/{utils → impl}/cipher/CryptoCipherUtils.d.ts +1 -1
- package/lib/impl/cipher/CryptoCipherUtils.js +18 -0
- package/lib/{utils → impl}/cipher/SubtleCryptoCipherUtils.d.ts +1 -2
- package/lib/impl/cipher/SubtleCryptoCipherUtils.js +38 -0
- package/lib/{utils → impl}/hash/CryptoHashUtils.d.ts +1 -2
- package/lib/impl/hash/CryptoHashUtils.js +10 -0
- package/lib/{utils → impl}/hash/CryptoJSHashUtils.d.ts +1 -2
- package/lib/{utils → impl}/hash/CryptoJSHashUtils.js +1 -1
- package/lib/{utils → impl}/hash/SubtleCryptoHashUtils.d.ts +1 -2
- package/lib/impl/hash/SubtleCryptoHashUtils.js +21 -0
- package/lib/{utils → impl}/hmac/CryptoHmacUtils.d.ts +1 -2
- package/lib/{utils → impl}/hmac/CryptoHmacUtils.js +2 -1
- package/lib/{utils → impl}/hmac/CryptoJSHmacUtils.d.ts +1 -2
- package/lib/{utils → impl}/hmac/CryptoJSHmacUtils.js +1 -1
- package/lib/{http/impl → impl/http}/phin/PhinHttpClient.d.ts +1 -1
- package/lib/impl/http/phin/PhinHttpClient.js +31 -0
- package/lib/{http/impl → impl/http}/phin/PhinIncomingResponse.d.ts +2 -2
- package/lib/impl/http/phin/PhinIncomingResponse.js +23 -0
- package/lib/{utils → impl}/ip_range_checker/DefaultIpRangeChecker.d.ts +1 -1
- package/lib/{utils → impl}/request_id_generator/UuidRequestIdGenerator.d.ts +1 -1
- package/lib/{utils → impl}/url_parser/DefaultUrlParser.d.ts +4 -4
- package/lib/{utils → impl}/url_parser/DefaultUrlParser.js +9 -2
- package/lib/logger/HttpLogServiceClient.d.ts +17 -0
- package/lib/logger/HttpLogServiceClient.js +52 -0
- package/lib/logger/ILogServiceClient.d.ts +6 -0
- package/lib/logger/ILogServiceClient.js +1 -0
- package/lib/logger/ILogger.d.ts +6 -0
- package/lib/logger/LoggerBase.d.ts +6 -2
- package/lib/logger/LoggerBase.js +14 -1
- package/lib/logger/constants.d.ts +2 -0
- package/lib/logger/constants.js +2 -0
- package/lib/logger/index.d.ts +4 -0
- package/lib/logger/index.js +3 -0
- package/lib/logger/model/EnrichedLogRecord.d.ts +3 -0
- package/lib/logger/model/EnrichedLogRecord.js +1 -0
- package/lib/logger/model/LogMetadata.d.ts +9 -0
- package/lib/logger/model/LogMetadata.js +1 -0
- package/lib/logger/model/LogRecord.d.ts +6 -0
- package/lib/logger/model/LogRecord.js +1 -0
- package/lib/logger/model/index.d.ts +3 -0
- package/lib/logger/model/index.js +3 -0
- package/lib/phase/flow/EndEnforcerFlow.d.ts +6 -0
- package/lib/phase/flow/EndEnforcerFlow.js +10 -0
- package/lib/phase/flow/index.d.ts +1 -0
- package/lib/phase/flow/index.js +1 -0
- package/lib/phase/impl/AdditionalActivityHandlerPhase.js +4 -15
- package/lib/phase/impl/CompositePhase.js +9 -19
- package/lib/phase/impl/CreateBlockResponsePhase.js +24 -35
- package/lib/phase/impl/DecideActionPhase.js +11 -21
- package/lib/phase/impl/EnrichContextFromRequestPhase.js +28 -45
- package/lib/phase/impl/EnrichContextFromResponsePhase.js +12 -23
- package/lib/phase/impl/FilterPhase.js +3 -13
- package/lib/phase/impl/FirstPartyPhase.js +21 -32
- package/lib/phase/impl/ModifyIncomingRequestPhase.js +4 -14
- package/lib/phase/impl/ModifyOutgoingResponsePhase.js +7 -18
- package/lib/phase/impl/ParseTokenPhase.js +5 -15
- package/lib/phase/impl/PreflightPhase.js +12 -20
- package/lib/phase/impl/RiskApiPhase.js +24 -36
- package/lib/phase/impl/SendAsyncActivitiesOnRequestPhase.js +8 -20
- package/lib/phase/impl/SendAsyncActivitiesOnResponsePhase.js +4 -14
- package/lib/phase/impl/SendLogsPhase.d.ts +11 -0
- package/lib/phase/impl/SendLogsPhase.js +16 -0
- package/lib/phase/impl/TelemetryPhase.js +9 -21
- package/lib/phase/impl/index.d.ts +1 -0
- package/lib/phase/impl/index.js +1 -0
- package/lib/products/account_defender/AccountDefender.js +16 -35
- package/lib/products/bot_defender/BotDefender.js +51 -72
- package/lib/products/bot_defender/BotDefenderActionData.js +2 -0
- package/lib/products/bot_defender/block/DefaultBotDefenderBlocker.d.ts +4 -4
- package/lib/products/bot_defender/block/DefaultBotDefenderBlocker.js +5 -3
- package/lib/products/bot_defender/block/captcha/CaptchaBlocker.d.ts +7 -4
- package/lib/products/bot_defender/block/captcha/CaptchaBlocker.js +12 -8
- package/lib/products/bot_defender/block/captcha/HtmlCaptchaBlocker.d.ts +1 -1
- package/lib/products/bot_defender/block/captcha/HtmlCaptchaBlocker.js +1 -0
- package/lib/products/bot_defender/block/captcha/JsonCaptchaBlocker.d.ts +1 -1
- package/lib/products/bot_defender/block/captcha/JsonCaptchaBlocker.js +5 -4
- package/lib/products/bot_defender/block/captcha/MobileCaptchaBlocker.d.ts +2 -2
- package/lib/products/bot_defender/block/captcha/MobileCaptchaBlocker.js +2 -0
- package/lib/products/bot_defender/block/utils.js +1 -2
- package/lib/products/bot_defender/filter/DefaultBotDefenderFilter.js +7 -1
- package/lib/products/bot_defender/first_party/DefaultBotDefenderFirstParty.js +51 -68
- package/lib/products/bot_defender/first_party/constants.d.ts +0 -4
- package/lib/products/bot_defender/first_party/constants.js +0 -7
- package/lib/products/credential_intelligence/CredentialIntelligence.js +42 -63
- package/lib/products/credential_intelligence/endpoint/CredentialEndpoint.js +15 -23
- package/lib/products/credential_intelligence/endpoint/CredentialEndpointManager.js +9 -22
- package/lib/products/credential_intelligence/endpoint/extractor/BodyCredentialExtractor.d.ts +5 -5
- package/lib/products/credential_intelligence/endpoint/extractor/BodyCredentialExtractor.js +22 -33
- package/lib/products/credential_intelligence/endpoint/extractor/CustomCredentialExtractor.js +8 -18
- package/lib/products/credential_intelligence/endpoint/extractor/HeaderCredentialExtractor.js +2 -0
- package/lib/products/credential_intelligence/endpoint/extractor/QueryParamCredentialExtractor.d.ts +1 -1
- package/lib/products/credential_intelligence/endpoint/extractor/QueryParamCredentialExtractor.js +11 -16
- package/lib/products/credential_intelligence/endpoint/hash_protocol/MultistepHashProtocol.js +11 -21
- package/lib/products/credential_intelligence/endpoint/hash_protocol/SingleStepAndMultistepHashProtocol.js +9 -18
- package/lib/products/credential_intelligence/endpoint/hash_protocol/SingleStepHashProtocol.js +13 -25
- package/lib/products/credential_intelligence/endpoint/login_successful/BodyLoginSuccessfulParser.js +4 -14
- package/lib/products/credential_intelligence/endpoint/login_successful/CustomLoginSuccessfulParser.js +10 -20
- package/lib/products/credential_intelligence/endpoint/login_successful/HeaderLoginSuccessfulParser.js +7 -16
- package/lib/products/credential_intelligence/endpoint/login_successful/LoginSuccessfulParserFactory.js +7 -6
- package/lib/products/credential_intelligence/endpoint/login_successful/StatusLoginSuccessfulParser.js +3 -13
- package/lib/products/credential_intelligence/endpoint/matcher/ExactPathEndpointMatcher.js +2 -0
- package/lib/products/credential_intelligence/endpoint/matcher/RegexPathEndpointMatcher.js +2 -0
- package/lib/pxde/DefaultDataEnrichment.js +47 -61
- package/lib/pxhd/PXHDUtils.js +2 -2
- package/lib/risk_api/client/PostRiskApiClientBase.d.ts +7 -12
- package/lib/risk_api/client/PostRiskApiClientBase.js +70 -171
- package/lib/risk_api/model/RiskActivity.d.ts +5 -45
- package/lib/risk_api/risk_response/IRiskResponse.d.ts +1 -0
- package/lib/risk_api/risk_response/RiskResponseBase.d.ts +1 -0
- package/lib/risk_api/risk_response/RiskResponseBase.js +20 -33
- package/lib/risk_api/risk_response/v2/DefaultRiskResponseV2.d.ts +1 -1
- package/lib/risk_api/risk_response/v2/DefaultRiskResponseV2.js +3 -5
- package/lib/risk_api/risk_response/v2/RiskResponseV2Payload.d.ts +1 -0
- package/lib/risk_api/risk_response/v3/DefaultRiskResponseV3.js +2 -4
- package/lib/risk_api/risk_response/v3/RiskResponseV3Payload.d.ts +1 -0
- package/lib/risk_token/parser/TokenParserBase.js +25 -36
- package/lib/risk_token/token/TokenBase.js +24 -29
- package/lib/risk_token/token/v2/DefaultTokenV2.js +34 -49
- package/lib/risk_token/token/v3/DefaultTokenV3.js +63 -77
- package/lib/telemetry/DefaultTelemetry.js +46 -58
- package/lib/utils/base64/index.d.ts +0 -3
- package/lib/utils/base64/index.js +0 -3
- package/lib/utils/cipher/index.d.ts +1 -3
- package/lib/utils/cipher/index.js +1 -2
- package/lib/utils/constants.d.ts +2 -1
- package/lib/utils/constants.js +2 -1
- package/lib/utils/hash/index.d.ts +0 -3
- package/lib/utils/hash/index.js +0 -3
- package/lib/utils/hmac/index.d.ts +0 -2
- package/lib/utils/hmac/index.js +0 -2
- package/lib/utils/ip_range_checker/index.d.ts +1 -2
- package/lib/utils/ip_range_checker/index.js +1 -1
- package/lib/utils/request_id_generator/index.d.ts +1 -2
- package/lib/utils/request_id_generator/index.js +1 -1
- package/lib/utils/url_parser/index.d.ts +0 -1
- package/lib/utils/url_parser/index.js +0 -1
- package/lib/utils/utils.d.ts +1 -7
- package/lib/utils/utils.js +3 -25
- package/package.json +12 -6
- package/lib/activities/model/Activity.d.ts +0 -13
- package/lib/http/impl/index.d.ts +0 -4
- package/lib/http/impl/index.js +0 -4
- package/lib/http/impl/phin/PhinHttpClient.js +0 -41
- package/lib/http/impl/phin/PhinIncomingResponse.js +0 -38
- package/lib/utils/cipher/CryptoCipherUtils.js +0 -28
- package/lib/utils/cipher/SubtleCryptoCipherUtils.js +0 -47
- package/lib/utils/hash/CryptoHashUtils.js +0 -20
- package/lib/utils/hash/SubtleCryptoHashUtils.js +0 -31
- /package/lib/activities/model/{Activity.js → AsyncActivity.js} +0 -0
- /package/lib/activities/model/{ActivityDetails.js → AsyncActivityDetails.js} +0 -0
- /package/lib/http/{impl → utils}/FormDataImpl.d.ts +0 -0
- /package/lib/http/{impl → utils}/MinimalResponseImpl.d.ts +0 -0
- /package/lib/{utils → impl}/base64/AtobBase64Utils.js +0 -0
- /package/lib/{utils → impl}/base64/JSBase64Base64Utils.js +0 -0
- /package/lib/{http/impl → impl/http}/phin/index.d.ts +0 -0
- /package/lib/{http/impl → impl/http}/phin/index.js +0 -0
- /package/lib/{utils → impl}/ip_range_checker/DefaultIpRangeChecker.js +0 -0
- /package/lib/{utils → impl}/request_id_generator/UuidRequestIdGenerator.js +0 -0
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { DefaultDataEnrichment } from '../pxde';
|
|
11
2
|
import { DefaultTelemetry } from '../telemetry';
|
|
12
3
|
import { DefaultTokenV2Parser, DefaultTokenV3Parser, TokenVersion } from '../risk_token';
|
|
13
4
|
import { DefaultCors } from '../cors';
|
|
14
5
|
import { PostRiskApiClientV2, PostRiskApiClientV3 } from '../risk_api';
|
|
15
|
-
import { EnforceFlow, FilterFlow, PostEnforceFlow } from '../phase';
|
|
6
|
+
import { EndEnforcerFlow, EnforceFlow, FilterFlow, PostEnforceFlow } from '../phase';
|
|
16
7
|
import { AccountDefender, BotDefender, CredentialIntelligence, ProductName } from '../products';
|
|
17
8
|
import { HttpActivityClient, HttpBatchedActivityClient } from '../activities';
|
|
18
9
|
import { DefaultGraphQLParser } from '../graphql';
|
|
10
|
+
import { HttpLogServiceClient } from '../logger';
|
|
19
11
|
export class EnforcerBase {
|
|
12
|
+
config;
|
|
13
|
+
filterFlow;
|
|
14
|
+
enforceFlow;
|
|
15
|
+
postEnforceFlow;
|
|
16
|
+
endEnforcerFlow;
|
|
17
|
+
activityClient;
|
|
20
18
|
/**
|
|
21
19
|
* The EnforcerBase constructor.
|
|
22
20
|
* @param config - The enforcer configuration.
|
|
@@ -30,26 +28,25 @@ export class EnforcerBase {
|
|
|
30
28
|
this.filterFlow = new FilterFlow(config, initializationBlock);
|
|
31
29
|
this.enforceFlow = new EnforceFlow(config, initializationBlock);
|
|
32
30
|
this.postEnforceFlow = new PostEnforceFlow(config, initializationBlock);
|
|
31
|
+
this.endEnforcerFlow = new EndEnforcerFlow(config, initializationBlock);
|
|
33
32
|
}
|
|
34
33
|
/**
|
|
35
34
|
* The central function that triggers enforcement on the incoming request.
|
|
36
35
|
* @param args - The EnforceArgs required to enforce the incoming request.
|
|
37
36
|
* @returns Promise<Res|null> - A Promise resolving to a Res or null depending on the action that should be taken.
|
|
38
37
|
*/
|
|
39
|
-
enforce(...args) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.config.logger.debug('module is disabled, will not enforce');
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
return yield this.doEnforce(...args);
|
|
47
|
-
}
|
|
48
|
-
catch (e) {
|
|
49
|
-
this.config.logger.error(`caught error in enforce - ${e}`);
|
|
38
|
+
async enforce(...args) {
|
|
39
|
+
try {
|
|
40
|
+
if (!this.config.moduleEnabled) {
|
|
41
|
+
this.config.logger.debug('module is disabled, will not enforce');
|
|
50
42
|
return null;
|
|
51
43
|
}
|
|
52
|
-
|
|
44
|
+
return await this.doEnforce(...args);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
this.config.logger.error(`caught error in enforce - ${e}`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
53
50
|
}
|
|
54
51
|
/**
|
|
55
52
|
* Performs all enforcer functionality on the incoming request context.
|
|
@@ -57,17 +54,20 @@ export class EnforcerBase {
|
|
|
57
54
|
* @returns Promise<Res|null> - A Promise resolving to a Res or null depending on the action that should be taken.
|
|
58
55
|
* @protected
|
|
59
56
|
*/
|
|
60
|
-
doEnforce(...args) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
async doEnforce(...args) {
|
|
58
|
+
const context = await this.constructContext(...args);
|
|
59
|
+
let result = await this.filterFlow.execute(context);
|
|
60
|
+
if (result.done) {
|
|
61
|
+
await this.endEnforcerFlow.execute(context);
|
|
62
|
+
return result.response ? this.convertToRes(result.response, ...args) : null;
|
|
63
|
+
}
|
|
64
|
+
this.preserveContext(context, ...args);
|
|
65
|
+
result = await this.enforceFlow.execute(context);
|
|
66
|
+
if (result.done) {
|
|
67
|
+
await this.endEnforcerFlow.execute(context);
|
|
68
|
+
return result.response ? this.convertToRes(result.response, ...args) : null;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
73
|
* Performs all required functionality after an origin response has been received.
|
|
@@ -75,27 +75,24 @@ export class EnforcerBase {
|
|
|
75
75
|
* @returns Promise<void> - The response parameter will be modified as needed
|
|
76
76
|
* @protected
|
|
77
77
|
*/
|
|
78
|
-
postEnforce(...args) {
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const context = this.retrieveContext(...args);
|
|
82
|
-
if (context) {
|
|
83
|
-
context.response = yield this.convertToOutgoingResponse(...args);
|
|
84
|
-
yield this.postEnforceFlow.execute(context);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch (e) {
|
|
88
|
-
this.config.logger.error(`caught error in post enforce - ${e}`);
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
sendAdditionalS2SActivity(...args) {
|
|
93
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
async postEnforce(...args) {
|
|
79
|
+
try {
|
|
94
80
|
const context = this.retrieveContext(...args);
|
|
95
81
|
if (context) {
|
|
96
|
-
|
|
82
|
+
context.response = await this.convertToOutgoingResponse(...args);
|
|
83
|
+
await this.postEnforceFlow.execute(context);
|
|
84
|
+
await this.endEnforcerFlow.execute(context);
|
|
97
85
|
}
|
|
98
|
-
}
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
this.config.logger.error(`caught error in post enforce - ${e}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async sendAdditionalS2SActivity(...args) {
|
|
92
|
+
const context = this.retrieveContext(...args);
|
|
93
|
+
if (context) {
|
|
94
|
+
await this.activityClient.sendActivities(context);
|
|
95
|
+
}
|
|
99
96
|
}
|
|
100
97
|
/**
|
|
101
98
|
* Returns the components needed to initialize the enforcer according to the provided options. If no
|
|
@@ -124,6 +121,7 @@ export class EnforcerBase {
|
|
|
124
121
|
(config.maxActivityBatchSize > 1
|
|
125
122
|
? new HttpBatchedActivityClient(config, httpClient)
|
|
126
123
|
: new HttpActivityClient(config, httpClient));
|
|
124
|
+
const logServiceClient = options.logServiceClient || (config.loggerAuthToken ? new HttpLogServiceClient(config, httpClient) : null);
|
|
127
125
|
const allOptions = {
|
|
128
126
|
httpClient,
|
|
129
127
|
base64Utils,
|
|
@@ -137,22 +135,23 @@ export class EnforcerBase {
|
|
|
137
135
|
tokenParser,
|
|
138
136
|
riskApiClient,
|
|
139
137
|
activityClient,
|
|
138
|
+
logServiceClient,
|
|
140
139
|
};
|
|
141
140
|
const products = this.initializeProducts(config, options.products, base64Utils, hashUtils, ipRangeChecker);
|
|
142
|
-
return
|
|
141
|
+
return { products, ...allOptions };
|
|
143
142
|
}
|
|
144
143
|
initializeProducts(config, products, base64Utils, hashUtils, ipRangeChecker) {
|
|
145
|
-
const botDefender =
|
|
146
|
-
const accountDefender =
|
|
144
|
+
const botDefender = products?.bd || new BotDefender(config, { base64Utils, ipRangeChecker });
|
|
145
|
+
const accountDefender = products?.ad || new AccountDefender(config, { base64Utils });
|
|
147
146
|
const credentialIntelligence = config.ciEnabled
|
|
148
|
-
?
|
|
147
|
+
? products?.ci || new CredentialIntelligence(config, hashUtils)
|
|
149
148
|
: null;
|
|
150
149
|
return {
|
|
151
150
|
[ProductName.BOT_DEFENDER]: botDefender,
|
|
152
151
|
[ProductName.ACCOUNT_DEFENDER]: accountDefender,
|
|
153
|
-
[ProductName.CODE_DEFENDER]: products
|
|
152
|
+
[ProductName.CODE_DEFENDER]: products?.cd,
|
|
154
153
|
[ProductName.CREDENTIAL_INTELLIGENCE]: credentialIntelligence,
|
|
155
|
-
[ProductName.HYPE_SALE_CHALLENGE]: products
|
|
154
|
+
[ProductName.HYPE_SALE_CHALLENGE]: products?.hsc,
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
}
|
|
@@ -8,6 +8,7 @@ import { IRiskApiClient } from '../../risk_api';
|
|
|
8
8
|
import { IActivityClient } from '../../activities';
|
|
9
9
|
import { Products } from '../../products';
|
|
10
10
|
import { IGraphQLParser } from '../../graphql';
|
|
11
|
+
import { ILogServiceClient } from '../../logger';
|
|
11
12
|
export type EnforcerBaseOptions<Req, Res> = {
|
|
12
13
|
httpClient: IHttpClient;
|
|
13
14
|
base64Utils: IBase64Utils;
|
|
@@ -22,4 +23,5 @@ export type EnforcerBaseOptions<Req, Res> = {
|
|
|
22
23
|
telemetry?: ITelemetry<Req, Res>;
|
|
23
24
|
riskApiClient?: IRiskApiClient<Req, Res>;
|
|
24
25
|
activityClient?: IActivityClient<Req, Res>;
|
|
26
|
+
logServiceClient?: ILogServiceClient<Req, Res>;
|
|
25
27
|
};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { isRouteInPatterns } from '../utils';
|
|
11
2
|
import { HttpMethod } from '../http';
|
|
12
3
|
import { GraphQLOperationType } from './model';
|
|
13
4
|
export class DefaultGraphQLParser {
|
|
5
|
+
config;
|
|
6
|
+
graphqlRoutes;
|
|
7
|
+
sensitiveOperationTypes;
|
|
8
|
+
sensitiveOperationNames;
|
|
14
9
|
constructor(config) {
|
|
15
10
|
this.config = config;
|
|
16
11
|
this.graphqlRoutes = config.graphqlRoutes;
|
|
@@ -20,42 +15,38 @@ export class DefaultGraphQLParser {
|
|
|
20
15
|
isGraphQLRequest({ requestData }) {
|
|
21
16
|
return (requestData.method === HttpMethod.POST && isRouteInPatterns(requestData.url.pathname, this.graphqlRoutes));
|
|
22
17
|
}
|
|
23
|
-
parseGraphQLRequest({ requestData }) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
const data = this.parseGraphQLOperations(graphQLOperations);
|
|
32
|
-
if (!data || data.length === 0) {
|
|
33
|
-
this.config.logger.debug('unable to parse graphql operations');
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
this.config.logger.debug(`${data.length} graphql operation${data.length === 1 ? '' : 's'} parsed successfully`);
|
|
37
|
-
return data;
|
|
18
|
+
async parseGraphQLRequest({ requestData }) {
|
|
19
|
+
try {
|
|
20
|
+
const graphQLOperations = await this.getGraphQLOperationsFromBody(requestData);
|
|
21
|
+
if (!graphQLOperations) {
|
|
22
|
+
this.config.logger.debug('unable to get graphql operations from request body');
|
|
23
|
+
return null;
|
|
38
24
|
}
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
const data = this.parseGraphQLOperations(graphQLOperations);
|
|
26
|
+
if (!data || data.length === 0) {
|
|
27
|
+
this.config.logger.debug('unable to parse graphql operations');
|
|
41
28
|
return null;
|
|
42
29
|
}
|
|
43
|
-
|
|
30
|
+
this.config.logger.debug(`${data.length} graphql operation${data.length === 1 ? '' : 's'} parsed successfully`);
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
this.config.logger.debug(`unable to parse graphql request: ${e}`);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
44
37
|
}
|
|
45
|
-
getGraphQLOperationsFromBody({ request, }) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (!body) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return Array.isArray(body) ? body : [body];
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
this.config.logger.debug(`unable to parse body to json: ${e}`);
|
|
38
|
+
async getGraphQLOperationsFromBody({ request, }) {
|
|
39
|
+
try {
|
|
40
|
+
let body = await request.json();
|
|
41
|
+
if (!body) {
|
|
56
42
|
return null;
|
|
57
43
|
}
|
|
58
|
-
|
|
44
|
+
return Array.isArray(body) ? body : [body];
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
this.config.logger.debug(`unable to parse body to json: ${e}`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
59
50
|
}
|
|
60
51
|
parseGraphQLOperations(operations) {
|
|
61
52
|
return operations.map((operation) => this.parseGraphQlOperation(operation)).filter((x) => x);
|
package/lib/http/index.d.ts
CHANGED
package/lib/http/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncOrSync } from 'ts-essentials';
|
|
2
2
|
import { IFormData } from './IFormData';
|
|
3
|
+
import { IURLSearchParams } from './IURLSearchParams';
|
|
3
4
|
export interface IBody {
|
|
4
5
|
/**
|
|
5
6
|
* the unread body.
|
|
@@ -18,7 +19,7 @@ export interface IBody {
|
|
|
18
19
|
*/
|
|
19
20
|
text(): AsyncOrSync<string>;
|
|
20
21
|
/**
|
|
21
|
-
* Converts the body to
|
|
22
|
+
* Converts the body to a URL search params-like object (application/x-www-form-urlencoded)
|
|
22
23
|
*/
|
|
23
|
-
formUrlEncoded(): AsyncOrSync<
|
|
24
|
+
formUrlEncoded(): AsyncOrSync<IURLSearchParams>;
|
|
24
25
|
}
|
|
@@ -21,6 +21,10 @@ export interface IIncomingRequest<Req> extends IBody {
|
|
|
21
21
|
* Return the client IP provided by the environment or null.
|
|
22
22
|
*/
|
|
23
23
|
readonly clientIP: string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Http version provided by the environment if supported.
|
|
26
|
+
*/
|
|
27
|
+
readonly httpVersion?: string;
|
|
24
28
|
/**
|
|
25
29
|
* Returns the platform-specific request implementation of the request.
|
|
26
30
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface IURLSearchParams {
|
|
2
|
+
get(name: string): string;
|
|
3
|
+
getAll(name: string): string[];
|
|
4
|
+
set(name: string, value: string): void;
|
|
5
|
+
append(name: string, value: string): void;
|
|
6
|
+
delete(name: string): void;
|
|
7
|
+
has(name: string): boolean;
|
|
8
|
+
forEach(callback: (value: string, key: string, params?: IURLSearchParams, thisArg?: any) => void): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export class FormDataImpl {
|
|
2
|
+
data;
|
|
2
3
|
constructor(data) {
|
|
3
|
-
this.data = data
|
|
4
|
+
this.data = data ?? {};
|
|
4
5
|
}
|
|
5
6
|
append(name, value, fileName) {
|
|
6
7
|
this.data[name] = (this.data[name] || []).concat(value);
|
|
@@ -10,14 +11,13 @@ export class FormDataImpl {
|
|
|
10
11
|
}
|
|
11
12
|
forEach(callbackfn, thisArg) {
|
|
12
13
|
Object.entries(this.data).forEach(([key, values]) => {
|
|
13
|
-
values
|
|
14
|
+
values?.forEach((val) => {
|
|
14
15
|
callbackfn(val, key, this);
|
|
15
16
|
});
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
get(name) {
|
|
19
|
-
|
|
20
|
-
return ((_a = this.data[name]) === null || _a === void 0 ? void 0 : _a[0]) || null;
|
|
20
|
+
return this.data[name]?.[0] || null;
|
|
21
21
|
}
|
|
22
22
|
getAll(name) {
|
|
23
23
|
return this.data[name] || [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MinimalResponseImpl } from '../
|
|
1
|
+
import { MinimalResponseImpl } from '../utils';
|
|
2
2
|
export var MinimalResponseUtils;
|
|
3
3
|
(function (MinimalResponseUtils) {
|
|
4
4
|
MinimalResponseUtils.appendHeader = (response, name, value) => {
|
|
@@ -10,7 +10,7 @@ export var MinimalResponseUtils;
|
|
|
10
10
|
const body = response.body;
|
|
11
11
|
const statusCode = response.status;
|
|
12
12
|
const responseHeaders = response.headers;
|
|
13
|
-
const newHeaders =
|
|
13
|
+
const newHeaders = { ...responseHeaders };
|
|
14
14
|
Object.entries(headers).forEach(([name, values]) => {
|
|
15
15
|
newHeaders[name] = (newHeaders[name] || []).concat(values);
|
|
16
16
|
});
|
|
@@ -22,11 +22,9 @@ export var MinimalResponseUtils;
|
|
|
22
22
|
};
|
|
23
23
|
MinimalResponseUtils.from = (response) => {
|
|
24
24
|
return new (class {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.status = response.status;
|
|
29
|
-
}
|
|
25
|
+
body = response.body;
|
|
26
|
+
headers = response.headers;
|
|
27
|
+
status = response.status;
|
|
30
28
|
})();
|
|
31
29
|
};
|
|
32
30
|
})(MinimalResponseUtils || (MinimalResponseUtils = {}));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FormDataImpl } from '
|
|
1
|
+
import { FormDataImpl } from './FormDataImpl';
|
|
2
2
|
export var MultipartFormDataUtils;
|
|
3
3
|
(function (MultipartFormDataUtils) {
|
|
4
4
|
MultipartFormDataUtils.createFormDataWithoutFiles = (rawBody, contentType) => {
|
|
@@ -19,22 +19,21 @@ export var MultipartFormDataUtils;
|
|
|
19
19
|
return boundary.slice(BOUNDARY_PREFIX.length).trim();
|
|
20
20
|
};
|
|
21
21
|
MultipartFormDataUtils.parseMultipartBodyWithoutFiles = (boundary, rawBody) => {
|
|
22
|
-
var _a, _b, _c, _d, _e, _f;
|
|
23
22
|
if (!rawBody || !boundary) {
|
|
24
23
|
return null;
|
|
25
24
|
}
|
|
26
25
|
const body = {};
|
|
27
26
|
const entries = rawBody.split(boundary);
|
|
28
27
|
for (const item of entries) {
|
|
29
|
-
const filename =
|
|
28
|
+
const filename = item.match(/filename="(.+?)"/)?.[1]?.trim();
|
|
30
29
|
if (filename) {
|
|
31
30
|
continue;
|
|
32
31
|
}
|
|
33
|
-
const name =
|
|
32
|
+
const name = item.match(/name="(.+?)"/)?.[1]?.trim();
|
|
34
33
|
if (!name) {
|
|
35
34
|
continue;
|
|
36
35
|
}
|
|
37
|
-
const value =
|
|
36
|
+
const value = item.match(/\r\n\r\n([^\r\n\v]*)\r\n--$/)?.[1]?.trim();
|
|
38
37
|
if (!value) {
|
|
39
38
|
continue;
|
|
40
39
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IURL, IURLSearchParams } from '../interfaces';
|
|
2
|
+
export declare namespace URLUtils {
|
|
3
|
+
const parseURL: (rawUrl: string) => IURL;
|
|
4
|
+
const parseSearchParams: (search: string) => IURLSearchParams;
|
|
5
|
+
const decodeUriComponent: (input: string) => string;
|
|
6
|
+
const encodeUriComponent: (input: string) => string;
|
|
7
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { UrlImpl } from './UrlImpl';
|
|
2
|
+
import { UrlSearchParamsImpl } from './UrlSearchParamsImpl';
|
|
3
|
+
export var URLUtils;
|
|
4
|
+
(function (URLUtils) {
|
|
5
|
+
URLUtils.parseURL = (rawUrl) => {
|
|
6
|
+
return global?.URL ? new URL(rawUrl) : new UrlImpl(rawUrl);
|
|
7
|
+
};
|
|
8
|
+
URLUtils.parseSearchParams = (search) => {
|
|
9
|
+
return global?.URLSearchParams ? new URLSearchParams(search) : new UrlSearchParamsImpl(search);
|
|
10
|
+
};
|
|
11
|
+
URLUtils.decodeUriComponent = (input) => {
|
|
12
|
+
return global?.decodeURIComponent ? decodeURIComponent(input) : decodeUriComponentPolyfill(input);
|
|
13
|
+
};
|
|
14
|
+
URLUtils.encodeUriComponent = (input) => {
|
|
15
|
+
return global?.encodeURIComponent ? encodeURIComponent(input) : encodeUriComponentPolyfill(input);
|
|
16
|
+
};
|
|
17
|
+
const decodeUriComponentPolyfill = (input) => {
|
|
18
|
+
// https://www.npmjs.com/package/as-uri-encode-decode
|
|
19
|
+
// Note: Does not work well with multibyte characters
|
|
20
|
+
let result = '';
|
|
21
|
+
for (let i = 0; i < input.length; i++) {
|
|
22
|
+
if (input.charAt(i) === '+') {
|
|
23
|
+
result += ' ';
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (input.charAt(i) === '%' && input.charAt(i + 1) !== '%' && input.charAt(i + 2) !== '%') {
|
|
27
|
+
const charCode = parseInt(input.charAt(i + 1) + input.charAt(i + 2), 16);
|
|
28
|
+
const char = String.fromCharCode(charCode);
|
|
29
|
+
result += char;
|
|
30
|
+
i += 2;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
result += input.charAt(i);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
const encodeUriComponentPolyfill = (input) => {
|
|
38
|
+
// https://www.npmjs.com/package/as-uri-encode-decode
|
|
39
|
+
// Note: Does not work well with multibyte characters
|
|
40
|
+
let result = '';
|
|
41
|
+
for (let i = 0; i < input.length; i++) {
|
|
42
|
+
const c = input.charAt(i);
|
|
43
|
+
if (isSafe(c)) {
|
|
44
|
+
result += c;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
result += '%' + c.charCodeAt(0).toString(16).toUpperCase();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
const isSafe = (c) => {
|
|
53
|
+
return ((c >= 'a' && c <= 'z') ||
|
|
54
|
+
(c >= 'A' && c <= 'Z') ||
|
|
55
|
+
(c >= '0' && c <= '9') ||
|
|
56
|
+
c == '-' ||
|
|
57
|
+
c == '_' ||
|
|
58
|
+
c == '.' ||
|
|
59
|
+
c == '*' ||
|
|
60
|
+
c == '!');
|
|
61
|
+
};
|
|
62
|
+
})(URLUtils || (URLUtils = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IURL, IURLSearchParams } from '../interfaces';
|
|
2
|
+
export declare class UrlImpl implements IURL {
|
|
3
|
+
protocol: string;
|
|
4
|
+
hostname: string;
|
|
5
|
+
pathname: string;
|
|
6
|
+
search: string;
|
|
7
|
+
hash: string;
|
|
8
|
+
protected _port: string;
|
|
9
|
+
constructor(rawUrl: string);
|
|
10
|
+
get href(): string;
|
|
11
|
+
get origin(): string;
|
|
12
|
+
get host(): string;
|
|
13
|
+
set host(newHost: string);
|
|
14
|
+
get port(): string;
|
|
15
|
+
set port(port: string);
|
|
16
|
+
get searchParams(): IURLSearchParams;
|
|
17
|
+
private isDefaultPort;
|
|
18
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { URL_REGEX } from '../../utils';
|
|
2
|
+
import { URLUtils } from './URLUtils';
|
|
3
|
+
export class UrlImpl {
|
|
4
|
+
protocol;
|
|
5
|
+
hostname;
|
|
6
|
+
pathname;
|
|
7
|
+
search;
|
|
8
|
+
hash;
|
|
9
|
+
_port;
|
|
10
|
+
constructor(rawUrl) {
|
|
11
|
+
const match = rawUrl.match(URL_REGEX);
|
|
12
|
+
if (!match) {
|
|
13
|
+
throw new Error(`Invalid UrlImpl: ${rawUrl}`);
|
|
14
|
+
}
|
|
15
|
+
this.protocol = match[1];
|
|
16
|
+
this.hostname = match[3];
|
|
17
|
+
this.port = match[4] || '';
|
|
18
|
+
this.pathname = match[5] || '/';
|
|
19
|
+
this.search = match[6] || '';
|
|
20
|
+
this.hash = match[7] || '';
|
|
21
|
+
}
|
|
22
|
+
get href() {
|
|
23
|
+
return `${this.origin}${this.pathname}${this.search}${this.hash}`;
|
|
24
|
+
}
|
|
25
|
+
get origin() {
|
|
26
|
+
return `${this.protocol}//${this.host}`;
|
|
27
|
+
}
|
|
28
|
+
get host() {
|
|
29
|
+
return `${this.hostname}${this.port ? `:${this.port}` : ''}`;
|
|
30
|
+
}
|
|
31
|
+
set host(newHost) {
|
|
32
|
+
const [host, port] = newHost.split(':');
|
|
33
|
+
this.hostname = host;
|
|
34
|
+
this.port = port;
|
|
35
|
+
}
|
|
36
|
+
get port() {
|
|
37
|
+
return this._port;
|
|
38
|
+
}
|
|
39
|
+
set port(port) {
|
|
40
|
+
if (port) {
|
|
41
|
+
this._port = this.isDefaultPort(port) ? '' : port;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
get searchParams() {
|
|
45
|
+
return URLUtils.parseSearchParams(this.search);
|
|
46
|
+
}
|
|
47
|
+
isDefaultPort(port) {
|
|
48
|
+
const PROTOCOL_TO_DEFAULT_PORT = {
|
|
49
|
+
'https:': '443',
|
|
50
|
+
'http:': '80',
|
|
51
|
+
};
|
|
52
|
+
return PROTOCOL_TO_DEFAULT_PORT[this.protocol] === port;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IURLSearchParams } from '../interfaces';
|
|
2
|
+
export declare class UrlSearchParamsImpl implements IURLSearchParams {
|
|
3
|
+
private _searchParamsArray;
|
|
4
|
+
private _searchParamsMap;
|
|
5
|
+
constructor(init?: string | Record<string, string | string[]> | [string, string][]);
|
|
6
|
+
append(name: string, value: any): void;
|
|
7
|
+
delete(name: string): void;
|
|
8
|
+
forEach(callback: (value: string, key: string, params?: IURLSearchParams, thisArg?: any) => void): void;
|
|
9
|
+
get(name: string): string | null;
|
|
10
|
+
getAll(name: string): string[];
|
|
11
|
+
has(name: string): boolean;
|
|
12
|
+
set(name: string, value: any): void;
|
|
13
|
+
toString(): string;
|
|
14
|
+
private _constructSearchParamsFromString;
|
|
15
|
+
private _constructSearchParamsFromArray;
|
|
16
|
+
private _constructSearchParamsFromObject;
|
|
17
|
+
private _saveParam;
|
|
18
|
+
private _storeParamInSearchParamsMap;
|
|
19
|
+
}
|