Skip to content

Commit

Permalink
feat: optionally require JWT token to access api, logs requests
Browse files Browse the repository at this point in the history
  • Loading branch information
VolcanoCookies authored and birme committed Sep 29, 2023
1 parent ce3b154 commit 929eaa7
Show file tree
Hide file tree
Showing 8 changed files with 303 additions and 4 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ To try it out, go to your favourite HLS/MPEG-DASH video player such as `https://
| `statusCode` | Replace the response for a specific segment request with a specified status code response |
| `timeout` | Force a timeout for the response of a specific segment request |
| `throttle` | Send back the segment at a specified speed of bytes per second |
| `token` | JWT for authentication if `JWT_SECRET` env is set |

### Environmental Variales

| VARIABLE | TYPE | DESCRIPTION |
| -------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET` | string | Enables jwt authentication for all endpoints and logs requests from users, provide token with the `token` query parameter. |
| `LOAD_PARAMS_FROM_AWS_SSM` | boolean | Load manifest url params from AWS SSM, [see below](#load-manifest-url-params-from-aws-ssm-parameter-store-instead) |
| `AWS_REGION` | string | AWS region for SSM parameters, no effect if `LOAD_PARAMS_FROM_AWS_SSM` is false |
| `AWS_SSM_PARAM_KEY` | string | Key for AWS SSM params, no effect if `LOAD_PARAMS_FROM_AWS_SSM` is false |

### Stateful Mode

Expand Down
134 changes: 134 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"typecheck": "tsc --noEmit -p tsconfig.json",
"pretty": "prettier --check --ignore-unknown .",
"deploy:dev": "git tag $(git rev-parse --short HEAD)-dev && git push --tags",
"postversion": "git push && git push --tags"
"postversion": "git push && git push --tags",
"genJwt": "node dist/genJwt.js"
},
"dependencies": {
"@aws-sdk/client-ssm": "^3.306.0",
Expand All @@ -25,6 +26,7 @@
"fastify": "^3.29.5",
"fastify-cors": "^6.0.2",
"jest": "^27.5.1",
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.15",
"nock": "^13.2.4",
"node-cache": "^5.1.2",
Expand All @@ -40,6 +42,7 @@
"@types/aws-lambda": "^8.10.92",
"@types/clone": "^2.1.1",
"@types/jest": "^27.4.0",
"@types/jsonwebtoken": "^9.0.2",
"@types/node": "^17.0.18",
"@types/node-fetch": "^2.5.7",
"@types/stream-throttle": "^0.1.1",
Expand Down
10 changes: 10 additions & 0 deletions src/genJwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import jwt from 'jsonwebtoken';

if (process.argv.length < 5)
console.error('Expected 3 arguments; <secret> <email> <company>');
else {
const secret = process.argv[2];
const email = process.argv[3];
const company = process.argv[4];
console.log(jwt.sign({ company, email }, secret));
}
4 changes: 3 additions & 1 deletion src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import segmentRoutes from './segments/routes';
import manifestRoutes from './manifests/routes';
import {
generateHeartbeatResponse,
addCustomVersionHeader
addCustomVersionHeader,
authenticateToken
} from './shared/utils';
import throttlingProxyRoutes from './segments/routes/throttlingProxy';

Expand All @@ -23,4 +24,5 @@ export function registerRoutes(app: FastifyInstance) {
app.register(manifestRoutes, opts);
app.register(throttlingProxyRoutes, opts);
addCustomVersionHeader(app);
authenticateToken(app);
}
28 changes: 28 additions & 0 deletions src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import {
} from './segments/constants';

describe('Chaos Stream Proxy server', () => {
const env = process.env;
let app = null;
beforeEach(() => {
jest.resetModules();
process.env = { ...env };
app = fastify();
registerRoutes(app);
});

afterEach(() => {
process.env = env;
});

it.each([HLS_PROXY_MASTER, HLS_PROXY_MEDIA, SEGMENTS_PROXY_SEGMENT])(
'route %p contains x-version header',
async (route) => {
Expand All @@ -24,4 +31,25 @@ describe('Chaos Stream Proxy server', () => {
);
}
);

it('requires token when running with env JWT_SECRET set', async () => {
process.env.JWT_SECRET = 'somesecret';
const appInternal = fastify();
registerRoutes(appInternal);
const invalidResponse = await appInternal.inject('/?token=invalid');
expect(invalidResponse.statusCode).toEqual(401);

const validResponse = await appInternal.inject(
'/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wYW55IjoidGVzdGNvbXBhbnkiLCJlbWFpbCI6InRlc3RAZW1haWwuY29tIiwiaWF0IjoxNjg2MTUzMzU5fQ.wHnzxMdoPZlzdU0GDCzEwd5lnEmq-rX2Ew0yODxqlzg'
);
expect(validResponse.statusCode).toEqual(200);
});

it('ignores token when running without env JWT_SECRET set', async () => {
process.env.JWT_SECRET = undefined;
const appInternal = fastify();
registerRoutes(appInternal);
const response = await appInternal.inject('/?token=invalid');
expect(response.statusCode).toEqual(200);
});
});
Loading

0 comments on commit 929eaa7

Please sign in to comment.