0.18.2 • Published 2 months ago

perimeterx-js-core v0.18.2

Weekly downloads
-
License
ISC
Repository
-
Last release
2 months ago

PerimeterX JavaScript Core

Overview

The purpose of this repository is to provide the components and utilities needed to build a JavaScript/TypeScript enforcer on any platform/environment. This repository is not a complete running enforcer; rather, it is a tool kit with all the building blocks that an enforcer comprises, separated into small, self-contained chunks.

A single repository for core enforcer components allows for:

  • Consistent functionality across all JavaScript enforcers.
  • Faster delivery of new features and bug fixes.

Design Principles

This library was designed with an interface-first mindset. In other words, all provided classes are implementations of defined interfaces. Whenever possible, you should use the provided, default implementation for a particular feature to ensure consistent behavior across enforcers.

However, if the default component cannot be made to function in the framework you are working on, extend it or create a new class that implements the relevant interface, and it will work with all the other components in the library.

Another important note is that components such as the risk API client, token parser, products, and other such classes are not permitted to modify the context. Rather than make alterations to the context directly, they return data that is then used by phases to adjust the context as needed. This helps separate specific product logic (e.g., Bot Defender, Account Defender, etc.) from the logic and actions of the enforcer as a whole.

Naming Conventions

  • Interfaces always start with the letter I (e.g., IFirstParty)
  • Abstract classes always end with the word Base (e.g., TokenParserBase)
  • Complete, standard implementations start with the word Default (e.g., DefaultTelemetry)
  • Utility functions relevant to a particular feature live in a Utils namespace named for the feature (e.g., PXHDUtils)

Library Components

In using this library, most features will work out-of-the-box. However, there are certain classes you will need to modify depending on the specific platform you're developing for.

Most development you will need to complete will most likely be in the following areas.

Enforcer

While every enforcer will require a different implementation, the API and sequence of events in an enforcer should be consistent across different SDKs. To maintain consistency, the following interface and abstract class have been included.

IEnforcer - Represents the enforcer itself. The parameters and return values are any due to the varying nature of each platform. The specific enforcer implementation you create should have a concrete signature.

EnforcerBase - An abstract base class that provides the basic enforcer flow with the default building blocks. Select abstract functions must be implemented (such as constructing the context, etc.). All key functional building blocks are interfaces that can be swapped out, and modifications to the flow can be made by overriding the protected class methods.

Configuration

Every enforcer configuration is different. This includes how the configurations are stored (a JSON file, in-memory object, or KV namespace), the configuration values themselves, and logging functionality. Utilize these components to simplify your enforcer's configuration setup.

IConfiguration - Represents the enforcer configuration and is required to construct most other components in this library.

ConfigurationBase - An implementation of the above interface that validates provided configurations and merges them with default ones.

DefaultConfigurations - A static object complete with all default enforcer configurations.

Context

Different platforms expose varying levels of information about the HTTP request and server environment. Additionally, the cryptographic capabilities on each platform may vary, allowing the support of either V2 or V3 of the Risk Cookie. While you will need to create a custom implementation for the request context, you can use these tools to help.

IContext - Represents the request context.

DefaultContext - An implementation of the above interface that takes care of basic context setup.

HTTP

Every framework has a different API for creating and sending HTTP requests and responses. This library reduces this functionality into several interfaces:

IHeaders - Represents the HTTP request/response headers.

IIncomingRequest - Represents an HTTP request from the user.

IOutgoingResponse - Represents an HTTP response which is returned to the user.

IOutgoingRequest - Represents an HTTP request that can be executed (sent to other origin)

IIncomingResponse - Represents an HTTP response that received from sending IOutgoingRequest

IHttpClient - Represents a client that can send an IIncomingRequest and return an IOutgoingResponse.

When developing your JavaScript/TypeScript enforcer with this library, you will need to wrap the native HTTP request/response objects such that they conform to these interfaces. Of course, you are free to extend these interfaces as needed.

You will also need to implement an HTTP client. You can do this however you see fit: use the platform's built-in API or use an external library if needed. This library includes implementations using phin (PhinHttpClient and PhinIncomingResponse) for Node.js-based enforcers.

Crypto

Since cryptographic functionality varies from platform to platform, this library's crypto utils takes the form of interfaces as well.

IBase64Utils - Represents a Base64 encoding and decoding utility that other components may require. The following implementations are provided:

  • AtobBase64Utils, which relies on native atob and btoa functions.
  • BufferBase64Utils, which relies on the native NodeJS Buffer.from() function.
  • JSBase64Base64Utils, which uses the js-base64 dependency.

IHmacUtils - Represents an HMAC-generating utility that other components may require. The following implementations are provided:

  • CryptoHmacUtils, which relies on the native NodeJS crypto package.
  • CryptoJSHmacUtils, which uses the crypto-js dependency.

ICipherUtils - Represents an encryption and decryption utility that is required for RiskTokenV3. The following implementations are provided:

  • CryptoCipherUtils, which relies on the native NodeJS crypto package.
  • SubtleCryptoCipherUtils, which relies on an object implementing the SubtleCrypto interface. By default, it is assumed that the global crypto.subtle implements this interface.

IHashUtils - Represents a hashing utility that is required by Credential Intelligence. The following implementations are provided:

  • CryptoHashUtils, which relies on the native NodeJS crypto package.
  • CryptoJSHashUtils, which uses the crypto-js dependency.
  • SubtleCryptoHashUtils, which relies on an object implementing the SubtleCrypto interface. By default, it is assumed that the global crypto.subtle implements this interface.

Other Dependencies

All dependencies in this library have been encapsulated into specific implementations with a defined interface and therefore can be swapped with other implementations. These classes are:

LibraryImplementationUsed For
crypto-jsCryptoJSHmacUtilsPXDE, telemetry, token V2/V3, etc.
js-base64JSBase64Base64UtilsPXDE, telemetry, token V2, etc.
uuidUuidRequestIdGeneratorDefaultContext
ip-range-checkDefaultIpRangeCheckerDefaultBotDefenderFilter
phinPhinHttpClient, PhinIncomingResponseFirst party, Risk API, Activities

For Contributors

Installing Dependencies

To install dependencies, run:

npm install

Building

To build the module as a library, run:

npm run build

Testing

To run unit tests, run:

npm run test

To see unit test coverage, run:

npm run coverage