> This page is for Applications Protection.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.humansecurity.com/llms.txt.

# Installation

## Prerequisites

The HUMAN Fastly JavaScript Compute\@Edge enforcer requires access to:

* [Fastly Compute@Edge services](https://developer.fastly.com/learning/compute/)
* Node.js v16.x or higher

## Installation

0. Get started by [creating a Fastly C@E Service](https://developer.fastly.com/learning/compute#getting-started) and downloading the Fastly CLI (if you haven't already).
1. Use the HUMAN Fastly JavaScript Compute\@Edge [starter kit](https://github.com/PerimeterX/perimeterx-fastly-js-edge-template) or install the HUMAN Enforcer [NPM package](https://www.npmjs.com/package/perimeterx-fastly-js-edge) into your existing Fastly project.

```sh
# if you want to start a brand new project
fastly compute init --from=https://github.com/PerimeterX/perimeterx-fastly-js-edge-template --language=javascript

# if you have an existing project
npm i --save perimeterx-fastly-js-edge
```

2. Integrate the HUMAN Enforcer into your project.

For an out-of-the box request handler with the HUMAN Enforcer integrated into it already, simply import and use the `createEnforcedRequestHandler` function.

```javascript
import { createEnforcedRequestHandler } from "perimeterx-fastly-js-edge";

// define HUMAN configuration
const config = {
    px_app_id: '<APP_ID>',
    px_cookie_secret: '<COOKIE_SECRET>',
    px_auth_token: '<AUTH_TOKEN>',
};

// define what to do when requests pass HUMAN enforcement
const onPass = (event) => {
    console.log('handling HUMAN-validated request')
    return fetch(event.request, { backend: '<ORIGIN_NAME>' })
};

// define what to do for block responses (optional)
const onResponse = (response) => {
    console.log('handling response from HUMAN enforcer');
    return response;
};

// create request handler
const handleRequest = createEnforcedRequestHandler(config, onPass, onResponse);

// invoke handleRequest on incoming fetch event
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));
```

The example below shows what the `createEnforcedRequestHandler()` function does behind the scenes. For a more customized solution, create a new `HumanSecurityEnforcer` instance and use it in your request handler as desired.

The recommended usage is to:

* initialize the `HumanSecurityEnforcer`, call the `enforce()` function, and return any resulting response as early as possible in the request flow to minimize invocation of unnecessary logic.
* call the `postEnforce()` right before returning the response from the request handler to ensure any necessary response modifications are performed and HUMAN data is sent to the collector.

```javascript
import { HumanSecurityEnforcer } from 'perimeterx-fastly-js-edge';

// define HUMAN configuration
const config = {
    px_app_id: '<APP_ID>',
    px_cookie_secret: '<COOKIE_SECRET>',
    px_auth_token: '<AUTH_TOKEN>',
};

async function handleRequest(event) {
    // create enforcer with configuration params
    const enforcer = await HumanSecurityEnforcer.initialize(config);

    // await enforcement
    let response = await enforcer.enforce(event);

    // return enforcer response (first party or block) if it exists
    if (response) {

        // if any block response modifications are needed, perform them here
        return response;
    }

    // perform logic to fetch desired response, for example:
    response = await fetch(event.request, { backend: '<ORIGIN_NAME>' });

    // await any necessary post-processing
    await enforcer.postEnforce(response);

    // return response
    return response;
}

// invoke handleRequest on incoming fetch event
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));
```

3. Add or modify the required HUMAN backends in your `fastly.toml` file ([see here for more info](https://developer.fastly.com/reference/compute/fastly-toml/)) and/or directly to your Fastly service, replacing the application ID placeholder with your application ID.

```toml
[setup.backends.human_sapi]
  address = "sapi-PX12345678.perimeterx.net"
  description = "The Human Score API backend"

[setup.backends.human_collector]
  address = "collector-PX12345678.perimeterx.net"
  description = "The Human Collector backend"

[setup.backends.human_client]
  address = "client.perimeterx.net"
  description = "The Human backend that serves the client sensor"

[setup.backends.human_captcha]
  address = "captcha.px-cdn.net"
  description = "The Human backend that serves the captcha script"
```

> **Backend Names**
>
> The default names of these backends are `human_sapi`, `human_collector`, `human_client`, and `human_captcha`. If the default `human_*` backend names are changed, the new backend names must be explicitly indicated in the Enforcer configuration using the `px_backend_score_name`, `px_backend_collector_name`, `px_backend_client_name`, and `px_backend_captcha_name` configurations, respectively.

4. Build, test, and deploy the worker using the Fastly CLI.

```sh
# builds and packages the worker
fastly compute build

# test the worker locally
fastly compute serve

# deploy the worker to Fastly
fastly compute deploy

# update an existing service
fastly compute update -p ./path/to/packaged_worker.tar.gz --version=latest --autoclone
```

## Helpful Links

* [Fastly JavaScript on Compute@Edge Basics](https://developer.fastly.com/learning/compute/javascript/)
* [Fastly Compute@Edge JavaScript SDK](https://js-compute-reference-docs.edgecompute.app/)
* [Fastly Compute@Edge CLI Commands](https://developer.fastly.com/reference/cli/compute/)