perimeterx-js-core 0.7.1 → 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 +1 -1
- package/lib/config/IConfiguration.d.ts +1 -1
- package/lib/config/StaticConfigurationBase.d.ts +1 -1
- package/lib/config/StaticConfigurationBase.js +3 -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.js +51 -62
- 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.js +27 -35
- package/lib/logger/LoggerBase.js +2 -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.js +8 -18
- package/lib/phase/impl/TelemetryPhase.js +9 -21
- 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 +2 -0
- 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,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
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// This file is based on the implementation found here:
|
|
2
|
+
// https://github.com/pinglu85/BFEdevSolutions/blob/main/Coding-Problems/80.implement-your-own-URLSearchParams.md
|
|
3
|
+
import { URLUtils } from './URLUtils';
|
|
4
|
+
export class UrlSearchParamsImpl {
|
|
5
|
+
_searchParamsArray;
|
|
6
|
+
_searchParamsMap;
|
|
7
|
+
constructor(init) {
|
|
8
|
+
this._searchParamsArray = [];
|
|
9
|
+
this._searchParamsMap = new Map();
|
|
10
|
+
if (init) {
|
|
11
|
+
if (typeof init !== 'object') {
|
|
12
|
+
this._constructSearchParamsFromString(init);
|
|
13
|
+
}
|
|
14
|
+
else if (Array.isArray(init)) {
|
|
15
|
+
this._constructSearchParamsFromArray(init);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this._constructSearchParamsFromObject(init);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
append(name, value) {
|
|
23
|
+
name = String(name);
|
|
24
|
+
value = String(value);
|
|
25
|
+
this._saveParam(name, value);
|
|
26
|
+
}
|
|
27
|
+
delete(name) {
|
|
28
|
+
name = String(name);
|
|
29
|
+
this._searchParamsMap.delete(name);
|
|
30
|
+
this._searchParamsArray = this._searchParamsArray.filter((param) => param[0] !== name);
|
|
31
|
+
}
|
|
32
|
+
forEach(callback) {
|
|
33
|
+
this._searchParamsArray.forEach((param) => {
|
|
34
|
+
callback(param[1], param[0], this);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
get(name) {
|
|
38
|
+
name = String(name);
|
|
39
|
+
const value = this._searchParamsMap.get(name);
|
|
40
|
+
return value ? value[0] : null;
|
|
41
|
+
}
|
|
42
|
+
getAll(name) {
|
|
43
|
+
name = String(name);
|
|
44
|
+
const value = this._searchParamsMap.get(name);
|
|
45
|
+
return value ? value : [];
|
|
46
|
+
}
|
|
47
|
+
has(name) {
|
|
48
|
+
name = String(name);
|
|
49
|
+
return this._searchParamsMap.has(name);
|
|
50
|
+
}
|
|
51
|
+
set(name, value) {
|
|
52
|
+
name = String(name);
|
|
53
|
+
value = String(value);
|
|
54
|
+
if (!this.has(name)) {
|
|
55
|
+
this.append(name, value);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
name = URLUtils.decodeUriComponent(name);
|
|
59
|
+
value = URLUtils.decodeUriComponent(value);
|
|
60
|
+
this._searchParamsMap.set(name, [value]);
|
|
61
|
+
const searchParamIdx = this._searchParamsArray.findIndex((param) => param[0] === name);
|
|
62
|
+
this._searchParamsArray[searchParamIdx][1] = value;
|
|
63
|
+
this._searchParamsArray = this._searchParamsArray.filter((param, idx) => param[0] !== name || idx === searchParamIdx);
|
|
64
|
+
}
|
|
65
|
+
toString() {
|
|
66
|
+
return this._searchParamsArray
|
|
67
|
+
.map(([key, value]) => `${URLUtils.encodeUriComponent(key)}=${URLUtils.encodeUriComponent(value)}`)
|
|
68
|
+
.join('&');
|
|
69
|
+
}
|
|
70
|
+
_constructSearchParamsFromString(init) {
|
|
71
|
+
let searchParams = String(init);
|
|
72
|
+
if (searchParams.startsWith('?')) {
|
|
73
|
+
searchParams = searchParams.slice(1);
|
|
74
|
+
}
|
|
75
|
+
searchParams.split('&').forEach((param) => {
|
|
76
|
+
let [key, value] = param.split('=');
|
|
77
|
+
if (!value) {
|
|
78
|
+
value = '';
|
|
79
|
+
}
|
|
80
|
+
this._saveParam(key, value);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
_constructSearchParamsFromArray(init) {
|
|
84
|
+
for (const param of init) {
|
|
85
|
+
if (!Array.isArray(param || param.length !== 2)) {
|
|
86
|
+
throw new Error("Failed to construct 'UrlSearchParamsImpl'");
|
|
87
|
+
}
|
|
88
|
+
const key = String(param[0]);
|
|
89
|
+
const value = String(param[1]);
|
|
90
|
+
this._saveParam(key, value);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
_constructSearchParamsFromObject(init) {
|
|
94
|
+
if (init instanceof Set) {
|
|
95
|
+
throw new Error("Failed to construct 'UrlSearchParamsImpl'");
|
|
96
|
+
}
|
|
97
|
+
for (const key of Object.keys(init)) {
|
|
98
|
+
const value = String(init[key]);
|
|
99
|
+
this._saveParam(key, value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
_saveParam(key, value) {
|
|
103
|
+
key = URLUtils.decodeUriComponent(key);
|
|
104
|
+
value = URLUtils.decodeUriComponent(value);
|
|
105
|
+
this._searchParamsArray.push([key, value]);
|
|
106
|
+
this._storeParamInSearchParamsMap(key, value);
|
|
107
|
+
}
|
|
108
|
+
_storeParamInSearchParamsMap(key, value) {
|
|
109
|
+
let values = this._searchParamsMap.get(key);
|
|
110
|
+
if (!values) {
|
|
111
|
+
values = [];
|
|
112
|
+
this._searchParamsMap.set(key, values);
|
|
113
|
+
}
|
|
114
|
+
values.push(value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -3,3 +3,9 @@ export * from './constants';
|
|
|
3
3
|
export * from './HttpMethod';
|
|
4
4
|
export * from './MinimalResponseUtils';
|
|
5
5
|
export * from './MultipartFormDataUtils';
|
|
6
|
+
export * from './FormDataImpl';
|
|
7
|
+
export * from './MinimalResponseImpl';
|
|
8
|
+
export * from './OutgoingRequestImpl';
|
|
9
|
+
export * from './UrlImpl';
|
|
10
|
+
export * from './UrlSearchParamsImpl';
|
|
11
|
+
export * from './URLUtils';
|
package/lib/http/utils/index.js
CHANGED
|
@@ -3,3 +3,9 @@ export * from './constants';
|
|
|
3
3
|
export * from './HttpMethod';
|
|
4
4
|
export * from './MinimalResponseUtils';
|
|
5
5
|
export * from './MultipartFormDataUtils';
|
|
6
|
+
export * from './FormDataImpl';
|
|
7
|
+
export * from './MinimalResponseImpl';
|
|
8
|
+
export * from './OutgoingRequestImpl';
|
|
9
|
+
export * from './UrlImpl';
|
|
10
|
+
export * from './UrlSearchParamsImpl';
|
|
11
|
+
export * from './URLUtils';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export class BufferBase64Utils {
|
|
2
|
+
static BASE_64_ENCODING = 'base64';
|
|
2
3
|
base64Decode(stringToDecode) {
|
|
3
4
|
const buffer = Buffer.from(stringToDecode, BufferBase64Utils.BASE_64_ENCODING);
|
|
4
5
|
return buffer.toString('utf8');
|
|
@@ -8,4 +9,3 @@ export class BufferBase64Utils {
|
|
|
8
9
|
return buffer.toString(BufferBase64Utils.BASE_64_ENCODING);
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
|
-
BufferBase64Utils.BASE_64_ENCODING = 'base64';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import * as crypto from 'crypto';
|
|
3
|
-
import { ICipherUtils, Pbkdf2DecryptOptions } from '
|
|
3
|
+
import { ICipherUtils, Pbkdf2DecryptOptions } from '../../utils';
|
|
4
4
|
declare type CryptoModule = typeof crypto;
|
|
5
5
|
export declare class CryptoCipherUtils implements ICipherUtils {
|
|
6
6
|
private crypto;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
export class CryptoCipherUtils {
|
|
3
|
+
crypto;
|
|
4
|
+
constructor(cryptoModule = crypto) {
|
|
5
|
+
this.crypto = cryptoModule;
|
|
6
|
+
}
|
|
7
|
+
async pbkdf2Decrypt(secret, encryptedString, iterations, salt, options) {
|
|
8
|
+
const keylen = options?.keylen || 32;
|
|
9
|
+
const ivlen = options?.ivlen || 16;
|
|
10
|
+
const derivation = this.crypto.pbkdf2Sync(secret, Buffer.from(salt, 'base64'), iterations, keylen + ivlen, 'sha256');
|
|
11
|
+
const key = derivation.subarray(0, keylen);
|
|
12
|
+
const iv = derivation.subarray(keylen);
|
|
13
|
+
const cipher = this.crypto.createDecipheriv('aes-256-cbc', key, iv);
|
|
14
|
+
let decrypted = cipher.update(encryptedString, 'base64', 'utf8');
|
|
15
|
+
decrypted += cipher.final('utf8');
|
|
16
|
+
return decrypted;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { IBase64Utils } from '
|
|
2
|
-
import { ICipherUtils, Pbkdf2DecryptOptions } from './ICipherUtils';
|
|
1
|
+
import { ICipherUtils, IBase64Utils, Pbkdf2DecryptOptions } from '../../utils';
|
|
3
2
|
export declare class SubtleCryptoCipherUtils implements ICipherUtils {
|
|
4
3
|
private base64Utils;
|
|
5
4
|
private subtleCrypto;
|