From ef90e02737148474ba39cfc34160165b2faf6ad7 Mon Sep 17 00:00:00 2001 From: VolcanoCookies Date: Wed, 28 Jun 2023 17:58:31 +0200 Subject: [PATCH] fix: always allow heartbeat path --- README.md | 12 ++++++------ src/server.test.ts | 20 +++++++++++++++----- src/shared/utils.ts | 33 ++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index fc6a27d..5f8d8cc 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,12 @@ To try it out, go to your favourite HLS/MPEG-DASH video player such as `https:// ### 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 | +| VARIABLE | TYPE | DESCRIPTION | +| -------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `JWT_SECRET` | string | Enables jwt authentication for all endpoints and logs requests from users, provide token with the `token` query parameter. Heartbeat path unaffected. | +| `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 diff --git a/src/server.test.ts b/src/server.test.ts index 98af681..2475fb7 100644 --- a/src/server.test.ts +++ b/src/server.test.ts @@ -32,17 +32,27 @@ describe('Chaos Stream Proxy server', () => { } ); - it('requires token when running with env JWT_SECRET set', async () => { + it('requires token when running with env JWT_SECRET set, except for heartbeat path', async () => { + // Arrange process.env.JWT_SECRET = 'somesecret'; const appInternal = fastify(); registerRoutes(appInternal); - const invalidResponse = await appInternal.inject('/?token=invalid'); - expect(invalidResponse.statusCode).toEqual(401); + + // Act + const invalidResponse = await appInternal.inject( + '/api/v2/manifests/dash/proxy-master.mpd?token=invalid' + ); const validResponse = await appInternal.inject( - '/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wYW55IjoidGVzdGNvbXBhbnkiLCJlbWFpbCI6InRlc3RAZW1haWwuY29tIiwiaWF0IjoxNjg2MTUzMzU5fQ.wHnzxMdoPZlzdU0GDCzEwd5lnEmq-rX2Ew0yODxqlzg' + '/api/v2/manifests/dash/proxy-master.mpd?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wYW55IjoidGVzdGNvbXBhbnkiLCJlbWFpbCI6InRlc3RAZW1haWwuY29tIiwiaWF0IjoxNjg2MTUzMzU5fQ.wHnzxMdoPZlzdU0GDCzEwd5lnEmq-rX2Ew0yODxqlzg' ); - expect(validResponse.statusCode).toEqual(200); + + const allowHeartbeatAlways = await appInternal.inject('/'); + + // Assert + expect(invalidResponse.statusCode).toEqual(401); + expect(validResponse.statusCode).toEqual(400); + expect(allowHeartbeatAlways.statusCode).toEqual(200); }); it('ignores token when running without env JWT_SECRET set', async () => { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index f93876a..3bc7d94 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -358,21 +358,24 @@ export function authenticateToken(app: FastifyInstance): void { app.addHook( 'onRequest', async (request, reply): Promise => { - const token = request.query['token']; - if (token == undefined) - return reply.code(401).send({ error: 'No token provided' }); - try { - const censoredUrl = request.url.replace(token, 'TOKEN'); - const decoded = jwt.verify(token, secret) as JwtToken; - awsLogger.info( - { path: censoredUrl }, - request['awsLambda']?.['context'] as Context, - decoded - ); - } catch (err) { - return reply - .code(401) - .send({ error: 'Invalid authentication token' }); + const path = request.raw.url.split('?')[0]; + if (path != '/') { + const token = request.query['token']; + if (token == undefined) + return reply.code(401).send({ error: 'No token provided' }); + try { + const censoredUrl = request.url.replace(token, 'TOKEN'); + const decoded = jwt.verify(token, secret) as JwtToken; + awsLogger.info( + { path: censoredUrl }, + request['awsLambda']?.['context'] as Context, + decoded + ); + } catch (err) { + return reply + .code(401) + .send({ error: 'Invalid authentication token' }); + } } } );