perimeterx-js-core 0.2.0 → 0.3.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.
Files changed (39) hide show
  1. package/lib/activities/model/ActivityDetails.d.ts +4 -2
  2. package/lib/activities/utils.js +2 -1
  3. package/lib/config/ConfigurationParams.d.ts +4 -0
  4. package/lib/config/DefaultConfigurations.js +5 -1
  5. package/lib/config/IConfiguration.d.ts +18 -0
  6. package/lib/config/StaticConfigurationBase.d.ts +4 -0
  7. package/lib/config/StaticConfigurationBase.js +28 -0
  8. package/lib/context/ContextBase.d.ts +3 -2
  9. package/lib/context/ContextBase.js +13 -77
  10. package/lib/context/IContext.d.ts +4 -3
  11. package/lib/custom_parameters/CustomParametersUtils.d.ts +3 -0
  12. package/lib/custom_parameters/CustomParametersUtils.js +59 -0
  13. package/lib/enforcer/EnforcerBase.d.ts +6 -1
  14. package/lib/enforcer/EnforcerBase.js +41 -7
  15. package/lib/first_party/DefaultFirstParty.js +1 -1
  16. package/lib/graphql/DefaultGraphQLParser.d.ts +19 -0
  17. package/lib/graphql/DefaultGraphQLParser.js +183 -0
  18. package/lib/graphql/IGraphQLParser.d.ts +5 -0
  19. package/lib/graphql/IGraphQLParser.js +2 -0
  20. package/lib/graphql/index.d.ts +5 -0
  21. package/lib/graphql/index.js +7 -0
  22. package/lib/graphql/model/GraphQLData.d.ts +7 -0
  23. package/lib/graphql/model/GraphQLData.js +2 -0
  24. package/lib/graphql/model/GraphQLOperation.d.ts +5 -0
  25. package/lib/graphql/model/GraphQLOperation.js +2 -0
  26. package/lib/graphql/model/GraphQLOperationType.d.ts +5 -0
  27. package/lib/graphql/model/GraphQLOperationType.js +9 -0
  28. package/lib/http/utils/HttpHeaders.d.ts +3 -1
  29. package/lib/http/utils/HttpHeaders.js +19 -2
  30. package/lib/index.d.ts +1 -0
  31. package/lib/index.js +1 -0
  32. package/lib/risk_api/PostRiskApiClient.js +6 -3
  33. package/lib/risk_api/model/RiskActivity.d.ts +2 -0
  34. package/lib/risk_api/model/RiskResponseV2.d.ts +2 -0
  35. package/lib/risk_api/risk_response_handler/RiskResponseV2Handler.js +1 -0
  36. package/lib/utils/constants.d.ts +1 -1
  37. package/lib/utils/constants.js +1 -1
  38. package/lib/utils/utils.js +1 -1
  39. package/package.json +1 -2
@@ -1,5 +1,6 @@
1
- import { PassReason } from '../../utils/PassReason';
2
- import { BlockReason } from '../../block_handler/BlockReason';
1
+ import { PassReason } from '../../utils';
2
+ import { BlockReason } from '../../block_handler';
3
+ import { GraphQLData } from '../../graphql';
3
4
  export declare type ActivityTypeDetails = PageRequestedActivityDetails | BlockActivityDetails | AdditionalS2SActivityDetails;
4
5
  export declare type ActivityDetails = ActivityTypeDetails & {
5
6
  client_uuid: string;
@@ -17,6 +18,7 @@ export declare type ActivityDetails = ActivityTypeDetails & {
17
18
  tls_preferred_ciphers?: string;
18
19
  tls_ciphers_sha?: string;
19
20
  tls_ja3_fingerprint?: string;
21
+ graphql_operations?: GraphQLData[];
20
22
  credentials_compromised?: boolean;
21
23
  ci_version?: string;
22
24
  sso_step?: string;
@@ -8,7 +8,7 @@ var createActivity = function (activityType, config, context) {
8
8
  type: activityType,
9
9
  px_app_id: config.appId,
10
10
  url: context.requestData.url.href,
11
- headers: (0, utils_1.removeSensitiveHeaders)(context.requestData.headers, config.sensitiveHeaders).toObject(),
11
+ headers: (0, utils_1.removeSensitiveHeaders)(context.requestData.headers, config.sensitiveHeaders).toObject(','),
12
12
  pxhd: context.pxhd,
13
13
  socket_ip: context.requestData.ip,
14
14
  timestamp: Date.now(),
@@ -44,6 +44,7 @@ var createGenericActivityDetails = function (config, context) {
44
44
  requestId: 'request_id',
45
45
  uuid: 'client_uuid',
46
46
  tokenOrigin: 'cookie_origin',
47
+ graphqlData: 'graphql_operations',
47
48
  });
48
49
  (0, utils_1.transferExistingProperties)(context.requestData, genericActivityDetails, {
49
50
  httpVersion: 'http_version',
@@ -58,6 +58,10 @@ export declare type ConfigurationParams = {
58
58
  px_jwt_header_name?: string;
59
59
  px_jwt_header_user_id_field_name?: string;
60
60
  px_jwt_header_additional_field_names?: string[];
61
+ px_graphql_enabled?: boolean;
62
+ px_graphql_routes?: string[];
63
+ px_sensitive_graphql_operation_names?: string[];
64
+ px_sensitive_graphql_operation_types?: Array<'query' | 'mutation' | 'subscription'>;
61
65
  px_extract_ip?: () => {};
62
66
  px_additional_activity_handler?: AdditionalActivityHandler;
63
67
  px_enrich_custom_parameters?: CustomParametersFunction;
@@ -94,8 +94,12 @@ exports.DEFAULT_CONFIGURATIONS = {
94
94
  px_filter_by_user_agent: [],
95
95
  px_css_ref: '',
96
96
  px_js_ref: '',
97
- px_custom_cookie_header: '',
97
+ px_custom_cookie_header: 'x-px-cookies',
98
98
  px_custom_logo: '',
99
+ px_graphql_enabled: true,
100
+ px_graphql_routes: ['/graphql'],
101
+ px_sensitive_graphql_operation_names: [],
102
+ px_sensitive_graphql_operation_types: [],
99
103
  px_enrich_custom_parameters: null,
100
104
  px_proxy_url: '',
101
105
  px_jwt_cookie_name: '',
@@ -165,6 +165,24 @@ export interface IConfiguration<ParamsType extends ConfigurationParams = Configu
165
165
  * The maximum amount of time to wait before sending asynchronous activities to the collector.
166
166
  */
167
167
  readonly activityBatchTimeoutMs: number;
168
+ /**
169
+ * Whether parsing of GraphQL request bodies should be enabled.
170
+ */
171
+ readonly graphqlEnabled: boolean;
172
+ /**
173
+ * Routes that should trigger GraphQL parsing by the enforcer.
174
+ */
175
+ readonly graphqlRoutes: string[];
176
+ /**
177
+ * An array of GraphQL operation names that should trigger a risk API call
178
+ * even if a valid, unexpired, low-score risk cookie is present.
179
+ */
180
+ readonly sensitiveGraphqlOperationNames: string[];
181
+ /**
182
+ * An array of GraphQL operation types (e.g., mutation) that should trigger a risk API call
183
+ * even if a valid, unexpired, low-score risk cookie is present.
184
+ */
185
+ readonly sensitiveGraphqlOperationTypes: string[];
168
186
  /**
169
187
  * A function returning CustomParameters that will be added to the enforcer activities.
170
188
  */
@@ -53,6 +53,10 @@ export declare abstract class StaticConfigurationBase<ParamsType extends Configu
53
53
  get userAgentMaxLength(): number;
54
54
  get maxActivityBatchSize(): number;
55
55
  get activityBatchTimeoutMs(): number;
56
+ get graphqlEnabled(): boolean;
57
+ get graphqlRoutes(): string[];
58
+ get sensitiveGraphqlOperationNames(): string[];
59
+ get sensitiveGraphqlOperationTypes(): string[];
56
60
  get enrichCustomParameters(): CustomParametersFunction;
57
61
  get additionalActivityHandler(): AdditionalActivityHandler;
58
62
  get altBackendCaptchaUrl(): string;
@@ -343,6 +343,34 @@ var StaticConfigurationBase = /** @class */ (function () {
343
343
  enumerable: false,
344
344
  configurable: true
345
345
  });
346
+ Object.defineProperty(StaticConfigurationBase.prototype, "graphqlEnabled", {
347
+ get: function () {
348
+ return this.configParams.px_graphql_enabled;
349
+ },
350
+ enumerable: false,
351
+ configurable: true
352
+ });
353
+ Object.defineProperty(StaticConfigurationBase.prototype, "graphqlRoutes", {
354
+ get: function () {
355
+ return this.configParams.px_graphql_routes;
356
+ },
357
+ enumerable: false,
358
+ configurable: true
359
+ });
360
+ Object.defineProperty(StaticConfigurationBase.prototype, "sensitiveGraphqlOperationNames", {
361
+ get: function () {
362
+ return this.configParams.px_sensitive_graphql_operation_names;
363
+ },
364
+ enumerable: false,
365
+ configurable: true
366
+ });
367
+ Object.defineProperty(StaticConfigurationBase.prototype, "sensitiveGraphqlOperationTypes", {
368
+ get: function () {
369
+ return this.configParams.px_sensitive_graphql_operation_types;
370
+ },
371
+ enumerable: false,
372
+ configurable: true
373
+ });
346
374
  Object.defineProperty(StaticConfigurationBase.prototype, "enrichCustomParameters", {
347
375
  get: function () {
348
376
  return this.configParams.px_enrich_custom_parameters || null;
@@ -4,6 +4,7 @@ import { CustomParameters } from '../custom_parameters';
4
4
  import { FilterReason } from '../filter';
5
5
  import { IHttpRequest, HttpHeaders } from '../http';
6
6
  import { PXDE } from '../pxde';
7
+ import { GraphQLData } from '../graphql';
7
8
  import { IBotDefenderToken, TokenOrigin } from '../risk_token';
8
9
  import { VidSource, PassReason, ICookieParser, IUuidGenerator } from '../utils';
9
10
  import { IContext, MobileData, RequestData, ResponseData, RiskApiData, ServerData, TlsData } from './IContext';
@@ -35,21 +36,21 @@ export declare abstract class ContextBase<OptionsType extends ContextBaseOptions
35
36
  pxde?: PXDE;
36
37
  pxdeVerified?: boolean;
37
38
  customParameters?: CustomParameters;
39
+ graphqlData?: GraphQLData[];
38
40
  protected readonly config: IConfiguration;
39
41
  protected constructor(config: IConfiguration, request: IHttpRequest, options?: OptionsType);
40
42
  protected abstract createRiskToken(config: IConfiguration, cookies: Record<string, string>, options: OptionsType): IBotDefenderToken;
41
43
  protected createRequestData(config: IConfiguration, request: IHttpRequest, cookieParser?: ICookieParser): RequestData;
44
+ protected getCookies(cookieParser: ICookieParser, ...cookieHeaderValues: string[]): Record<string, string>;
42
45
  protected extractUserAgentFromHeader(config: IConfiguration, headers: HttpHeaders): string;
43
46
  protected extractIpFromHeader(config: IConfiguration, headers: HttpHeaders): string;
44
47
  protected isMonitored(config: IConfiguration, requestData: RequestData): boolean;
45
48
  protected isSensitive(config: IConfiguration, { url }: RequestData): boolean;
46
49
  protected isAllowedToBypassMonitor(config: IConfiguration, requestData: RequestData): boolean;
47
- completeInitialization(): Promise<void>;
48
50
  protected setRiskTokenOnContext(config: IConfiguration, options: OptionsType): void;
49
51
  protected setMobileTokenOnContext(config: IConfiguration, mobileToken: string, options: OptionsType): void;
50
52
  protected setWebTokenOnContext(config: IConfiguration, options: OptionsType): void;
51
53
  protected setCookiesOnContext(): void;
52
54
  protected getMobileToken(config: IConfiguration, mobileToken: string, options: OptionsType): IBotDefenderToken;
53
- protected handleCustomParameters(config: IConfiguration, request: IHttpRequest): Promise<void>;
54
55
  get isMobile(): boolean;
55
56
  }
@@ -1,44 +1,7 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
2
  Object.defineProperty(exports, "__esModule", { value: true });
39
3
  exports.ContextBase = void 0;
40
4
  var block_handler_1 = require("../block_handler");
41
- var custom_parameters_1 = require("../custom_parameters");
42
5
  var http_1 = require("../http");
43
6
  var risk_token_1 = require("../risk_token");
44
7
  var utils_1 = require("../utils");
@@ -63,18 +26,28 @@ var ContextBase = /** @class */ (function () {
63
26
  }
64
27
  }
65
28
  ContextBase.prototype.createRequestData = function (config, request, cookieParser) {
66
- var _a;
29
+ var _a, _b;
67
30
  if (cookieParser === void 0) { cookieParser = new utils_1.DefaultCookieParser(); }
68
31
  var url = (0, utils_1.getDecodedUrl)(request.url);
69
32
  var method = request.method;
70
33
  var headers = request.headers;
71
- var cookieHeaderValue = ((_a = request.headers.get(config.customCookieHeader || http_1.COOKIE_HEADER_NAME)) === null || _a === void 0 ? void 0 : _a[0]) || '';
72
- var cookies = cookieHeaderValue ? cookieParser.parseCookies(cookieHeaderValue) : {};
34
+ var cookies = this.getCookies(cookieParser, (_a = request.headers.get(http_1.COOKIE_HEADER_NAME)) === null || _a === void 0 ? void 0 : _a[0], (_b = request.headers.get(config.customCookieHeader)) === null || _b === void 0 ? void 0 : _b[0]);
73
35
  var requestCookieNames = Object.keys(cookies);
74
36
  var userAgent = this.extractUserAgentFromHeader(config, headers);
75
37
  var ip = this.extractIpFromHeader(config, headers);
76
38
  return { url: url, method: method, headers: headers, cookies: cookies, ip: ip, userAgent: userAgent, requestCookieNames: requestCookieNames, request: request };
77
39
  };
40
+ ContextBase.prototype.getCookies = function (cookieParser) {
41
+ var cookieHeaderValues = [];
42
+ for (var _i = 1; _i < arguments.length; _i++) {
43
+ cookieHeaderValues[_i - 1] = arguments[_i];
44
+ }
45
+ var cookies = {};
46
+ cookieHeaderValues.forEach(function (value) {
47
+ Object.assign(cookies, value ? cookieParser.parseCookies(value) : null);
48
+ });
49
+ return cookies;
50
+ };
78
51
  ContextBase.prototype.extractUserAgentFromHeader = function (config, headers) {
79
52
  var _a;
80
53
  var userAgent = ((_a = headers === null || headers === void 0 ? void 0 : headers.get(http_1.USER_AGENT_HEADER_NAME)) === null || _a === void 0 ? void 0 : _a[0]) || '';
@@ -111,18 +84,6 @@ var ContextBase = /** @class */ (function () {
111
84
  return (config.bypassMonitorHeader &&
112
85
  ((_a = requestData.headers.get(config.bypassMonitorHeader)) === null || _a === void 0 ? void 0 : _a[0]) === utils_1.BYPASS_MONITOR_HEADER_VALUE);
113
86
  };
114
- ContextBase.prototype.completeInitialization = function () {
115
- return __awaiter(this, void 0, void 0, function () {
116
- return __generator(this, function (_a) {
117
- switch (_a.label) {
118
- case 0: return [4 /*yield*/, this.handleCustomParameters(this.config, this.requestData.request)];
119
- case 1:
120
- _a.sent();
121
- return [2 /*return*/];
122
- }
123
- });
124
- });
125
- };
126
87
  ContextBase.prototype.setRiskTokenOnContext = function (config, options) {
127
88
  var _a;
128
89
  var mobileToken = (_a = this.requestData.headers.get(utils_1.X_PX_AUTHORIZATION_HEADER_NAME)) === null || _a === void 0 ? void 0 : _a[0];
@@ -169,31 +130,6 @@ var ContextBase = /** @class */ (function () {
169
130
  return null;
170
131
  }
171
132
  };
172
- ContextBase.prototype.handleCustomParameters = function (config, request) {
173
- return __awaiter(this, void 0, void 0, function () {
174
- var _a, _b, _c, e_1;
175
- return __generator(this, function (_d) {
176
- switch (_d.label) {
177
- case 0:
178
- if (!(config.enrichCustomParameters && typeof config.enrichCustomParameters === 'function')) return [3 /*break*/, 4];
179
- _d.label = 1;
180
- case 1:
181
- _d.trys.push([1, 3, , 4]);
182
- _a = this;
183
- _c = (_b = custom_parameters_1.CustomParametersUtils).normalizeCustomParams;
184
- return [4 /*yield*/, config.enrichCustomParameters(config.toParams(), request)];
185
- case 2:
186
- _a.customParameters = _c.apply(_b, [_d.sent()]);
187
- return [3 /*break*/, 4];
188
- case 3:
189
- e_1 = _d.sent();
190
- config.logger.error("unable to enrich custom params: ".concat(e_1));
191
- return [3 /*break*/, 4];
192
- case 4: return [2 /*return*/];
193
- }
194
- });
195
- });
196
- };
197
133
  Object.defineProperty(ContextBase.prototype, "isMobile", {
198
134
  get: function () {
199
135
  return this.tokenOrigin === risk_token_1.TokenOrigin.HEADER;
@@ -6,6 +6,7 @@ import { BlockAction, BlockReason } from '../block_handler';
6
6
  import { HttpHeaders, HttpMethod, IHttpRequest } from '../http';
7
7
  import { CustomParameters } from '../custom_parameters';
8
8
  import { PXDE } from '../pxde';
9
+ import { GraphQLData } from '../graphql/model/GraphQLData';
9
10
  export declare type RequestData = {
10
11
  /**
11
12
  * The request URL.
@@ -253,8 +254,8 @@ export interface IContext {
253
254
  */
254
255
  customParameters?: CustomParameters;
255
256
  /**
256
- * A function that completes context initialization. Should be called only if
257
- * the request should not be filtered and is not first-party.
257
+ * An array of objects with information about the different GraphQL operations
258
+ * parsed from the request.
258
259
  */
259
- completeInitialization(): Promise<void>;
260
+ graphqlData?: GraphQLData[];
260
261
  }
@@ -1,4 +1,7 @@
1
+ import { IConfiguration } from '../config';
2
+ import { IContext } from '../context';
1
3
  import { CustomParameters } from './CustomParameters';
2
4
  export declare namespace CustomParametersUtils {
5
+ const handleCustomParameters: (config: IConfiguration, context: IContext) => Promise<void>;
3
6
  const normalizeCustomParams: (customParameters: Record<string, any>) => CustomParameters;
4
7
  }
@@ -1,8 +1,67 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
2
38
  Object.defineProperty(exports, "__esModule", { value: true });
3
39
  exports.CustomParametersUtils = void 0;
4
40
  var CustomParametersUtils;
5
41
  (function (CustomParametersUtils) {
42
+ var _this = this;
43
+ CustomParametersUtils.handleCustomParameters = function (config, context) { return __awaiter(_this, void 0, void 0, function () {
44
+ var parameters, e_1;
45
+ return __generator(this, function (_a) {
46
+ switch (_a.label) {
47
+ case 0:
48
+ if (!(config.enrichCustomParameters && typeof config.enrichCustomParameters === 'function')) return [3 /*break*/, 4];
49
+ _a.label = 1;
50
+ case 1:
51
+ _a.trys.push([1, 3, , 4]);
52
+ return [4 /*yield*/, config.enrichCustomParameters(config.toParams(), context.requestData.request)];
53
+ case 2:
54
+ parameters = _a.sent();
55
+ context.customParameters = CustomParametersUtils.normalizeCustomParams(parameters);
56
+ return [3 /*break*/, 4];
57
+ case 3:
58
+ e_1 = _a.sent();
59
+ config.logger.error("unable to enrich custom params: ".concat(e_1));
60
+ return [3 /*break*/, 4];
61
+ case 4: return [2 /*return*/];
62
+ }
63
+ });
64
+ }); };
6
65
  CustomParametersUtils.normalizeCustomParams = function (customParameters) {
7
66
  var normalizedParams = {};
8
67
  if (customParameters && typeof customParameters === 'object') {
@@ -10,6 +10,7 @@ import { ITelemetry } from '../telemetry';
10
10
  import { IBlockResponseGenerator } from '../block_handler';
11
11
  import { TokenVersion } from '../risk_token';
12
12
  import { IActivityClient } from '../activities';
13
+ import { IGraphQLParser } from '../graphql';
13
14
  export declare type EnforcerBaseOptions = {
14
15
  tokenVersion?: TokenVersion;
15
16
  dataEnrichment?: IDataEnrichment;
@@ -20,6 +21,7 @@ export declare type EnforcerBaseOptions = {
20
21
  hashUtils?: IHashUtils;
21
22
  cipherUtils?: ICipherUtils;
22
23
  blockGenerator?: IBlockResponseGenerator;
24
+ graphqlParser?: IGraphQLParser;
23
25
  } & ({
24
26
  httpClient: IHttpClient;
25
27
  firstParty?: IFirstParty;
@@ -43,6 +45,7 @@ export declare abstract class EnforcerBase<EnforceArgs extends any[], Req, Res>
43
45
  protected riskApiScoreRetriever: IScoreRetriever;
44
46
  protected blockGenerator: IBlockResponseGenerator;
45
47
  protected activityClient: IActivityClient;
48
+ protected graphQLParser?: IGraphQLParser;
46
49
  /**
47
50
  * Returns the original Req object in case the module is disabled or an error is thrown.
48
51
  * @param args - The EnforceArgs required to enforce the incoming request.
@@ -65,7 +68,7 @@ export declare abstract class EnforcerBase<EnforceArgs extends any[], Req, Res>
65
68
  * @returns IContext - The context for the request.
66
69
  * @protected
67
70
  */
68
- protected abstract retrieveContext(req: Req, res: Res, ...args: EnforceArgs): IContext;
71
+ protected abstract retrieveContext(req: Req, res: Res, ...args: EnforceArgs): IContext | null;
69
72
  /**
70
73
  * Converts the IHttpRequest object into the Req object.
71
74
  * @param httpRequest - The IHttpRequest object.
@@ -118,6 +121,8 @@ export declare abstract class EnforcerBase<EnforceArgs extends any[], Req, Res>
118
121
  protected handleFirstParty(context: IContext): Promise<IHttpResponse>;
119
122
  protected handleFilter(context: IContext): boolean;
120
123
  protected handleCompleteContextInitialization(context: IContext): Promise<void>;
124
+ protected handleGraphQL(context: IContext): Promise<void>;
125
+ protected handleEnrichCustomParameters(context: IContext): Promise<void>;
121
126
  protected handleTelemetryIfNeeded(context: IContext): Promise<void>;
122
127
  protected handlePxde(context: IContext): Promise<void>;
123
128
  protected handleCookieRetrieverIfNeeded(context: IContext): Promise<void>;
@@ -57,6 +57,8 @@ var block_handler_1 = require("../block_handler");
57
57
  var risk_token_1 = require("../risk_token");
58
58
  var risk_api_1 = require("../risk_api");
59
59
  var activities_1 = require("../activities");
60
+ var graphql_1 = require("../graphql");
61
+ var custom_parameters_1 = require("../custom_parameters");
60
62
  var EnforcerBase = /** @class */ (function () {
61
63
  /**
62
64
  * The EnforcerBase constructor.
@@ -72,6 +74,9 @@ var EnforcerBase = /** @class */ (function () {
72
74
  this.cookieScoreRetriever = options.cookieScoreRetriever || new risk_token_1.RiskTokenScoreRetriever(this.config);
73
75
  this.blockGenerator = options.blockGenerator || new block_handler_1.DefaultBlockResponseGenerator(this.config, base64Utils);
74
76
  this.dataEnrichment = options.dataEnrichment || new pxde_1.DefaultDataEnrichment(this.config, base64Utils, hashUtils);
77
+ this.graphQLParser = this.config.graphqlEnabled
78
+ ? options.graphqlParser || new graphql_1.DefaultGraphQLParser(this.config)
79
+ : null;
75
80
  var httpClient = options.httpClient;
76
81
  this.firstParty = options.firstParty || new first_party_1.DefaultFirstParty(this.config, httpClient);
77
82
  this.telemetry = options.telemetry || new telemetry_1.DefaultTelemetry(this.config, httpClient, base64Utils, hashUtils);
@@ -151,23 +156,29 @@ var EnforcerBase = /** @class */ (function () {
151
156
  case 3:
152
157
  _a.sent();
153
158
  this.config.logger.debug('context initialization complete');
154
- return [4 /*yield*/, this.handleTelemetryIfNeeded(context)];
159
+ return [4 /*yield*/, this.handleGraphQL(context)];
155
160
  case 4:
156
161
  _a.sent();
157
- return [4 /*yield*/, this.handlePxde(context)];
162
+ return [4 /*yield*/, this.handleEnrichCustomParameters(context)];
158
163
  case 5:
159
164
  _a.sent();
160
- return [4 /*yield*/, this.handleCookieRetrieverIfNeeded(context)];
165
+ return [4 /*yield*/, this.handleTelemetryIfNeeded(context)];
161
166
  case 6:
162
167
  _a.sent();
163
- return [4 /*yield*/, this.handleRiskApiIfNeeded(context)];
168
+ return [4 /*yield*/, this.handlePxde(context)];
164
169
  case 7:
165
170
  _a.sent();
166
- return [4 /*yield*/, this.handleAdditionalActivityHandler(context)];
171
+ return [4 /*yield*/, this.handleCookieRetrieverIfNeeded(context)];
167
172
  case 8:
168
173
  _a.sent();
169
- return [4 /*yield*/, this.handleBlockResponse(context)];
174
+ return [4 /*yield*/, this.handleRiskApiIfNeeded(context)];
170
175
  case 9:
176
+ _a.sent();
177
+ return [4 /*yield*/, this.handleAdditionalActivityHandler(context)];
178
+ case 10:
179
+ _a.sent();
180
+ return [4 /*yield*/, this.handleBlockResponse(context)];
181
+ case 11:
171
182
  httpResponse = _a.sent();
172
183
  if (httpResponse) {
173
184
  this.config.logger.debug("blocking request due to ".concat(context.blockReason));
@@ -204,10 +215,33 @@ var EnforcerBase = /** @class */ (function () {
204
215
  return this.filter.shouldFilter(context);
205
216
  };
206
217
  EnforcerBase.prototype.handleCompleteContextInitialization = function (context) {
218
+ return __awaiter(this, void 0, void 0, function () {
219
+ return __generator(this, function (_a) {
220
+ return [2 /*return*/];
221
+ });
222
+ });
223
+ };
224
+ EnforcerBase.prototype.handleGraphQL = function (context) {
225
+ var _a;
226
+ return __awaiter(this, void 0, void 0, function () {
227
+ return __generator(this, function (_b) {
228
+ switch (_b.label) {
229
+ case 0:
230
+ if (!((_a = this.graphQLParser) === null || _a === void 0 ? void 0 : _a.isGraphQLRequest(context))) return [3 /*break*/, 2];
231
+ return [4 /*yield*/, this.graphQLParser.parseGraphQLRequest(context)];
232
+ case 1:
233
+ _b.sent();
234
+ _b.label = 2;
235
+ case 2: return [2 /*return*/];
236
+ }
237
+ });
238
+ });
239
+ };
240
+ EnforcerBase.prototype.handleEnrichCustomParameters = function (context) {
207
241
  return __awaiter(this, void 0, void 0, function () {
208
242
  return __generator(this, function (_a) {
209
243
  switch (_a.label) {
210
- case 0: return [4 /*yield*/, context.completeInitialization()];
244
+ case 0: return [4 /*yield*/, custom_parameters_1.CustomParametersUtils.handleCustomParameters(this.config, context)];
211
245
  case 1:
212
246
  _a.sent();
213
247
  return [2 /*return*/];
@@ -153,7 +153,7 @@ var DefaultFirstParty = /** @class */ (function () {
153
153
  case 1: return [2 /*return*/, _b.sent()];
154
154
  case 2:
155
155
  e_1 = _b.sent();
156
- this.config.logger.debug("failed sending first party request to ".concat(url));
156
+ this.config.logger.debug("failed sending first party request to ".concat(url, ": ").concat(e_1));
157
157
  return [2 /*return*/, null];
158
158
  case 3: return [2 /*return*/];
159
159
  }
@@ -0,0 +1,19 @@
1
+ import { IContext } from '../context/IContext';
2
+ import { IConfiguration } from '../config';
3
+ import { IGraphQLParser } from './IGraphQLParser';
4
+ export declare class DefaultGraphQLParser implements IGraphQLParser {
5
+ private readonly logger;
6
+ private readonly graphqlRoutes;
7
+ private readonly sensitiveOperationTypes;
8
+ private readonly sensitiveOperationNames;
9
+ constructor(config: IConfiguration);
10
+ isGraphQLRequest({ requestData }: IContext): boolean;
11
+ parseGraphQLRequest(context: IContext): Promise<boolean>;
12
+ private getGraphQLOperationsFromBody;
13
+ private parseGraphQLOperations;
14
+ private parseGraphQlOperation;
15
+ private getOperationNameToTypeMap;
16
+ private getGraphQLData;
17
+ private isSensitiveOperation;
18
+ private extractGraphQLVariableNames;
19
+ }
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DefaultGraphQLParser = void 0;
40
+ var http_1 = require("../http");
41
+ var GraphQLOperationType_1 = require("./model/GraphQLOperationType");
42
+ var utils_1 = require("../utils");
43
+ var DefaultGraphQLParser = /** @class */ (function () {
44
+ function DefaultGraphQLParser(config) {
45
+ this.logger = config.logger;
46
+ this.graphqlRoutes = config.graphqlRoutes;
47
+ this.sensitiveOperationNames = config.sensitiveGraphqlOperationNames;
48
+ this.sensitiveOperationTypes = config.sensitiveGraphqlOperationTypes;
49
+ }
50
+ DefaultGraphQLParser.prototype.isGraphQLRequest = function (_a) {
51
+ var requestData = _a.requestData;
52
+ return (requestData.method === http_1.HttpMethod.POST && (0, utils_1.isRouteInPatterns)(requestData.url.pathname, this.graphqlRoutes));
53
+ };
54
+ DefaultGraphQLParser.prototype.parseGraphQLRequest = function (context) {
55
+ return __awaiter(this, void 0, void 0, function () {
56
+ var graphQLOperations, data, e_1;
57
+ return __generator(this, function (_a) {
58
+ switch (_a.label) {
59
+ case 0:
60
+ _a.trys.push([0, 2, , 3]);
61
+ return [4 /*yield*/, this.getGraphQLOperationsFromBody(context.requestData)];
62
+ case 1:
63
+ graphQLOperations = _a.sent();
64
+ if (!graphQLOperations) {
65
+ this.logger.debug('unable to get graphql operations from request body');
66
+ return [2 /*return*/, false];
67
+ }
68
+ data = this.parseGraphQLOperations(graphQLOperations);
69
+ if (!data || data.length === 0) {
70
+ this.logger.debug('unable to parse graphql operations');
71
+ return [2 /*return*/, false];
72
+ }
73
+ this.logger.debug("".concat(data.length, " graphql operation").concat(data.length === 1 ? '' : 's', " parsed successfully"));
74
+ context.graphqlData = data;
75
+ context.isSensitiveRequest = context.isSensitiveRequest || data.some(function (operation) { return operation.sensitive; });
76
+ return [2 /*return*/, true];
77
+ case 2:
78
+ e_1 = _a.sent();
79
+ this.logger.debug("error parsing graphql request: ".concat(e_1));
80
+ return [2 /*return*/, false];
81
+ case 3: return [2 /*return*/];
82
+ }
83
+ });
84
+ });
85
+ };
86
+ DefaultGraphQLParser.prototype.getGraphQLOperationsFromBody = function (_a) {
87
+ var request = _a.request;
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var body;
90
+ return __generator(this, function (_b) {
91
+ switch (_b.label) {
92
+ case 0: return [4 /*yield*/, request.readBody()];
93
+ case 1:
94
+ body = _b.sent();
95
+ if (typeof body === 'string') {
96
+ try {
97
+ body = JSON.parse(body);
98
+ }
99
+ catch (e) {
100
+ this.logger.debug("unable to parse string body: ".concat(e));
101
+ }
102
+ }
103
+ if (!body || typeof body !== 'object') {
104
+ return [2 /*return*/, null];
105
+ }
106
+ return [2 /*return*/, Array.isArray(body) ? body : [body]];
107
+ }
108
+ });
109
+ });
110
+ };
111
+ DefaultGraphQLParser.prototype.parseGraphQLOperations = function (operations) {
112
+ var _this = this;
113
+ return operations.map(function (operation) { return _this.parseGraphQlOperation(operation); }).filter(function (x) { return x; });
114
+ };
115
+ DefaultGraphQLParser.prototype.parseGraphQlOperation = function (operation) {
116
+ if (!operation.query || typeof operation.query !== 'string') {
117
+ return null;
118
+ }
119
+ var operationNameToTypeMap = this.getOperationNameToTypeMap(operation.query);
120
+ if (!operationNameToTypeMap) {
121
+ return null;
122
+ }
123
+ return this.getGraphQLData(operationNameToTypeMap, operation);
124
+ };
125
+ DefaultGraphQLParser.prototype.getOperationNameToTypeMap = function (query) {
126
+ var operationTypesString = Object.values(GraphQLOperationType_1.GraphQLOperationType).join('|');
127
+ var pattern = new RegExp("\\s*(".concat(operationTypesString, ")\\s+(\\w+)"), 'gm');
128
+ var match;
129
+ var map = {};
130
+ while ((match = pattern.exec(query)) !== null) {
131
+ var operationType = match[1];
132
+ var operationName = match[2];
133
+ if (map[operationName]) {
134
+ // query contains two operations with the same name which is illegal
135
+ return null;
136
+ }
137
+ else {
138
+ map[operationName] = operationType;
139
+ }
140
+ }
141
+ return map;
142
+ };
143
+ DefaultGraphQLParser.prototype.getGraphQLData = function (operationNameToTypeMap, operation) {
144
+ var name = operation.operationName ||
145
+ (Object.keys(operationNameToTypeMap).length === 1 ? Object.keys(operationNameToTypeMap)[0] : undefined);
146
+ var type = operationNameToTypeMap[name];
147
+ if (!type && /^\s*{/.test(operation.query)) {
148
+ type = GraphQLOperationType_1.GraphQLOperationType.QUERY;
149
+ }
150
+ if (!type) {
151
+ return null;
152
+ }
153
+ var data = { name: name, type: type };
154
+ if (this.isSensitiveOperation(name, type)) {
155
+ data.sensitive = true;
156
+ }
157
+ if (operation.variables && typeof operation.variables === 'object') {
158
+ data.variables = this.extractGraphQLVariableNames(operation.variables);
159
+ }
160
+ return data;
161
+ };
162
+ DefaultGraphQLParser.prototype.isSensitiveOperation = function (operationName, operationType) {
163
+ return (this.sensitiveOperationTypes.some(function (type) { return type === operationType; }) ||
164
+ this.sensitiveOperationNames.some(function (name) { return name === operationName; }));
165
+ };
166
+ DefaultGraphQLParser.prototype.extractGraphQLVariableNames = function (variables) {
167
+ var processVariables = function (variablesObj, prefix) {
168
+ return Object.entries(variablesObj).reduce(function (total, _a) {
169
+ var key = _a[0], value = _a[1];
170
+ if (!value || typeof value !== 'object' || Object.keys(value).length === 0) {
171
+ total.push(prefix + key);
172
+ return total;
173
+ }
174
+ else {
175
+ return total.concat(processVariables(value, "".concat(prefix).concat(key, ".")));
176
+ }
177
+ }, []);
178
+ };
179
+ return processVariables(variables, '');
180
+ };
181
+ return DefaultGraphQLParser;
182
+ }());
183
+ exports.DefaultGraphQLParser = DefaultGraphQLParser;
@@ -0,0 +1,5 @@
1
+ import { IContext } from '../context';
2
+ export interface IGraphQLParser {
3
+ isGraphQLRequest(context: IContext): boolean;
4
+ parseGraphQLRequest(context: IContext): Promise<boolean>;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export { GraphQLOperationType } from './model/GraphQLOperationType';
2
+ export { GraphQLOperation } from './model/GraphQLOperation';
3
+ export { GraphQLData } from './model/GraphQLData';
4
+ export { IGraphQLParser } from './IGraphQLParser';
5
+ export { DefaultGraphQLParser } from './DefaultGraphQLParser';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultGraphQLParser = exports.GraphQLOperationType = void 0;
4
+ var GraphQLOperationType_1 = require("./model/GraphQLOperationType");
5
+ Object.defineProperty(exports, "GraphQLOperationType", { enumerable: true, get: function () { return GraphQLOperationType_1.GraphQLOperationType; } });
6
+ var DefaultGraphQLParser_1 = require("./DefaultGraphQLParser");
7
+ Object.defineProperty(exports, "DefaultGraphQLParser", { enumerable: true, get: function () { return DefaultGraphQLParser_1.DefaultGraphQLParser; } });
@@ -0,0 +1,7 @@
1
+ import { GraphQLOperationType } from './GraphQLOperationType';
2
+ export declare type GraphQLData = {
3
+ type: GraphQLOperationType;
4
+ name?: string;
5
+ sensitive?: boolean;
6
+ variables?: string[];
7
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export declare type GraphQLOperation = {
2
+ query: string;
3
+ operationName?: string;
4
+ variables?: Record<string, unknown>;
5
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export declare enum GraphQLOperationType {
2
+ QUERY = "query",
3
+ MUTATION = "mutation",
4
+ SUBSCRIPTION = "subscription"
5
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphQLOperationType = void 0;
4
+ var GraphQLOperationType;
5
+ (function (GraphQLOperationType) {
6
+ GraphQLOperationType["QUERY"] = "query";
7
+ GraphQLOperationType["MUTATION"] = "mutation";
8
+ GraphQLOperationType["SUBSCRIPTION"] = "subscription";
9
+ })(GraphQLOperationType = exports.GraphQLOperationType || (exports.GraphQLOperationType = {}));
@@ -1,6 +1,7 @@
1
1
  export declare type HttpHeadersInit = Record<string, string[]>;
2
2
  export declare class HttpHeaders {
3
3
  private readonly headers;
4
+ static from(headers: Headers): HttpHeaders;
4
5
  /**
5
6
  * Constructs a new instance of the HttpHeaders class.
6
7
  * @param init - Optional header names and values with which to initialize the HttpHeaders instance.
@@ -41,11 +42,12 @@ export declare class HttpHeaders {
41
42
  * @returns object - An object representing the current state of the HttpHeaders instance. The keys are the header
42
43
  * names (all lowercase), and the values are arrays of all the associated header values.
43
44
  */
44
- toObject(): Record<string, string[]>;
45
+ toObject(joinDelimiter?: string): Record<string, string | string[]>;
45
46
  /**
46
47
  * Iterates through all headers and applies a callback function to each one.
47
48
  * @param callbackFn - The callback function to be applied on every header.
48
49
  */
49
50
  forEach(callbackFn: (values: readonly string[], name: string) => void): void;
50
51
  private toKey;
52
+ entries(delimiter?: string): [string, string][];
51
53
  }
@@ -19,6 +19,13 @@ var HttpHeaders = /** @class */ (function () {
19
19
  var _this = this;
20
20
  this.headers = init ? new Map(Object.keys(init).map(function (name) { return [_this.toKey(name), init[name]]; })) : new Map();
21
21
  }
22
+ HttpHeaders.from = function (headers) {
23
+ var ret = new HttpHeaders();
24
+ headers.forEach(function (value, key) {
25
+ ret.append(key, value);
26
+ });
27
+ return ret;
28
+ };
22
29
  /**
23
30
  * Retrieves the values associated with the provided header name. If no header exists, it returns undefined.
24
31
  * @param name - The case-insensitive header name.
@@ -84,10 +91,10 @@ var HttpHeaders = /** @class */ (function () {
84
91
  * @returns object - An object representing the current state of the HttpHeaders instance. The keys are the header
85
92
  * names (all lowercase), and the values are arrays of all the associated header values.
86
93
  */
87
- HttpHeaders.prototype.toObject = function () {
94
+ HttpHeaders.prototype.toObject = function (joinDelimiter) {
88
95
  var obj = {};
89
96
  this.forEach(function (values, name) {
90
- obj[name] = __spreadArray([], values, true);
97
+ obj[name] = joinDelimiter ? values.join(joinDelimiter) : __spreadArray([], values, true);
91
98
  });
92
99
  return obj;
93
100
  };
@@ -101,6 +108,16 @@ var HttpHeaders = /** @class */ (function () {
101
108
  HttpHeaders.prototype.toKey = function (name) {
102
109
  return name.toLowerCase();
103
110
  };
111
+ HttpHeaders.prototype.entries = function (delimiter) {
112
+ if (delimiter === void 0) { delimiter = ','; }
113
+ var ret = [];
114
+ this.headers.forEach(function (values, headerName) {
115
+ if (values === null || values === void 0 ? void 0 : values.length) {
116
+ ret.push([headerName, values.join(delimiter)]);
117
+ }
118
+ });
119
+ return ret;
120
+ };
104
121
  return HttpHeaders;
105
122
  }());
106
123
  exports.HttpHeaders = HttpHeaders;
package/lib/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from './custom_parameters';
7
7
  export * from './enforcer';
8
8
  export * from './filter';
9
9
  export * from './first_party';
10
+ export * from './graphql';
10
11
  export * from './http';
11
12
  export * from './logger';
12
13
  export * from './pxde';
package/lib/index.js CHANGED
@@ -23,6 +23,7 @@ __exportStar(require("./custom_parameters"), exports);
23
23
  __exportStar(require("./enforcer"), exports);
24
24
  __exportStar(require("./filter"), exports);
25
25
  __exportStar(require("./first_party"), exports);
26
+ __exportStar(require("./graphql"), exports);
26
27
  __exportStar(require("./http"), exports);
27
28
  __exportStar(require("./logger"), exports);
28
29
  __exportStar(require("./pxde"), exports);
@@ -37,7 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.PostRiskApiClient = void 0;
40
- var TokenOrigin_1 = require("../risk_token/TokenOrigin");
40
+ var risk_token_1 = require("../risk_token");
41
41
  var http_1 = require("../http");
42
42
  var utils_1 = require("../utils");
43
43
  var S2SCallReason_1 = require("./S2SCallReason");
@@ -136,7 +136,7 @@ var PostRiskApiClient = /** @class */ (function () {
136
136
  http_method: context.requestData.method,
137
137
  http_version: context.requestData.httpVersion,
138
138
  risk_mode: context.isMonitoredRequest ? utils_1.ModuleMode.MONITOR : utils_1.ModuleMode.ACTIVE_BLOCKING,
139
- cookie_origin: context.tokenOrigin || TokenOrigin_1.TokenOrigin.COOKIE,
139
+ cookie_origin: context.tokenOrigin || risk_token_1.TokenOrigin.COOKIE,
140
140
  request_cookie_names: context.requestData.requestCookieNames,
141
141
  request_id: context.requestId,
142
142
  },
@@ -169,6 +169,7 @@ var PostRiskApiClient = /** @class */ (function () {
169
169
  PostRiskApiClient.prototype.addOptionalRiskFieldsToAdditional = function (riskActivity, context) {
170
170
  (0, utils_1.transferExistingProperties)(context, riskActivity.additional, {
171
171
  vidSource: 'enforcer_vid_source',
172
+ graphqlData: 'graphql_operations',
172
173
  });
173
174
  (0, utils_1.transferExistingProperties)(context.serverData, riskActivity.additional, {
174
175
  region: 'server_info_region',
@@ -197,11 +198,13 @@ var PostRiskApiClient = /** @class */ (function () {
197
198
  PostRiskApiClient.prototype.addCookieRiskFieldsToAdditional = function (riskActivity, _a) {
198
199
  var riskToken = _a.riskToken;
199
200
  if (riskToken) {
200
- riskActivity.additional.px_orig_cookie = riskToken.getCookieString();
201
201
  if (riskToken.isValid()) {
202
202
  riskActivity.additional.px_cookie = riskToken.getPayloadString();
203
203
  riskActivity.additional.px_cookie_hmac = riskToken.hmac;
204
204
  }
205
+ else {
206
+ riskActivity.additional.px_orig_cookie = riskToken.getCookieString();
207
+ }
205
208
  }
206
209
  };
207
210
  PostRiskApiClient.prototype.formatRiskHeadersField = function (headers) {
@@ -1,6 +1,7 @@
1
1
  import { ModuleMode, VidSource } from '../../utils';
2
2
  import { TokenOrigin } from '../../risk_token';
3
3
  import { CustomParameters } from '../../custom_parameters';
4
+ import { GraphQLData } from '../../graphql/';
4
5
  import { S2SCallReason } from '../S2SCallReason';
5
6
  export declare type HeaderEntry = {
6
7
  name: string;
@@ -40,6 +41,7 @@ export declare type RiskAdditionalData = {
40
41
  cross_tab_session?: string;
41
42
  app_user_id?: string;
42
43
  jwt_additional_fields?: string[];
44
+ graphql_operations?: GraphQLData[];
43
45
  } & CustomParameters;
44
46
  export declare type RiskActivity = {
45
47
  vid?: string;
@@ -1,8 +1,10 @@
1
1
  import { RiskStatus } from './RiskStatus';
2
2
  import { PXDE } from '../../pxde';
3
+ import { BlockAction } from '../../block_handler';
3
4
  export declare type RiskResponseV2 = {
4
5
  status: RiskStatus;
5
6
  cookie_cfg_block_result?: '0' | '1';
7
+ action?: BlockAction;
6
8
  uuid?: string;
7
9
  pxhd?: string;
8
10
  message?: string;
@@ -35,6 +35,7 @@ var RiskResponseV2Handler = /** @class */ (function (_super) {
35
35
  (0, utils_1.transferExistingProperties)(riskResponse, context, {
36
36
  uuid: 'uuid',
37
37
  pxhd: 'pxhd',
38
+ action: 'blockAction',
38
39
  data_enrichment: 'pxde',
39
40
  });
40
41
  if (riskResponse.data_enrichment) {
@@ -7,4 +7,4 @@ export declare const BYPASS_MONITOR_HEADER_VALUE = "1";
7
7
  export declare const X_PX_AUTHORIZATION_HEADER_NAME = "x-px-authorization";
8
8
  export declare const X_PX_ORIGINAL_TOKEN_HEADER_NAME = "x-px-original-token";
9
9
  export declare const X_PX_BYPASS_REASON_HEADER_NAME = "x-px-bypass-reason";
10
- export declare const CORE_MODULE_VERSION = "JS Core 0.2.0";
10
+ export declare const CORE_MODULE_VERSION = "JS Core 0.3.0";
@@ -10,4 +10,4 @@ exports.BYPASS_MONITOR_HEADER_VALUE = '1';
10
10
  exports.X_PX_AUTHORIZATION_HEADER_NAME = 'x-px-authorization';
11
11
  exports.X_PX_ORIGINAL_TOKEN_HEADER_NAME = 'x-px-original-token';
12
12
  exports.X_PX_BYPASS_REASON_HEADER_NAME = 'x-px-bypass-reason';
13
- exports.CORE_MODULE_VERSION = 'JS Core 0.2.0';
13
+ exports.CORE_MODULE_VERSION = 'JS Core 0.3.0';
@@ -104,7 +104,7 @@ var isRouteMatch = function (route, pattern) {
104
104
  if (!route || !pattern) {
105
105
  return false;
106
106
  }
107
- if (pattern instanceof RegExp && route.match(pattern)) {
107
+ if (pattern instanceof RegExp && pattern.test(route)) {
108
108
  return true;
109
109
  }
110
110
  if (typeof pattern === 'string' && route.startsWith(pattern)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perimeterx-js-core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -39,7 +39,6 @@
39
39
  "core-js": "^3.19.1",
40
40
  "eslint": "^8.25.0",
41
41
  "eslint-config-prettier": "^8.5.0",
42
- "eslint-plugin-no-loops": "^0.3.0",
43
42
  "eslint-plugin-prettier": "^4.2.1",
44
43
  "husky": "^8.0.3",
45
44
  "lint-staged": "^13.1.0",