Skip to content

Commit

Permalink
[Proxy] cookies forwarding (#232)
Browse files Browse the repository at this point in the history
* feat(proxy): ⚡ Adds an option to opt out from token fowrarding (per service)

* unit test coverage

* feat(proxy): ✨ List cookies you want to proxy in the `allowedCookies` option

* docs(proxy): ✏️ Fix typo
  • Loading branch information
bcldvd authored May 19, 2022
1 parent ebbe4f7 commit 90a7157
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 23 deletions.
6 changes: 3 additions & 3 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"recommendations": [
"alanwalk.markdown-toc",
"vivaxy.vscode-conventional-commits",
"orta.vscode-jest",
"cssho.vscode-svgviewer",
"gruntfuggly.todo-tree"
"gruntfuggly.todo-tree",
"huntertran.auto-markdown-toc"
]
}
}
48 changes: 29 additions & 19 deletions libs/proxy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,40 @@

**Table of Contents**

<!-- TOC depthFrom:2 depthTo:3 -->
<!-- TOC depthfrom:2 depthto:3 -->

- [0.5.3 (2021-10-20)](#053-2021-10-20)
- [2022-05-18](#2022-05-18)
- [Features](#features)
- [2021-11-4](#2021-11-4)
- [Features](#features)
- [2021-10-20](#2021-10-20)
- [Bugfixes](#bugfixes)
- [2021-10-20](#2021-10-20)
- [Bugfixes](#bugfixes)
- [2021-10-19](#2021-10-19)
- [Bugfixes](#bugfixes)
- [2021-09-27](#2021-09-27)
- [Features](#features)
- [2020-09-16](#2020-09-16)
- [Features](#features)
- [2020-07-23](#2020-07-23)
- [Bugfixes](#bugfixes)
- [0.5.2 (2021-10-20)](#052-2021-10-20)
- [Bugfixes](#bugfixes-1)
- [0.5.1 (2021-10-19)](#051-2021-10-19)
- [Bugfixes](#bugfixes-2)
- [0.5.0 (2021-09-27)](#050-2021-09-27)
- [2020-07-23](#2020-07-23)
- [Features](#features)
- [0.4.0 (2020-09-16)](#040-2020-09-16)
- [Features](#features-1)
- [0.3.1 (2020-07-23)](#031-2020-07-23)
- [Bugfixes](#bugfixes-3)
- [0.3.0 (2020-07-23)](#030-2020-07-23)
- [Features](#features-2)
- [0.2.1 (2020-06-25)](#021-2020-06-25)
- [2020-06-25](#2020-06-25)
- [Bug fixes](#bug-fixes)
- [2020-05-19](#2020-05-19)
- [Features](#features)
- [2020-04-30](#2020-04-30)
- [Bug fixes](#bug-fixes)
- [0.2.0 (2020-05-19)](#020-2020-05-19)
- [Features](#features-3)
- [0.1.1 (2020-04-30)](#011-2020-04-30)
- [Bug fixes](#bug-fixes-1)

<!-- /TOC -->

## 0.7.0 (2022-05-18)

### Features

- Adds an option to opt out from token fowrarding (per service).
- Adds an option to opt out from token forwarding (per service).

```typescript
services: [
Expand All @@ -43,6 +47,12 @@ services: [
];
```

- Cookies are not proxied anymore by default. You can opt in by listing the cookie names in the `allowedCookies` option.

```typescript
allowedCookies: ['cookie1', 'cookie2'],
```

## 0.6.0 (2021-11-4)

### Features
Expand Down
9 changes: 9 additions & 0 deletions libs/proxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ services: [

> &#x26A0; Be careful to only forward tokens to internal services. Don't forward the token to third party services.
### Cookies forwarding

Cookies are not proxied by default. You can opt in by listing the cookie names in the `allowedCookies` option:

```typescript
allowedCookies: ['cookie1', 'cookie2'],
```


### Default module configuration

If you do not provide any, the default proxy configuration for this module can be found in [proxy.constants.ts](./src/proxy.constants.ts), under `defaultProxyOptions`
Expand Down
1 change: 1 addition & 0 deletions libs/proxy/src/interfaces/proxy.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Service {
export interface ProxyModuleOptions {
config?: server.ServerOptions;
services?: Service[];
allowedCookies?: string[];
}

export interface ProxyModuleOptionsFactory {
Expand Down
55 changes: 55 additions & 0 deletions libs/proxy/src/proxy.module.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import * as server from 'http-proxy';
import { createRequest } from 'node-mocks-http';
import { ProxyModuleOptions } from './interfaces';
import { HTTP_PROXY } from './proxy.constants';
import { ProxyModule } from './proxy.module';

Expand All @@ -26,6 +27,7 @@ describe('ProxyModule', () => {
const proxyReq = createRequest();
const req = createRequest();
proxyReq.getHeader = header => header;
proxyReq.setHeader = jest.fn();
proxyReq.write = jest.fn();
proxyReq.protocol = 'http:';
proxyReq.host = 'localhost';
Expand All @@ -40,6 +42,7 @@ describe('ProxyModule', () => {
const body = { prop: 'test' };
req.body = body;
proxyReq.getHeader = header => header;
proxyReq.setHeader = jest.fn();
proxyReq.write = jest.fn();
proxyReq.protocol = 'http:';
proxyReq.host = 'localhost';
Expand All @@ -51,6 +54,7 @@ describe('ProxyModule', () => {
it('should stringify body if content type is json', () => {
const proxyReq = createRequest();
proxyReq.getHeader = header => 'application/json';
proxyReq.setHeader = jest.fn();
proxyReq.write = jest.fn();
proxyReq.setHeader = jest.fn();
proxyReq.protocol = 'http:';
Expand Down Expand Up @@ -81,6 +85,20 @@ describe('ProxyModule', () => {
proxy.emit('proxyReq', proxyReq, req);
expect(spy).toHaveBeenCalledWith('prop=test');
});

it('should strip all cookies since no allowedCookies defined', () => {
const proxyReq = createRequest();
const req = createRequest();
proxyReq._headers = { cookie: 'ga=test' };
proxyReq.getHeader = header => proxyReq._headers[header];
proxyReq.setHeader = (header, value) => (proxyReq._headers[header] = value);
proxyReq.write = jest.fn();
proxyReq.protocol = 'http:';
proxyReq.host = 'localhost';

proxy.emit('proxyReq', proxyReq, req);
expect(proxyReq.getHeader('cookie')).toBe('');
});
});
});
});
Expand Down Expand Up @@ -126,4 +144,41 @@ describe('ProxyModule', () => {
expect(module).toBeDefined();
});
});

describe('register sync', () => {
let module: TestingModule;
let proxy;
const mockProxyModuleOptions: ProxyModuleOptions = {
allowedCookies: ['_ga'],
};

beforeEach(async () => {
module = await Test.createTestingModule({
imports: [ProxyModule.forRoot(mockProxyModuleOptions)],
}).compile();
proxy = module.get<server>(HTTP_PROXY);
});

it('should be defined', () => {
expect(module).toBeDefined();
});

describe('proxyFactory', () => {
describe('on ProxyReq', () => {
it('should strip all cookies since no allowedCookies defined', () => {
const proxyReq = createRequest();
const req = createRequest();
proxyReq._headers = { cookie: '_ga=test; privateCookie=secret;' };
proxyReq.getHeader = header => proxyReq._headers[header];
proxyReq.setHeader = (header, value) => (proxyReq._headers[header] = value);
proxyReq.write = jest.fn();
proxyReq.protocol = 'http:';
proxyReq.host = 'localhost';

proxy.emit('proxyReq', proxyReq, req);
expect(proxyReq.getHeader('cookie')).toBe('_ga=test');
});
});
});
});
});
11 changes: 10 additions & 1 deletion libs/proxy/src/proxy.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@ const proxyFactory = {
...options.config,
});

proxy.on('proxyReq', function (proxyReq, req, res, options) {
proxy.on('proxyReq', function (proxyReq, req, res, opts) {
const url = concatPath(`${proxyReq.protocol}//${proxyReq.host}`, req.url);
logger.log(`Sending ${req.method} ${url}`);

let cookies = (proxyReq.getHeader('cookie') || '') as string;
const allowedCookies = options.allowedCookies || [];
cookies = cookies
.split(';')
.filter(cookie => allowedCookies.indexOf(cookie.split('=')[0].trim()) !== -1)
.join(';');

proxyReq.setHeader('cookie', cookies);

if (!req['body'] || !Object.keys(req['body']).length) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/configs/proxy-config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class ProxyConfigService implements ProxyModuleOptionsFactory {

return {
services,
allowedCookies: ['_ga'],
};
}
}

0 comments on commit 90a7157

Please # to comment.