perimeterx-js-core 0.6.2 → 0.7.1
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/ActionData.d.ts +1 -1
- package/lib/action/Decision.d.ts +1 -1
- package/lib/action/ProductAction.d.ts +1 -1
- package/lib/activities/model/Activity.d.ts +1 -1
- package/lib/activities/model/ActivityDetails.d.ts +5 -5
- package/lib/activities/utils.js +1 -1
- package/lib/additional_activity_handler/AdditionalActivityHandler.d.ts +1 -1
- package/lib/config/ConfigurationParams.d.ts +2 -1
- package/lib/config/DefaultConfigurations.js +1 -0
- package/lib/config/IConfiguration.d.ts +4 -0
- package/lib/config/StaticConfigurationBase.d.ts +1 -0
- package/lib/config/StaticConfigurationBase.js +3 -0
- package/lib/context/DefaultContext.d.ts +4 -1
- package/lib/context/DefaultContext.js +6 -3
- package/lib/context/interfaces/MobileData.d.ts +1 -1
- package/lib/context/interfaces/ReadonlyContext.d.ts +1 -1
- package/lib/context/interfaces/RequestData.d.ts +6 -1
- package/lib/context/interfaces/RiskApiData.d.ts +1 -1
- package/lib/context/interfaces/ServerData.d.ts +1 -1
- package/lib/context/interfaces/TlsData.d.ts +1 -1
- package/lib/context/interfaces/TokenData.d.ts +1 -1
- package/lib/cors/CustomBlockResponseHeadersHandler.d.ts +1 -1
- package/lib/cors/CustomPreflightHandler.d.ts +1 -1
- package/lib/custom_parameters/CustomParameters.d.ts +1 -1
- package/lib/custom_parameters/CustomParametersFunction.d.ts +1 -1
- package/lib/enforcer/EnforcerBase.d.ts +2 -1
- package/lib/enforcer/EnforcerBase.js +13 -3
- package/lib/enforcer/options/EnforcerBaseOptions.d.ts +3 -1
- package/lib/enforcer/options/EnforcerOptionsType.d.ts +1 -1
- package/lib/enforcer/options/EnforcerV2Options.d.ts +1 -1
- package/lib/enforcer/options/EnforcerV3Options.d.ts +1 -1
- package/lib/first_party/FirstPartyData.d.ts +1 -1
- package/lib/graphql/model/GraphQLData.d.ts +1 -1
- package/lib/graphql/model/GraphQLOperation.d.ts +1 -1
- package/lib/http/impl/FormDataImpl.js +2 -2
- package/lib/http/impl/MinimalResponseImpl.d.ts +1 -1
- package/lib/http/impl/OutgoingRequestImpl.d.ts +1 -1
- package/lib/http/interfaces/IHttpClient.d.ts +1 -1
- package/lib/http/interfaces/ReadonlyHeaders.d.ts +1 -1
- package/lib/logger/HttpLogServiceClient.d.ts +17 -0
- package/lib/logger/HttpLogServiceClient.js +60 -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 +12 -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/PhaseResult.d.ts +1 -1
- 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/SendLogsPhase.d.ts +11 -0
- package/lib/phase/impl/SendLogsPhase.js +26 -0
- package/lib/phase/impl/index.d.ts +1 -0
- package/lib/phase/impl/index.js +1 -0
- package/lib/products/account_defender/AccountDefender.d.ts +1 -1
- package/lib/products/account_defender/AccountDefenderData.d.ts +1 -1
- package/lib/products/account_defender/JwtData.d.ts +1 -1
- package/lib/products/bot_defender/BotDefender.d.ts +1 -1
- package/lib/products/bot_defender/BotDefenderData.d.ts +1 -1
- package/lib/products/bot_defender/block/model/BlockData.d.ts +1 -1
- package/lib/products/bot_defender/block/model/JsonBlockPayload.d.ts +1 -1
- package/lib/products/bot_defender/block/model/MobileBlockPayload.d.ts +1 -1
- package/lib/products/bot_defender/block/utils.js +5 -4
- package/lib/products/bot_defender/filter/DefaultBotDefenderFilter.js +5 -1
- package/lib/products/bot_defender/reasons/BotDefenderReasonType.d.ts +1 -1
- package/lib/products/credential_intelligence/endpoint/CredentialEndpointConfiguration.d.ts +1 -1
- package/lib/products/credential_intelligence/endpoint/login_successful/CustomLoginSuccessfulCallback.d.ts +1 -1
- package/lib/products/credential_intelligence/model/CredentialData.d.ts +1 -1
- package/lib/products/credential_intelligence/model/CredentialIntelligenceData.d.ts +1 -1
- package/lib/products/credential_intelligence/model/Credentials.d.ts +1 -1
- package/lib/products/credential_intelligence/model/CustomExtractionCallback.d.ts +1 -1
- package/lib/products/interfaces/ProductData.d.ts +1 -1
- package/lib/products/interfaces/ProductDataType.d.ts +1 -1
- package/lib/products/interfaces/ProductType.d.ts +1 -1
- package/lib/products/interfaces/Products.d.ts +1 -1
- package/lib/pxde/model/PXDE.d.ts +1 -1
- package/lib/pxde/model/PxdeData.d.ts +1 -1
- package/lib/pxhd/model/PXHD.d.ts +1 -1
- package/lib/risk_api/client/PostRiskApiClientBase.js +1 -1
- package/lib/risk_api/model/RiskActivity.d.ts +4 -4
- package/lib/risk_api/risk_response/RiskResponsePayloadType.d.ts +1 -1
- package/lib/risk_api/risk_response/v2/RiskResponseV2Payload.d.ts +1 -1
- package/lib/risk_api/risk_response/v3/RiskResponseV3Payload.d.ts +1 -1
- package/lib/risk_token/parser/DefaultTokenV2Parser.d.ts +1 -1
- package/lib/risk_token/parser/DefaultTokenV3Parser.d.ts +1 -1
- package/lib/risk_token/parser/TokenParserOptions.d.ts +1 -1
- package/lib/risk_token/token/TokenPayloadType.d.ts +1 -1
- package/lib/risk_token/token/v2/TokenV2Payload.d.ts +1 -1
- package/lib/risk_token/token/v3/TokenV3Payload.d.ts +1 -1
- package/lib/telemetry/model/TelemetryActivity.d.ts +2 -2
- package/lib/utils/cipher/ICipherUtils.d.ts +1 -1
- package/lib/utils/constants.d.ts +1 -1
- package/lib/utils/constants.js +1 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/lib/utils/url_parser/DefaultUrlParser.d.ts +13 -0
- package/lib/utils/url_parser/DefaultUrlParser.js +21 -0
- package/lib/utils/url_parser/IURLParser.d.ts +4 -0
- package/lib/utils/url_parser/IURLParser.js +1 -0
- package/lib/utils/url_parser/index.d.ts +2 -0
- package/lib/utils/url_parser/index.js +2 -0
- package/lib/utils/utils.d.ts +5 -0
- package/lib/utils/utils.js +5 -1
- package/package.json +4 -4
package/lib/action/Decision.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GraphQLData } from '../../graphql';
|
|
2
2
|
import { BlockAction } from '../../blocker';
|
|
3
|
-
export
|
|
4
|
-
export
|
|
3
|
+
export type ActivityTypeDetails = PageRequestedActivityDetails | BlockActivityDetails | AdditionalS2SActivityDetails;
|
|
4
|
+
export type ActivityDetails = ActivityTypeDetails & {
|
|
5
5
|
client_uuid: string;
|
|
6
6
|
request_id: string;
|
|
7
7
|
module_version: string;
|
|
@@ -26,20 +26,20 @@ export declare type ActivityDetails = ActivityTypeDetails & {
|
|
|
26
26
|
app_user_id?: string;
|
|
27
27
|
jwt_additional_fields?: Record<string, any>;
|
|
28
28
|
};
|
|
29
|
-
export
|
|
29
|
+
export type PageRequestedActivityDetails = {
|
|
30
30
|
pass_reason: string;
|
|
31
31
|
px_cookie?: string;
|
|
32
32
|
error_message?: string;
|
|
33
33
|
s2s_error_reason?: string;
|
|
34
34
|
s2s_error_http_status?: number;
|
|
35
35
|
};
|
|
36
|
-
export
|
|
36
|
+
export type BlockActivityDetails = {
|
|
37
37
|
block_reason: string;
|
|
38
38
|
block_action: BlockAction;
|
|
39
39
|
block_score: number;
|
|
40
40
|
simulated_block: boolean;
|
|
41
41
|
};
|
|
42
|
-
export
|
|
42
|
+
export type AdditionalS2SActivityDetails = {
|
|
43
43
|
http_status_code: number;
|
|
44
44
|
login_successful: boolean;
|
|
45
45
|
raw_username?: string;
|
package/lib/activities/utils.js
CHANGED
|
@@ -8,7 +8,7 @@ export const createActivity = (activityType, config, context) => {
|
|
|
8
8
|
return {
|
|
9
9
|
type: activityType,
|
|
10
10
|
px_app_id: config.appId,
|
|
11
|
-
url: context.requestData.
|
|
11
|
+
url: context.requestData.rawUrl,
|
|
12
12
|
headers: activityType !== ActivityType.ADDITIONAL_S2S
|
|
13
13
|
? joinHeaderValues(removeSensitiveHeaders(context.requestData.headers, config.sensitiveHeaders))
|
|
14
14
|
: undefined,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ConfigurationParams } from '../config';
|
|
2
2
|
import { ReadonlyContext } from '../context';
|
|
3
|
-
export
|
|
3
|
+
export type AdditionalActivityHandler = <Req, Res>(config: ConfigurationParams<Req, Res>, context: ReadonlyContext<Req, Res>, request: Req) => void | Promise<void>;
|
|
@@ -5,7 +5,7 @@ import { CredentialEndpointConfiguration, CredentialIntelligenceVersion, CustomL
|
|
|
5
5
|
import { LoggerSeverity } from '../logger';
|
|
6
6
|
import { ModuleMode } from '../utils';
|
|
7
7
|
import { GraphQLOperationType } from '../graphql';
|
|
8
|
-
export
|
|
8
|
+
export type ConfigurationParams<Req, Res> = {
|
|
9
9
|
px_app_id: string;
|
|
10
10
|
px_auth_token: string;
|
|
11
11
|
px_cookie_secret: string;
|
|
@@ -73,6 +73,7 @@ export declare type ConfigurationParams<Req, Res> = {
|
|
|
73
73
|
px_sensitive_graphql_operation_types?: Array<'query' | 'mutation' | 'subscription' | GraphQLOperationType>;
|
|
74
74
|
px_cors_support_enabled?: boolean;
|
|
75
75
|
px_cors_preflight_request_filter_enabled?: boolean;
|
|
76
|
+
px_logger_auth_token?: string;
|
|
76
77
|
px_extract_ip?: () => {};
|
|
77
78
|
px_additional_activity_handler?: AdditionalActivityHandler;
|
|
78
79
|
px_enrich_custom_parameters?: CustomParametersFunction<Req, Res>;
|
|
@@ -301,6 +301,10 @@ export interface IConfiguration<Req, Res, ParamsType extends ConfigurationParams
|
|
|
301
301
|
* The default login successful custom callback to use if none is defined for an endpoint.
|
|
302
302
|
*/
|
|
303
303
|
readonly ciDefaultLoginSuccessfulCustomCallback: CustomLoginSuccessfulCallback<Res>;
|
|
304
|
+
/**
|
|
305
|
+
* The authentication token for the logging service.
|
|
306
|
+
*/
|
|
307
|
+
readonly loggerAuthToken: string;
|
|
304
308
|
/**
|
|
305
309
|
* Returns an object representation of the current configuration.
|
|
306
310
|
*/
|
|
@@ -76,6 +76,7 @@ export declare abstract class StaticConfigurationBase<Req, Res, ParamsType exten
|
|
|
76
76
|
get jwtHeaderName(): string;
|
|
77
77
|
get jwtHeaderUserIdFieldName(): string;
|
|
78
78
|
get ciEnabled(): boolean;
|
|
79
|
+
get loggerAuthToken(): string;
|
|
79
80
|
get ciEndpoints(): CredentialEndpointConfiguration<Req, Res>[];
|
|
80
81
|
get ciCompromisedCredentialsHeaderName(): string;
|
|
81
82
|
get ciSendRawUsernameOnAdditionalS2SActivity(): boolean;
|
|
@@ -236,6 +236,9 @@ export class StaticConfigurationBase {
|
|
|
236
236
|
get ciEnabled() {
|
|
237
237
|
return this.configParams.px_login_credentials_extraction_enabled;
|
|
238
238
|
}
|
|
239
|
+
get loggerAuthToken() {
|
|
240
|
+
return this.configParams.px_logger_auth_token;
|
|
241
|
+
}
|
|
239
242
|
get ciEndpoints() {
|
|
240
243
|
return this.configParams.px_login_credentials_extraction;
|
|
241
244
|
}
|
|
@@ -9,9 +9,11 @@ import { ICookieParser, IRequestIdGenerator, VidSource } from '../utils';
|
|
|
9
9
|
import { IContext, RequestData, RiskApiData, ServerData, TlsData, TokenData } from './interfaces';
|
|
10
10
|
import { ProductData, ProductName } from '../products';
|
|
11
11
|
import { Action } from '../action';
|
|
12
|
-
|
|
12
|
+
import { IURLParser } from '../utils/url_parser';
|
|
13
|
+
export type DefaultContextOptions = {
|
|
13
14
|
cookieParser?: ICookieParser;
|
|
14
15
|
requestIdGenerator: IRequestIdGenerator;
|
|
16
|
+
urlParser?: IURLParser;
|
|
15
17
|
};
|
|
16
18
|
export declare class DefaultContext<Req, Res> implements IContext<Req, Res> {
|
|
17
19
|
readonly requestId: string;
|
|
@@ -35,6 +37,7 @@ export declare class DefaultContext<Req, Res> implements IContext<Req, Res> {
|
|
|
35
37
|
customParameters?: CustomParameters;
|
|
36
38
|
response?: IOutgoingResponse<Res>;
|
|
37
39
|
protected readonly config: IConfiguration<Req, Res>;
|
|
40
|
+
protected readonly urlParser: IURLParser;
|
|
38
41
|
constructor(config: IConfiguration<Req, Res>, request: IIncomingRequest<Req>, options: DefaultContextOptions);
|
|
39
42
|
get isMobile(): boolean;
|
|
40
43
|
protected createRequestData(config: IConfiguration<Req, Res>, request: IIncomingRequest<Req>, cookieParser?: ICookieParser): RequestData<Req>;
|
|
@@ -3,10 +3,12 @@ import { PXHDSource } from '../pxhd';
|
|
|
3
3
|
import { TokenOrigin, TokenParseResult } from '../risk_token';
|
|
4
4
|
import { RiskApiCallResult } from '../risk_api';
|
|
5
5
|
import { COOKIE_HEADER_NAME, toReadonlyHeaders, USER_AGENT_HEADER_NAME, } from '../http';
|
|
6
|
-
import { StringSplitCookieParser,
|
|
6
|
+
import { StringSplitCookieParser, PXHD_COOKIE_NAME, PXVID_COOKIE_NAME, X_PX_AUTHORIZATION_HEADER_NAME, } from '../utils';
|
|
7
|
+
import { DefaultUrlParser } from '../utils/url_parser';
|
|
7
8
|
export class DefaultContext {
|
|
8
9
|
constructor(config, request, options) {
|
|
9
10
|
this.config = config;
|
|
11
|
+
this.urlParser = options.urlParser || new DefaultUrlParser();
|
|
10
12
|
this.tokenData = {
|
|
11
13
|
tokenParseResult: TokenParseResult.NONE,
|
|
12
14
|
};
|
|
@@ -29,7 +31,8 @@ export class DefaultContext {
|
|
|
29
31
|
return this.tokenOrigin === TokenOrigin.HEADER;
|
|
30
32
|
}
|
|
31
33
|
createRequestData(config, request, cookieParser = new StringSplitCookieParser()) {
|
|
32
|
-
const
|
|
34
|
+
const rawUrl = request.url;
|
|
35
|
+
const url = this.urlParser.parse(rawUrl);
|
|
33
36
|
const method = request.method;
|
|
34
37
|
const headers = request.headers;
|
|
35
38
|
const cookies = DefaultContext.getCookies(cookieParser, request.headers.get(COOKIE_HEADER_NAME), request.headers.get(config.customCookieHeader));
|
|
@@ -37,7 +40,7 @@ export class DefaultContext {
|
|
|
37
40
|
const readOnlyHeaders = toReadonlyHeaders(headers);
|
|
38
41
|
const userAgent = this.extractUserAgentFromHeader(config, readOnlyHeaders);
|
|
39
42
|
const ip = this.extractIpFromHeader(config, readOnlyHeaders) || request.clientIP;
|
|
40
|
-
return { url, method, headers: readOnlyHeaders, cookies, ip, userAgent, requestCookieNames, request };
|
|
43
|
+
return { url, rawUrl, method, headers: readOnlyHeaders, cookies, ip, userAgent, requestCookieNames, request };
|
|
41
44
|
}
|
|
42
45
|
static getCookies(cookieParser, ...cookieHeaderValues) {
|
|
43
46
|
const cookies = {};
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { HttpMethod, IIncomingRequest, IURL, ReadonlyHeaders } from '../../http';
|
|
2
|
-
export
|
|
2
|
+
export type RequestData<Req> = {
|
|
3
3
|
/**
|
|
4
4
|
* The request URL.
|
|
5
5
|
*/
|
|
6
6
|
url: IURL;
|
|
7
|
+
/**
|
|
8
|
+
* The native url fetched from the environment.
|
|
9
|
+
* It should contain "..", duplicate slashes and un-decoded ascii characters (%XX) if possible.
|
|
10
|
+
*/
|
|
11
|
+
rawUrl: string;
|
|
7
12
|
/**
|
|
8
13
|
* The request method, capitalized.
|
|
9
14
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ReadonlyHeaders } from '../http';
|
|
2
|
-
export
|
|
2
|
+
export type CustomBlockResponseHeadersHandler<Req> = (request: Req) => ReadonlyHeaders | Promise<ReadonlyHeaders>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { IMinimalResponse } from '../http';
|
|
2
|
-
export
|
|
2
|
+
export type CustomPreflightHandler<Req> = (request: Req) => IMinimalResponse | Promise<IMinimalResponse>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ConfigurationParams } from '../config';
|
|
2
2
|
import { CustomParameters } from './CustomParameters';
|
|
3
|
-
export
|
|
3
|
+
export type CustomParametersFunction<Req, Res> = (config: ConfigurationParams<Req, Res>, request: Req) => CustomParameters | Promise<CustomParameters>;
|
|
@@ -13,6 +13,7 @@ export declare abstract class EnforcerBase<TokenV extends TokenVersion, Req, Res
|
|
|
13
13
|
protected readonly filterFlow: IPhase<Req, Res>;
|
|
14
14
|
protected readonly enforceFlow: IPhase<Req, Res>;
|
|
15
15
|
protected readonly postEnforceFlow: IPhase<Req, Res>;
|
|
16
|
+
protected readonly endEnforcerFlow: IPhase<Req, Res>;
|
|
16
17
|
protected readonly activityClient: IActivityClient<Req, Res>;
|
|
17
18
|
/**
|
|
18
19
|
* Constructs the concrete request context given the provided EnforceArgs.
|
|
@@ -42,7 +43,7 @@ export declare abstract class EnforcerBase<TokenV extends TokenVersion, Req, Res
|
|
|
42
43
|
* @returns Promise<Res> - A Promise resolving to Res.
|
|
43
44
|
* @protected
|
|
44
45
|
*/
|
|
45
|
-
protected abstract convertToRes(response: IMinimalResponse): Promise<Res>;
|
|
46
|
+
protected abstract convertToRes(response: IMinimalResponse, ...args: EnforceArgs): Promise<Res>;
|
|
46
47
|
/**
|
|
47
48
|
* Converts the Res object into the IOutgoingResponse interface.
|
|
48
49
|
* @param args - PostEnforceArgs
|
|
@@ -12,10 +12,11 @@ import { DefaultTelemetry } from '../telemetry';
|
|
|
12
12
|
import { DefaultTokenV2Parser, DefaultTokenV3Parser, TokenVersion } from '../risk_token';
|
|
13
13
|
import { DefaultCors } from '../cors';
|
|
14
14
|
import { PostRiskApiClientV2, PostRiskApiClientV3 } from '../risk_api';
|
|
15
|
-
import { EnforceFlow, FilterFlow, PostEnforceFlow } from '../phase';
|
|
15
|
+
import { EndEnforcerFlow, EnforceFlow, FilterFlow, PostEnforceFlow } from '../phase';
|
|
16
16
|
import { AccountDefender, BotDefender, CredentialIntelligence, ProductName } from '../products';
|
|
17
17
|
import { HttpActivityClient, HttpBatchedActivityClient } from '../activities';
|
|
18
18
|
import { DefaultGraphQLParser } from '../graphql';
|
|
19
|
+
import { HttpLogServiceClient } from '../logger';
|
|
19
20
|
export class EnforcerBase {
|
|
20
21
|
/**
|
|
21
22
|
* The EnforcerBase constructor.
|
|
@@ -30,6 +31,7 @@ export class EnforcerBase {
|
|
|
30
31
|
this.filterFlow = new FilterFlow(config, initializationBlock);
|
|
31
32
|
this.enforceFlow = new EnforceFlow(config, initializationBlock);
|
|
32
33
|
this.postEnforceFlow = new PostEnforceFlow(config, initializationBlock);
|
|
34
|
+
this.endEnforcerFlow = new EndEnforcerFlow(config, initializationBlock);
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* The central function that triggers enforcement on the incoming request.
|
|
@@ -62,11 +64,16 @@ export class EnforcerBase {
|
|
|
62
64
|
const context = yield this.constructContext(...args);
|
|
63
65
|
let result = yield this.filterFlow.execute(context);
|
|
64
66
|
if (result.done) {
|
|
65
|
-
|
|
67
|
+
yield this.endEnforcerFlow.execute(context);
|
|
68
|
+
return result.response ? this.convertToRes(result.response, ...args) : null;
|
|
66
69
|
}
|
|
67
70
|
this.preserveContext(context, ...args);
|
|
68
71
|
result = yield this.enforceFlow.execute(context);
|
|
69
|
-
|
|
72
|
+
if (result.response) {
|
|
73
|
+
yield this.endEnforcerFlow.execute(context);
|
|
74
|
+
return this.convertToRes(result.response, ...args);
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
70
77
|
});
|
|
71
78
|
}
|
|
72
79
|
/**
|
|
@@ -83,6 +90,7 @@ export class EnforcerBase {
|
|
|
83
90
|
context.response = yield this.convertToOutgoingResponse(...args);
|
|
84
91
|
yield this.postEnforceFlow.execute(context);
|
|
85
92
|
}
|
|
93
|
+
yield this.endEnforcerFlow.execute(context);
|
|
86
94
|
}
|
|
87
95
|
catch (e) {
|
|
88
96
|
this.config.logger.error(`caught error in post enforce - ${e}`);
|
|
@@ -124,6 +132,7 @@ export class EnforcerBase {
|
|
|
124
132
|
(config.maxActivityBatchSize > 1
|
|
125
133
|
? new HttpBatchedActivityClient(config, httpClient)
|
|
126
134
|
: new HttpActivityClient(config, httpClient));
|
|
135
|
+
const logServiceClient = options.logServiceClient || (config.loggerAuthToken ? new HttpLogServiceClient(config, httpClient) : null);
|
|
127
136
|
const allOptions = {
|
|
128
137
|
httpClient,
|
|
129
138
|
base64Utils,
|
|
@@ -137,6 +146,7 @@ export class EnforcerBase {
|
|
|
137
146
|
tokenParser,
|
|
138
147
|
riskApiClient,
|
|
139
148
|
activityClient,
|
|
149
|
+
logServiceClient,
|
|
140
150
|
};
|
|
141
151
|
const products = this.initializeProducts(config, options.products, base64Utils, hashUtils, ipRangeChecker);
|
|
142
152
|
return Object.assign({ products }, allOptions);
|
|
@@ -8,7 +8,8 @@ import { IRiskApiClient } from '../../risk_api';
|
|
|
8
8
|
import { IActivityClient } from '../../activities';
|
|
9
9
|
import { Products } from '../../products';
|
|
10
10
|
import { IGraphQLParser } from '../../graphql';
|
|
11
|
-
|
|
11
|
+
import { ILogServiceClient } from '../../logger';
|
|
12
|
+
export type EnforcerBaseOptions<Req, Res> = {
|
|
12
13
|
httpClient: IHttpClient;
|
|
13
14
|
base64Utils: IBase64Utils;
|
|
14
15
|
hmacUtils: IHmacUtils;
|
|
@@ -22,4 +23,5 @@ export declare 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,4 +1,4 @@
|
|
|
1
1
|
import { TokenVersion } from '../../risk_token';
|
|
2
2
|
import { EnforcerV2Options } from './EnforcerV2Options';
|
|
3
3
|
import { EnforcerV3Options } from './EnforcerV3Options';
|
|
4
|
-
export
|
|
4
|
+
export type EnforcerOptionsType<TokenV extends TokenVersion, Req, Res> = TokenV extends TokenVersion.V2 ? EnforcerV2Options<Req, Res> : TokenV extends TokenVersion.V3 ? EnforcerV3Options<Req, Res> : never;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TokenVersion } from '../../risk_token';
|
|
2
2
|
import { EnforcerBaseOptions } from './EnforcerBaseOptions';
|
|
3
|
-
export
|
|
3
|
+
export type EnforcerV2Options<Req, Res> = {
|
|
4
4
|
tokenVersion: TokenVersion.V2;
|
|
5
5
|
} & EnforcerBaseOptions<Req, Res>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TokenVersion } from '../../risk_token';
|
|
2
2
|
import { ICipherUtils } from '../../utils';
|
|
3
3
|
import { EnforcerBaseOptions } from './EnforcerBaseOptions';
|
|
4
|
-
export
|
|
4
|
+
export type EnforcerV3Options<Req, Res> = {
|
|
5
5
|
tokenVersion: TokenVersion.V3;
|
|
6
6
|
cipherUtils: ICipherUtils;
|
|
7
7
|
} & EnforcerBaseOptions<Req, Res>;
|
|
@@ -29,8 +29,8 @@ export class FormDataImpl {
|
|
|
29
29
|
if (typeof value === 'string') {
|
|
30
30
|
this.data[name] = [value];
|
|
31
31
|
}
|
|
32
|
-
else {
|
|
33
|
-
this.data[name] = [
|
|
32
|
+
else if (File) {
|
|
33
|
+
this.data[name] = [new File([value], filename)];
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncOrSync } from 'ts-essentials';
|
|
2
2
|
import { IOutgoingRequest } from './IOutgoingRequest';
|
|
3
3
|
import { IIncomingResponse } from './IIncomingResponse';
|
|
4
|
-
export
|
|
4
|
+
export type HttpSendOptions = {
|
|
5
5
|
timeoutMs?: number;
|
|
6
6
|
};
|
|
7
7
|
export interface IHttpClient {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeepReadonly } from 'ts-essentials';
|
|
2
2
|
import { IHeaders } from './IHeaders';
|
|
3
|
-
export
|
|
3
|
+
export type ReadonlyHeaders = DeepReadonly<Record<string, string[]>>;
|
|
4
4
|
export declare const toReadonlyHeaders: (headers: IHeaders) => ReadonlyHeaders;
|
|
5
5
|
export declare const toMutableHeaders: (headers: ReadonlyHeaders) => Record<string, string[]>;
|
|
6
6
|
export declare const joinHeaderValues: (headers: ReadonlyHeaders) => Record<string, string>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EnrichedLogRecord, LogRecord } from './model';
|
|
2
|
+
import { ReadonlyContext } from '../context';
|
|
3
|
+
import { IConfiguration } from '../config';
|
|
4
|
+
import { IHttpClient } from '../http';
|
|
5
|
+
import { ILogger } from '../logger';
|
|
6
|
+
import { ILogServiceClient } from './ILogServiceClient';
|
|
7
|
+
export declare class HttpLogServiceClient<Req, Res> implements ILogServiceClient<Req, Res> {
|
|
8
|
+
protected readonly appId: string;
|
|
9
|
+
protected readonly backendUrl: string;
|
|
10
|
+
protected readonly loggerAuthToken: string;
|
|
11
|
+
protected readonly logger: ILogger;
|
|
12
|
+
protected readonly httpClient: IHttpClient;
|
|
13
|
+
constructor(config: IConfiguration<Req, Res>, httpClient: IHttpClient);
|
|
14
|
+
sendLogs(context: ReadonlyContext<Req, Res>, logs: LogRecord[]): Promise<void>;
|
|
15
|
+
protected enrichLogRecord(context: ReadonlyContext<Req, Res>, log: LogRecord): EnrichedLogRecord;
|
|
16
|
+
protected postLogs(logRecords: EnrichedLogRecord[]): Promise<boolean>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
import { EXTERNAL_LOGGER_SERVICE_PATH } from './constants';
|
|
11
|
+
import { AUTHORIZATION_HEADER_NAME, CONTENT_TYPE_HEADER_NAME, ContentType, HttpMethod, OutgoingRequestImpl, } from '../http';
|
|
12
|
+
import { getAuthorizationHeader } from '../utils';
|
|
13
|
+
export class HttpLogServiceClient {
|
|
14
|
+
constructor(config, httpClient) {
|
|
15
|
+
this.appId = config.appId;
|
|
16
|
+
this.backendUrl = config.backendScoreApiUrl;
|
|
17
|
+
this.loggerAuthToken = config.loggerAuthToken;
|
|
18
|
+
this.logger = config.logger;
|
|
19
|
+
this.httpClient = httpClient;
|
|
20
|
+
}
|
|
21
|
+
sendLogs(context, logs) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
const enrichedLogs = logs.map((log) => this.enrichLogRecord(context, log));
|
|
25
|
+
yield this.postLogs(enrichedLogs);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
this.logger.error(`unable to send logs: ${e}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
enrichLogRecord(context, log) {
|
|
33
|
+
const requestData = context.requestData;
|
|
34
|
+
const url = new URL(requestData.rawUrl);
|
|
35
|
+
const logMeta = {
|
|
36
|
+
container: 'enforcer',
|
|
37
|
+
appID: this.appId,
|
|
38
|
+
method: requestData.method,
|
|
39
|
+
host: url.host,
|
|
40
|
+
url: requestData.rawUrl,
|
|
41
|
+
path: url.pathname + requestData.url.search,
|
|
42
|
+
requestId: context.requestId,
|
|
43
|
+
};
|
|
44
|
+
return Object.assign(Object.assign({}, logMeta), log);
|
|
45
|
+
}
|
|
46
|
+
postLogs(logRecords) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const url = `${this.backendUrl}${EXTERNAL_LOGGER_SERVICE_PATH}`;
|
|
49
|
+
const method = HttpMethod.POST;
|
|
50
|
+
const headers = {
|
|
51
|
+
[CONTENT_TYPE_HEADER_NAME]: [ContentType.APPLICATION_JSON],
|
|
52
|
+
[AUTHORIZATION_HEADER_NAME]: [getAuthorizationHeader(this.loggerAuthToken)],
|
|
53
|
+
};
|
|
54
|
+
const body = JSON.stringify(logRecords);
|
|
55
|
+
const req = new OutgoingRequestImpl({ url, method, headers, body });
|
|
56
|
+
const res = yield this.httpClient.send(req);
|
|
57
|
+
return (res === null || res === void 0 ? void 0 : res.status) === 200;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ReadonlyContext } from '../context';
|
|
2
|
+
import { LogRecord } from './model';
|
|
3
|
+
import { AsyncOrSync } from 'ts-essentials';
|
|
4
|
+
export interface ILogServiceClient<Req, Res> {
|
|
5
|
+
sendLogs(context: ReadonlyContext<Req, Res>, logs: LogRecord[]): AsyncOrSync<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/logger/ILogger.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LoggerSeverity } from './LoggerSeverity';
|
|
2
|
+
import { LogRecord } from './model';
|
|
2
3
|
export interface ILogger {
|
|
3
4
|
/**
|
|
4
5
|
* @returns LoggerSeverity - The current logger severity.
|
|
@@ -21,4 +22,9 @@ export interface ILogger {
|
|
|
21
22
|
* @returns void
|
|
22
23
|
*/
|
|
23
24
|
error(message: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get all the saved logs for that request
|
|
27
|
+
* @returns LogRecord[]
|
|
28
|
+
*/
|
|
29
|
+
getLogs(): LogRecord[];
|
|
24
30
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ILogger } from './ILogger';
|
|
2
2
|
import { LoggerSeverity } from './LoggerSeverity';
|
|
3
|
+
import { LogRecord } from './model';
|
|
3
4
|
export declare abstract class LoggerBase implements ILogger {
|
|
4
|
-
|
|
5
|
-
protected
|
|
5
|
+
protected loggerSeverity: LoggerSeverity;
|
|
6
|
+
protected logs: LogRecord[];
|
|
7
|
+
protected constructor(loggerSeverity?: LoggerSeverity, logs?: LogRecord[]);
|
|
6
8
|
protected abstract log(message: string): void;
|
|
7
9
|
debug(message: string): void;
|
|
8
10
|
error(message: string): void;
|
|
@@ -10,4 +12,6 @@ export declare abstract class LoggerBase implements ILogger {
|
|
|
10
12
|
setLoggerSeverity(loggerSeverity: LoggerSeverity): void;
|
|
11
13
|
protected logError(message: string): void;
|
|
12
14
|
protected logDebug(message: string): void;
|
|
15
|
+
getLogs(): LogRecord[];
|
|
16
|
+
protected recordLog(message: string, loggerSeverity: LoggerSeverity): void;
|
|
13
17
|
}
|