# @jackdbd/eleventy-plugin-permissions-policy

[![npm version](https://badge.fury.io/js/@jackdbd%2Feleventy-plugin-permissions-policy.svg)](https://badge.fury.io/js/@jackdbd%2Feleventy-plugin-permissions-policy)
[![install size](https://packagephobia.com/badge?p=@jackdbd/eleventy-plugin-permissions-policy)](https://packagephobia.com/result?p=@jackdbd/eleventy-plugin-permissions-policy)
[![CodeCov badge](https://codecov.io/gh/jackdbd/undici/graph/badge.svg?token=BpFF8tmBYS)](https://app.codecov.io/gh/jackdbd/undici?flags%5B0%5D=eleventy-plugin-permissions-policy)
[![Socket Badge](https://socket.dev/api/badge/npm/package/@jackdbd/eleventy-plugin-permissions-policy)](https://socket.dev/npm/package/@jackdbd/eleventy-plugin-permissions-policy)

Eleventy plugin that writes Permissions-Policy and Feature-Policy headers to a `_headers` file when Eleventy builds your site.

- [Installation](#installation)
- [About](#about)
- [Docs](#docs)
- [Usage](#usage)
- [Configuration](#configuration)
  - [Plugin options](#plugin-options)
  - [Permissions-Policy directive](#permissions-policy-directive)
- [Troubleshooting](#troubleshooting)
- [Dependencies](#dependencies)
- [License](#license)

## Installation

```sh
npm install @jackdbd/eleventy-plugin-permissions-policy
```

> :warning: **Peer Dependencies**
>
> This package defines 2 peer dependencies.

| Peer | Version range |
|---|---|
| `@11ty/eleventy` | `>=2.0.0 or 3.0.0-alpha.4` |
| `debug` | `>=4.0.0` |

## About

Hosting providers like [Cloudflare Pages](https://developers.cloudflare.com/pages/configuration/headers/) and [Netlify](https://docs.netlify.com/routing/headers/) allow to define custom response headers in a plain text file called `_headers`. This file must be placed in the publish directory of your site (e.g. usually `_site` for a Eleventy site).

This plugin allows you to define a [Permissions-Policy](https://w3c.github.io/webappsec-permissions-policy/) or a [Feature-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy) header in your Eleventy configuration file, and then it automatically writes those headers into your `_headers` file when you build your site.

## Docs

[Docs generated by TypeDoc](https://jackdbd.github.io/undici/eleventy-plugin-permissions-policy/)

> :open_book: **API Docs**
>
> This project uses [API Extractor](https://api-extractor.com/) and [api-documenter markdown](https://api-extractor.com/pages/commands/api-documenter_markdown/) to generate a bunch of markdown files and a `.d.ts` rollup file containing all type definitions consolidated into a single file. I don't find this `.d.ts` rollup file particularly useful. On the other hand, the markdown files that api-documenter generates are quite handy when reviewing the public API of this project.
>
> *See [Generating API docs](https://api-extractor.com/pages/setup/generating_docs/) if you want to know more*.

## Usage

In your Eleventy config file:

```js
import { permissionsPolicyPlugin } from '@jackdbd/eleventy-plugin-permissions-policy'

export default function (eleventyConfig) {
  // some eleventy configuration...

  eleventyConfig.addPlugin(permissionsPolicyPlugin, {
    directives: [
      { feature: 'autoplay', allowlist: ['*'] },
      { feature: 'geolocation', allowlist: ['self'] },
      { feature: 'camera', allowlist: ['self', 'https://trusted-site.example'] },
      { feature: 'fullscreen', allowlist: [] }
    ],
    includeFeaturePolicy: true
  })

  // some more eleventy configuration...
}
```

## Configuration

Read these resources to understand how to configure the `Permissions-Policy` and the `Feature-Policy` HTTP response headers.

- [A new security header: Feature Policy](https://scotthelme.co.uk/a-new-security-header-feature-policy/)
- [Goodbye Feature Policy and hello Permissions Policy!](https://scotthelme.co.uk/goodbye-feature-policy-and-hello-permissions-policy/)
- [Permissions Policy Explainer](https://github.com/w3c/webappsec-permissions-policy/blob/main/permissions-policy-explainer.md)
- [Policy Controlled Features](https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md)
- [Controlling browser features with Permissions Policy](https://developer.chrome.com/en/docs/privacy-sandbox/permissions-policy/)

### Plugin options

| Key | Default | Description |
|---|---|---|
| `directives` | `[]` | Permissions-Policy [directives](https://w3c.github.io/webappsec-permissions-policy/#policy-directives). |
| `excludePatterns` | `[]` | Files that match these patterns will **not** be served with the Permissions-Policy header (nor with the Feature-Policy header, if generated). |
| `includeFeaturePolicy` | `true` | Whether to generate also a Feature-Policy header. |
| `includePatterns` | `[
  "/",
  "/*/"
]` | Files that match these patterns will be served with the Permissions-Policy header (and also with the Feature-Policy header, if generated). |
| `jsonRecap` | `false` |  |

### Permissions-Policy directive

| Key | Default | Description |
|---|---|---|
| `allowlist` | `undefined` | A set of origins and/or special values (`*`, `none`, `self`, `src`). |
| `feature` | `undefined` | A policy-controlled feature is an API or behaviour which can be enabled or disabled in a document by referring to it in a permissions policy. |

## Troubleshooting

This plugin uses the [debug](https://github.com/debug-js/debug) library for logging.
You can control what's logged using the `DEBUG` environment variable.

For example, if you set your environment variables in a `.envrc` file, you can do:

```sh
# print all logging statements
export DEBUG=11ty-plugin:*
```

## Dependencies

| Package | Version |
|---|---|
| [zod](https://www.npmjs.com/package/zod) | `^3.22.4` |
| [zod-validation-error](https://www.npmjs.com/package/zod-validation-error) | `^3.0.0` |

## License

&copy; 2022 - 2024 [Giacomo Debidda](https://www.giacomodebidda.com/) // [MIT License](https://spdx.org/licenses/MIT.html)
