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
|
@@ -2,6 +2,7 @@ import { ContentType, CONTENT_TYPE_HEADER_NAME, MinimalResponseImpl } from '../.
|
|
|
2
2
|
import { createBlockData, renderHtml } from '../utils';
|
|
3
3
|
import { CAPTCHA_TEMPLATE } from '../templates';
|
|
4
4
|
export class HtmlCaptchaBlocker {
|
|
5
|
+
config;
|
|
5
6
|
constructor(config) {
|
|
6
7
|
this.config = config;
|
|
7
8
|
}
|
|
@@ -3,7 +3,7 @@ import { ReadonlyContext } from '../../../../context';
|
|
|
3
3
|
import { IConditionalBlocker } from '../../../../blocker';
|
|
4
4
|
import { IMinimalResponse } from '../../../../http';
|
|
5
5
|
export declare class JsonCaptchaBlocker<Req, Res> implements IConditionalBlocker<Req, Res> {
|
|
6
|
-
|
|
6
|
+
protected readonly config: IConfiguration<Req, Res>;
|
|
7
7
|
constructor(config: IConfiguration<Req, Res>);
|
|
8
8
|
shouldBlock(context: ReadonlyContext<Req, Res>): boolean;
|
|
9
9
|
createBlockResponse(context: ReadonlyContext<Req, Res>): IMinimalResponse;
|
|
@@ -2,6 +2,7 @@ import { BlockAction } from '../../../../blocker';
|
|
|
2
2
|
import { ContentType, CONTENT_TYPE_HEADER_NAME, ACCEPT_HEADER_NAME, MinimalResponseImpl, } from '../../../../http';
|
|
3
3
|
import { createBlockData } from '../utils';
|
|
4
4
|
export class JsonCaptchaBlocker {
|
|
5
|
+
config;
|
|
5
6
|
constructor(config) {
|
|
6
7
|
this.config = config;
|
|
7
8
|
}
|
|
@@ -9,10 +10,10 @@ export class JsonCaptchaBlocker {
|
|
|
9
10
|
if (!this.config.advancedBlockingResponseEnabled) {
|
|
10
11
|
return false;
|
|
11
12
|
}
|
|
12
|
-
const acceptHeaderValue = context.requestData.request.headers.get(ACCEPT_HEADER_NAME) ||
|
|
13
|
-
|
|
14
|
-
''
|
|
15
|
-
|
|
13
|
+
const acceptHeaderValue = context.requestData.request.headers.get(ACCEPT_HEADER_NAME) || '';
|
|
14
|
+
const acceptHeaderContainsJson = acceptHeaderValue
|
|
15
|
+
?.split(',')
|
|
16
|
+
.some((value) => value.toLowerCase() === ContentType.APPLICATION_JSON);
|
|
16
17
|
return !context.isMobile && context.blockAction !== BlockAction.RATE_LIMIT && acceptHeaderContainsJson;
|
|
17
18
|
}
|
|
18
19
|
createBlockResponse(context) {
|
|
@@ -4,8 +4,8 @@ import { IBase64Utils } from '../../../../utils';
|
|
|
4
4
|
import { IConditionalBlocker } from '../../../../blocker';
|
|
5
5
|
import { IMinimalResponse } from '../../../../http';
|
|
6
6
|
export declare class MobileCaptchaBlocker<Req, Res> implements IConditionalBlocker<Req, Res> {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
protected readonly config: IConfiguration<Req, Res>;
|
|
8
|
+
protected readonly base64Utils: IBase64Utils;
|
|
9
9
|
constructor(config: IConfiguration<Req, Res>, base64Utils: IBase64Utils);
|
|
10
10
|
shouldBlock(context: ReadonlyContext<Req, Res>): boolean;
|
|
11
11
|
createBlockResponse(context: ReadonlyContext<Req, Res>): IMinimalResponse;
|
|
@@ -3,6 +3,8 @@ import { ContentType, CONTENT_TYPE_HEADER_NAME, MinimalResponseImpl } from '../.
|
|
|
3
3
|
import { createBlockData, renderHtml } from '../utils';
|
|
4
4
|
import { CAPTCHA_TEMPLATE } from '../templates';
|
|
5
5
|
export class MobileCaptchaBlocker {
|
|
6
|
+
config;
|
|
7
|
+
base64Utils;
|
|
6
8
|
constructor(config, base64Utils) {
|
|
7
9
|
this.config = config;
|
|
8
10
|
this.base64Utils = base64Utils;
|
|
@@ -12,7 +12,6 @@ export const renderHtml = (htmlTemplate, blockData) => {
|
|
|
12
12
|
return htmlTemplate;
|
|
13
13
|
};
|
|
14
14
|
export const createBlockData = (config, context) => {
|
|
15
|
-
var _a, _b;
|
|
16
15
|
const captchaScriptSuffix = '/captcha.js';
|
|
17
16
|
const captchaParams = `?a=${context.blockAction}&u=${context.uuid}&v=${context.vid || ''}&m=${context.isMobile ? '1' : '0'}`;
|
|
18
17
|
let jsClientSrc = `${config.backendClientUrl}/${config.appId}/main.min.js`;
|
|
@@ -28,7 +27,7 @@ export const createBlockData = (config, context) => {
|
|
|
28
27
|
const altBlockScript = `${config.altBackendCaptchaUrl}/${config.appId}${captchaScriptSuffix}${captchaParams}`;
|
|
29
28
|
return {
|
|
30
29
|
appId: config.appId,
|
|
31
|
-
vid: context.vid ||
|
|
30
|
+
vid: context.vid || context.requestData?.cookies?.[PXVID_COOKIE_NAME] || '',
|
|
32
31
|
uuid: context.uuid || '',
|
|
33
32
|
isMobile: context.isMobile,
|
|
34
33
|
customLogo: config.customLogo || '',
|
|
@@ -2,6 +2,8 @@ import { HttpMethod } from '../../../http';
|
|
|
2
2
|
import { FilterReason } from '../../../filter';
|
|
3
3
|
import { getExtension, isRouteInPatterns } from '../../../utils';
|
|
4
4
|
export class DefaultBotDefenderFilter {
|
|
5
|
+
config;
|
|
6
|
+
ipRangeChecker;
|
|
5
7
|
constructor(config, ipRangeChecker) {
|
|
6
8
|
this.config = config;
|
|
7
9
|
this.ipRangeChecker = ipRangeChecker;
|
|
@@ -9,7 +11,11 @@ export class DefaultBotDefenderFilter {
|
|
|
9
11
|
shouldFilter(context) {
|
|
10
12
|
const { requestData } = context;
|
|
11
13
|
const filterReason = this.getFilterReason(requestData);
|
|
12
|
-
|
|
14
|
+
if (filterReason !== FilterReason.NONE) {
|
|
15
|
+
this.config.logger.debug(`filter request due to ${filterReason}`);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
13
19
|
}
|
|
14
20
|
getFilterReason(request) {
|
|
15
21
|
if (this.shouldFilterByExtension(request)) {
|
|
@@ -1,61 +1,47 @@
|
|
|
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 { removeSensitiveHeaders } from '../../../utils';
|
|
11
|
-
import { COOKIE_HEADER_NAME, HOST_HEADER_NAME, X_FORWARDED_FOR_HEADER_NAME, OutgoingRequestImpl, MinimalResponseImpl, toMutableHeaders, } from '../../../http';
|
|
2
|
+
import { COOKIE_HEADER_NAME, HOST_HEADER_NAME, X_FORWARDED_FOR_HEADER_NAME, OutgoingRequestImpl, MinimalResponseImpl, toMutableHeaders, URLUtils, } from '../../../http';
|
|
12
3
|
import { getFirstPartyCaptchaScriptPathPrefixes, getFirstPartySensorScriptPaths, getFirstPartyXhrPathPrefixes, } from './utils';
|
|
13
4
|
import { DEFAULT_CLIENT_RESPONSE_OPTIONS, DEFAULT_GIF_RESPONSE, DEFAULT_XHR_RESPONSE, FIRST_PARTY_HEADER_NAME, FIRST_PARTY_HEADER_VALUE, X_PX_ENFORCER_TRUE_IP_HEADER_NAME, } from './constants';
|
|
14
5
|
import { FirstPartySuffix } from './FirstPartySuffix';
|
|
15
6
|
export class DefaultBotDefenderFirstParty {
|
|
7
|
+
config;
|
|
16
8
|
constructor(config) {
|
|
17
9
|
this.config = config;
|
|
18
10
|
}
|
|
19
|
-
handleFirstPartyRequest(context) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return null;
|
|
34
|
-
});
|
|
11
|
+
async handleFirstPartyRequest(context) {
|
|
12
|
+
const { pathname } = context.requestData.url;
|
|
13
|
+
if (getFirstPartySensorScriptPaths(this.config).includes(pathname)) {
|
|
14
|
+
return await this.proxySensorScriptRequest(context);
|
|
15
|
+
}
|
|
16
|
+
const xhrPrefix = getFirstPartyXhrPathPrefixes(this.config).find((prefix) => pathname.startsWith(prefix));
|
|
17
|
+
if (xhrPrefix) {
|
|
18
|
+
return await this.proxyXhrRequest(context, xhrPrefix);
|
|
19
|
+
}
|
|
20
|
+
const captchaPrefix = getFirstPartyCaptchaScriptPathPrefixes(this.config).find((prefix) => pathname.startsWith(prefix));
|
|
21
|
+
if (captchaPrefix) {
|
|
22
|
+
return await this.proxyCaptchaScriptRequest(context);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
35
25
|
}
|
|
36
|
-
proxySensorScriptRequest(context) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return { request, defaultResponse };
|
|
46
|
-
});
|
|
26
|
+
async proxySensorScriptRequest(context) {
|
|
27
|
+
const defaultResponse = new MinimalResponseImpl(DEFAULT_CLIENT_RESPONSE_OPTIONS);
|
|
28
|
+
if (!this.config.firstPartyEnabled) {
|
|
29
|
+
return { defaultResponse };
|
|
30
|
+
}
|
|
31
|
+
const url = this.getThirdPartySensorScriptUrl();
|
|
32
|
+
const request = await this.getOutgoingRequest(url, context);
|
|
33
|
+
this.config.logger.debug(`proxying first party sensor script ${context.requestData.url.pathname} to ${url}`);
|
|
34
|
+
return { request, defaultResponse };
|
|
47
35
|
}
|
|
48
|
-
proxyXhrRequest(context, prefix) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return { request, defaultResponse };
|
|
58
|
-
});
|
|
36
|
+
async proxyXhrRequest(context, prefix) {
|
|
37
|
+
const defaultResponse = DefaultBotDefenderFirstParty.getDefaultXhrResponse(context.requestData.url.pathname);
|
|
38
|
+
if (!this.config.firstPartyEnabled) {
|
|
39
|
+
return { defaultResponse };
|
|
40
|
+
}
|
|
41
|
+
const url = this.getThirdPartyXhrUrl(context, prefix);
|
|
42
|
+
const request = await this.getOutgoingRequest(url, context);
|
|
43
|
+
this.config.logger.debug(`proxying first party XHR request ${context.requestData.url.pathname} to ${url}`);
|
|
44
|
+
return { request, defaultResponse };
|
|
59
45
|
}
|
|
60
46
|
static getDefaultXhrResponse(path) {
|
|
61
47
|
const { content, options } = path.endsWith('.gif') ? DEFAULT_GIF_RESPONSE : DEFAULT_XHR_RESPONSE;
|
|
@@ -65,26 +51,22 @@ export class DefaultBotDefenderFirstParty {
|
|
|
65
51
|
headers: options.headers,
|
|
66
52
|
});
|
|
67
53
|
}
|
|
68
|
-
proxyCaptchaScriptRequest(context) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return { request, defaultResponse };
|
|
78
|
-
});
|
|
54
|
+
async proxyCaptchaScriptRequest(context) {
|
|
55
|
+
const defaultResponse = new MinimalResponseImpl(DEFAULT_CLIENT_RESPONSE_OPTIONS);
|
|
56
|
+
if (!this.config.firstPartyEnabled) {
|
|
57
|
+
return { defaultResponse };
|
|
58
|
+
}
|
|
59
|
+
const url = this.getThirdPartyCaptchaScriptUrl(context);
|
|
60
|
+
const request = await this.getOutgoingRequest(url, context);
|
|
61
|
+
this.config.logger.debug(`proxying first party captcha script ${context.requestData.url.pathname} to ${url}`);
|
|
62
|
+
return { request, defaultResponse };
|
|
79
63
|
}
|
|
80
|
-
getOutgoingRequest(url, { requestData, vid }) {
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
body: requestData.request.body,
|
|
87
|
-
});
|
|
64
|
+
async getOutgoingRequest(url, { requestData, vid }) {
|
|
65
|
+
return new OutgoingRequestImpl({
|
|
66
|
+
url: url,
|
|
67
|
+
method: requestData.method,
|
|
68
|
+
headers: this.prepareFirstPartyHeaders(url, requestData, vid),
|
|
69
|
+
body: requestData.request.body,
|
|
88
70
|
});
|
|
89
71
|
}
|
|
90
72
|
prepareFirstPartyHeaders(url, requestData, vid) {
|
|
@@ -105,7 +87,8 @@ export class DefaultBotDefenderFirstParty {
|
|
|
105
87
|
return headers;
|
|
106
88
|
}
|
|
107
89
|
setHostHeader(headers, url) {
|
|
108
|
-
|
|
90
|
+
const { host } = URLUtils.parseURL(url);
|
|
91
|
+
headers[HOST_HEADER_NAME] = [host];
|
|
109
92
|
}
|
|
110
93
|
setXffHeader(headers, ip) {
|
|
111
94
|
const xffValue = headers[X_FORWARDED_FOR_HEADER_NAME] || [];
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { ContentType } from '../../../http';
|
|
2
2
|
import { MinimalResponseOptions } from '../../../http';
|
|
3
|
-
export declare const EMPTY_GIF: number[];
|
|
4
3
|
export declare const X_PX_ENFORCER_TRUE_IP_HEADER_NAME = "x-px-enforcer-true-ip";
|
|
5
4
|
export declare const FIRST_PARTY_HEADER_NAME = "x-px-first-party";
|
|
6
5
|
export declare const FIRST_PARTY_HEADER_VALUE = "1";
|
|
7
|
-
export declare const FIRST_PARTY_SENSOR_SUFFIX = "/init.js";
|
|
8
|
-
export declare const FIRST_PARTY_CAPTCHA_SUFFIX = "/captcha";
|
|
9
|
-
export declare const FIRST_PARTY_XHR_SUFFIX = "/xhr";
|
|
10
6
|
export declare const DEFAULT_CLIENT_RESPONSE_OPTIONS: MinimalResponseOptions;
|
|
11
7
|
export declare const DEFAULT_XHR_RESPONSE: {
|
|
12
8
|
content: string;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { ContentType, CONTENT_TYPE_HEADER_NAME } from '../../../http';
|
|
2
|
-
export const EMPTY_GIF = [
|
|
3
|
-
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
|
4
|
-
0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b,
|
|
5
|
-
];
|
|
6
2
|
export const X_PX_ENFORCER_TRUE_IP_HEADER_NAME = 'x-px-enforcer-true-ip';
|
|
7
3
|
export const FIRST_PARTY_HEADER_NAME = 'x-px-first-party';
|
|
8
4
|
export const FIRST_PARTY_HEADER_VALUE = '1';
|
|
9
|
-
export const FIRST_PARTY_SENSOR_SUFFIX = '/init.js';
|
|
10
|
-
export const FIRST_PARTY_CAPTCHA_SUFFIX = '/captcha';
|
|
11
|
-
export const FIRST_PARTY_XHR_SUFFIX = '/xhr';
|
|
12
5
|
export const DEFAULT_CLIENT_RESPONSE_OPTIONS = {
|
|
13
6
|
body: '',
|
|
14
7
|
status: 200,
|
|
@@ -1,76 +1,56 @@
|
|
|
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 { Action } from '../../action';
|
|
11
|
-
import { ActivityType,
|
|
2
|
+
import { ActivityType, createAsyncActivity, ACTIVITIES_ENDPOINT } from '../../activities';
|
|
12
3
|
import { CredentialEndpoint, CredentialEndpointManager, CredentialExtractorFactory, CredentialIntelligenceEndpointMatcherFactory, CredentialIntelligenceHashProtocolFactory, LoginSuccessfulParserFactory, } from './endpoint';
|
|
13
4
|
import { ADDITIONAL_S2S_ACTIVITY_HEADER_NAME, ADDITIONAL_S2S_URL_HEADER_NAME, COMPROMISED_CREDENTIALS_HEADER_VALUE, } from './constants';
|
|
14
5
|
export class CredentialIntelligence {
|
|
6
|
+
config;
|
|
7
|
+
endpointManager;
|
|
15
8
|
constructor(config, hashUtils) {
|
|
16
9
|
this.config = config;
|
|
17
10
|
this.endpointManager = new CredentialEndpointManager(this.initializeCredentialIntelligenceEndpoints(config, hashUtils));
|
|
18
11
|
}
|
|
19
|
-
enrichContextFromRequest(context) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return Object.assign(Object.assign({}, data), { endpointIndex, action: Action.TRIGGER_RISK_API, reason: 'sensitive_route' });
|
|
30
|
-
});
|
|
12
|
+
async enrichContextFromRequest(context) {
|
|
13
|
+
const endpointIndex = this.endpointManager.getEndpointIndex(context);
|
|
14
|
+
if (endpointIndex === -1) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const data = await this.endpointManager.getCredentialsData(endpointIndex, context);
|
|
18
|
+
if (!data) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return { ...data, endpointIndex, action: Action.TRIGGER_RISK_API, reason: 'sensitive_route' };
|
|
31
22
|
}
|
|
32
|
-
enrichContextFromRiskApi(context) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const isCompromised = !!((_b = (_a = context.riskApiData.riskResponse) === null || _a === void 0 ? void 0 : _a.dataEnrichment) === null || _b === void 0 ? void 0 : _b.breached_account);
|
|
39
|
-
return { action: undefined, reason: undefined, isCompromised };
|
|
40
|
-
});
|
|
23
|
+
async enrichContextFromRiskApi(context) {
|
|
24
|
+
if (!context.productData.ci) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const isCompromised = !!context.riskApiData.riskResponse?.dataEnrichment?.breached_account;
|
|
28
|
+
return { action: undefined, reason: undefined, isCompromised };
|
|
41
29
|
}
|
|
42
|
-
modifyIncomingRequest(context) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
});
|
|
30
|
+
async modifyIncomingRequest(context) {
|
|
31
|
+
if (!context.productData.ci) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const { productData: { ci: { isCompromised }, }, requestData: { request }, } = context;
|
|
35
|
+
if (isCompromised) {
|
|
36
|
+
this.setCompromisedCredentialHeader(request);
|
|
37
|
+
}
|
|
38
|
+
if (this.shouldSetAdditionalS2SActivityHeaders()) {
|
|
39
|
+
this.setAdditionalS2SActivityHeaders(request, context);
|
|
40
|
+
}
|
|
55
41
|
}
|
|
56
|
-
enrichContextFromResponse(context) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return { isLoginSuccessful: yield this.isLoginSuccessful(context) };
|
|
62
|
-
});
|
|
42
|
+
async enrichContextFromResponse(context) {
|
|
43
|
+
if (!context.productData.ci) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
return { isLoginSuccessful: await this.isLoginSuccessful(context) };
|
|
63
47
|
}
|
|
64
|
-
modifyOutgoingResponse(context) {
|
|
65
|
-
|
|
66
|
-
// intentionally left blank
|
|
67
|
-
});
|
|
48
|
+
async modifyOutgoingResponse(context) {
|
|
49
|
+
// intentionally left blank
|
|
68
50
|
}
|
|
69
|
-
isLoginSuccessful(context) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return yield this.endpointManager.isLoginSuccessful(endpointIndex, context);
|
|
73
|
-
});
|
|
51
|
+
async isLoginSuccessful(context) {
|
|
52
|
+
const { endpointIndex } = context.productData.ci;
|
|
53
|
+
return await this.endpointManager.isLoginSuccessful(endpointIndex, context);
|
|
74
54
|
}
|
|
75
55
|
setCompromisedCredentialHeader(request) {
|
|
76
56
|
request.headers.set(this.config.ciCompromisedCredentialsHeaderName, COMPROMISED_CREDENTIALS_HEADER_VALUE);
|
|
@@ -79,16 +59,15 @@ export class CredentialIntelligence {
|
|
|
79
59
|
return !this.config.ciAutomaticAdditionalS2SEnabled && this.config.ciAdditionalS2SHeaderEnabled;
|
|
80
60
|
}
|
|
81
61
|
setAdditionalS2SActivityHeaders(request, context) {
|
|
82
|
-
const activity =
|
|
62
|
+
const activity = createAsyncActivity(ActivityType.ADDITIONAL_S2S, this.config, context);
|
|
83
63
|
request.headers.set(ADDITIONAL_S2S_ACTIVITY_HEADER_NAME, JSON.stringify(activity));
|
|
84
64
|
request.headers.set(ADDITIONAL_S2S_URL_HEADER_NAME, `${this.config.backendCollectorUrl}${ACTIVITIES_ENDPOINT}`);
|
|
85
65
|
}
|
|
86
66
|
initializeCredentialIntelligenceEndpoints(config, hashUtils) {
|
|
87
67
|
return config.ciEndpoints.map((endpointConfig) => {
|
|
88
|
-
var _a;
|
|
89
68
|
const matcher = CredentialIntelligenceEndpointMatcherFactory.create(endpointConfig);
|
|
90
69
|
const extractor = CredentialExtractorFactory.create(endpointConfig);
|
|
91
|
-
const protocol = CredentialIntelligenceHashProtocolFactory.create((
|
|
70
|
+
const protocol = CredentialIntelligenceHashProtocolFactory.create((endpointConfig.protocol ?? config.ciDefaultVersion), hashUtils);
|
|
92
71
|
const loginSuccessfulParser = LoginSuccessfulParserFactory.create(config, endpointConfig);
|
|
93
72
|
return new CredentialEndpoint(config, matcher, extractor, protocol, loginSuccessfulParser);
|
|
94
73
|
});
|
|
@@ -1,13 +1,9 @@
|
|
|
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
|
export class CredentialEndpoint {
|
|
2
|
+
config;
|
|
3
|
+
matcher;
|
|
4
|
+
extractor;
|
|
5
|
+
protocol;
|
|
6
|
+
loginSuccessfulParser;
|
|
11
7
|
constructor(config, matcher, extractor, protocol, loginSuccessfulParser) {
|
|
12
8
|
this.config = config;
|
|
13
9
|
this.matcher = matcher;
|
|
@@ -18,20 +14,16 @@ export class CredentialEndpoint {
|
|
|
18
14
|
matches(requestData) {
|
|
19
15
|
return this.matcher.matches(requestData);
|
|
20
16
|
}
|
|
21
|
-
getCredentialData(request) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return yield this.protocol.hashCredentials(credentials);
|
|
30
|
-
});
|
|
17
|
+
async getCredentialData(request) {
|
|
18
|
+
const credentials = await this.extractor.extractCredentials(request);
|
|
19
|
+
if (!credentials?.user && !credentials?.pass) {
|
|
20
|
+
this.config.logger.debug('unable to extract credentials');
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
this.config.logger.debug(`successfully extracted credentials`);
|
|
24
|
+
return await this.protocol.hashCredentials(credentials);
|
|
31
25
|
}
|
|
32
|
-
isLoginSuccessful(response) {
|
|
33
|
-
return
|
|
34
|
-
return this.loginSuccessfulParser.isLoginSuccessful(response);
|
|
35
|
-
});
|
|
26
|
+
async isLoginSuccessful(response) {
|
|
27
|
+
return this.loginSuccessfulParser.isLoginSuccessful(response);
|
|
36
28
|
}
|
|
37
29
|
}
|
|
@@ -1,32 +1,19 @@
|
|
|
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
|
export class CredentialEndpointManager {
|
|
2
|
+
config;
|
|
3
|
+
endpoints;
|
|
11
4
|
constructor(endpoints) {
|
|
12
5
|
this.endpoints = endpoints;
|
|
13
6
|
}
|
|
14
7
|
getEndpointIndex({ requestData }) {
|
|
15
8
|
return this.endpoints.findIndex((endpoint) => endpoint.matches(requestData));
|
|
16
9
|
}
|
|
17
|
-
getCredentialsData(endpointIndex, { requestData }) {
|
|
18
|
-
|
|
19
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
return yield ((_a = this.endpoints[endpointIndex]) === null || _a === void 0 ? void 0 : _a.getCredentialData(requestData.request));
|
|
21
|
-
});
|
|
10
|
+
async getCredentialsData(endpointIndex, { requestData }) {
|
|
11
|
+
return await this.endpoints[endpointIndex]?.getCredentialData(requestData.request);
|
|
22
12
|
}
|
|
23
|
-
isLoginSuccessful(endpointIndex, { response }) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
return yield ((_a = this.endpoints[endpointIndex]) === null || _a === void 0 ? void 0 : _a.isLoginSuccessful(response));
|
|
30
|
-
});
|
|
13
|
+
async isLoginSuccessful(endpointIndex, { response }) {
|
|
14
|
+
if (!response) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return await this.endpoints[endpointIndex]?.isLoginSuccessful(response);
|
|
31
18
|
}
|
|
32
19
|
}
|
package/lib/products/credential_intelligence/endpoint/extractor/BodyCredentialExtractor.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { DeepReadonly } from 'ts-essentials';
|
|
2
|
-
import { IFormData, IIncomingRequest } from '../../../../http';
|
|
2
|
+
import { IFormData, IIncomingRequest, IURLSearchParams } from '../../../../http';
|
|
3
3
|
import { Credentials } from '../../model';
|
|
4
4
|
import { ICredentialExtractor } from './ICredentialExtractor';
|
|
5
|
-
export declare class BodyCredentialExtractor implements ICredentialExtractor<
|
|
5
|
+
export declare class BodyCredentialExtractor<Req> implements ICredentialExtractor<Req> {
|
|
6
6
|
private readonly userField;
|
|
7
7
|
private readonly passField;
|
|
8
8
|
constructor(userField: string, passField: string);
|
|
9
|
-
extractCredentials(request: DeepReadonly<IIncomingRequest<
|
|
10
|
-
protected extractFromBody(contentType: string, request: DeepReadonly<IIncomingRequest<
|
|
9
|
+
extractCredentials(request: DeepReadonly<IIncomingRequest<Req>>): Promise<Credentials | null>;
|
|
10
|
+
protected extractFromBody(contentType: string, request: DeepReadonly<IIncomingRequest<Req>>): Promise<Credentials>;
|
|
11
11
|
protected extractFromJson(json: any): Credentials;
|
|
12
|
-
protected extractFromUrlEncoded(params:
|
|
12
|
+
protected extractFromUrlEncoded(params: IURLSearchParams): Credentials;
|
|
13
13
|
protected extractFromMultipart(formData: IFormData): Credentials;
|
|
14
14
|
private formDataEntryValueToString;
|
|
15
15
|
}
|
|
@@ -1,44 +1,33 @@
|
|
|
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 { CONTENT_TYPE_HEADER_NAME, ContentType } from '../../../../http';
|
|
11
2
|
import { getPropertyFromObject } from '../../../../utils';
|
|
12
3
|
export class BodyCredentialExtractor {
|
|
4
|
+
userField;
|
|
5
|
+
passField;
|
|
13
6
|
constructor(userField, passField) {
|
|
14
7
|
this.userField = userField;
|
|
15
8
|
this.passField = passField;
|
|
16
9
|
}
|
|
17
|
-
extractCredentials(request) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
catch (e) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
extractFromBody(contentType, request) {
|
|
30
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
-
if (contentType.includes('json')) {
|
|
32
|
-
return this.extractFromJson(yield request.json());
|
|
33
|
-
}
|
|
34
|
-
else if (contentType.includes(ContentType.APPLICATION_X_WWW_FORM_URL_ENCODED)) {
|
|
35
|
-
return this.extractFromUrlEncoded(yield request.formUrlEncoded());
|
|
36
|
-
}
|
|
37
|
-
else if (contentType.includes(ContentType.MULTIPART_FORM_DATA)) {
|
|
38
|
-
return this.extractFromMultipart(yield request.formData());
|
|
39
|
-
}
|
|
10
|
+
async extractCredentials(request) {
|
|
11
|
+
try {
|
|
12
|
+
const contentType = request.headers.get(CONTENT_TYPE_HEADER_NAME);
|
|
13
|
+
const credentials = await this.extractFromBody(contentType, request);
|
|
14
|
+
return typeof credentials?.user === 'string' || typeof credentials?.pass === 'string' ? credentials : null;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
40
17
|
return null;
|
|
41
|
-
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async extractFromBody(contentType, request) {
|
|
21
|
+
if (contentType.includes('json')) {
|
|
22
|
+
return this.extractFromJson(await request.json());
|
|
23
|
+
}
|
|
24
|
+
else if (contentType.includes(ContentType.APPLICATION_X_WWW_FORM_URL_ENCODED)) {
|
|
25
|
+
return this.extractFromUrlEncoded(await request.formUrlEncoded());
|
|
26
|
+
}
|
|
27
|
+
else if (contentType.includes(ContentType.MULTIPART_FORM_DATA)) {
|
|
28
|
+
return this.extractFromMultipart(await request.formData());
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
42
31
|
}
|
|
43
32
|
extractFromJson(json) {
|
|
44
33
|
if (!json) {
|