diff --git a/README.md b/README.md index d53060b..878eba2 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,14 @@ const service = new Satellite({ - `helmet`: the options to pass to the [helmet](https://www.npmjs.com/package/helmet) middleware. By default all options are turned on. Use `helmet: false` to disable helmet. +- `optOutFloc`: Enable adding the appropriate headers to Satellite to opt out of [Google's Floc](https://www.wired.com/story/google-floc-privacy-ad-tracking-explainer/). Disabled by default. + +```js +const service = new Satellite({ + options.optOutFloc: true, +}); +``` + - `beforeParsers`: an optional hook function that allows access to the `app` during creation prior to adding the body parsers ```js diff --git a/src/app.js b/src/app.js index c2eb872..1783208 100644 --- a/src/app.js +++ b/src/app.js @@ -34,6 +34,14 @@ function createApp(router, options = {}) { // Parse application/json app.use(express.json()); + // Allow adding auto-opt-out of FLoC (disabled by default) + if (options.optOutFloc) { + app.use((req, res, next) => { + res.setHeader('Permissions-Policy', 'interest-cohort=()'); + next(); + }); + } + // If beforeRouter is defined, add all middleware to the app // before we define the router. Useful for adding middleware just // before the router. diff --git a/test.js b/test.js index c8f7638..faceedb 100644 --- a/test.js +++ b/test.js @@ -117,6 +117,33 @@ describe('Satellite()', () => { }); }); + describe('auto-oup-out FLoC', () => { + test('Satellite() instance should include the { Permission-Policy: interest-cohort } header when the option is enabled', (done) => { + const service = createSatelliteInstance({ + name: 'test', + optOutFloc: true, + }); + service.start(port, async () => { + const res = await fetch(`${url}/always-200`); + expect(res.ok).toBe(true); + expect(res.headers.get('permissions-policy')).toBe('interest-cohort=()'); + service.stop(done); + }); + }); + + test('Satellite() instance should not include the { Permission-Policy: interest-cohort } header when the option is disabled', (done) => { + const service = createSatelliteInstance({ + name: 'test', + }); + service.start(port, async () => { + const res = await fetch(`${url}/always-200`); + expect(res.ok).toBe(true); + expect(res.headers.get('permissions-policy')).toBe(null); + service.stop(done); + }); + }); + }); + test('start() should throw if called twice', (done) => { service.start(port, () => { expect(() => service.start(port2, async () => {})).toThrow();