From 5deb43bfc8730a2e9b0f31426093b85d0e7f7b50 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 11 Apr 2024 18:46:04 +0700 Subject: [PATCH] fix(auth): Handle when authorization header is lowercased (#10442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In one of the PRs I did for last release, I switched getting the header using the new `getEventHeaders` function. This function will check for two cases: ``` getEventHeaders('Authorization') => a) header['authorization'] b) header['Authorization'] ``` **BUT** if you passed it a lowercase header in the first place: ``` getEventHeaders('authorization') => a) header['authorization'] b) header['authorization'] ``` I actually didn't change the logic it's the same as before, but in`parseAuthorizationHeader`, we used to call it with the capital case. I know the _full_ solution is to grab the headers, and convert them all to lower-case, but I'm intentionally avoiding this because I don't want to slow down handling of every request by looping over all the headers. --- This PR makes a minor change, and adds some extra tests. 🤞 we'll move everything to Fetch API soon and won't have to deal with this sillyness! --- .changesets/10442.md | 2 + .../parseAuthorizationHeader.test.ts | 70 +++++++++++++++++++ packages/api/src/auth/index.ts | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 .changesets/10442.md create mode 100644 packages/api/src/auth/__tests__/parseAuthorizationHeader.test.ts diff --git a/.changesets/10442.md b/.changesets/10442.md new file mode 100644 index 000000000000..ed6297fbc3a7 --- /dev/null +++ b/.changesets/10442.md @@ -0,0 +1,2 @@ +- fix(auth): Handle when authorization header is lowercased (#10442) by @dac09 +Handles when 'authorization' header is lowercased, and adds some extra tests. diff --git a/packages/api/src/auth/__tests__/parseAuthorizationHeader.test.ts b/packages/api/src/auth/__tests__/parseAuthorizationHeader.test.ts new file mode 100644 index 000000000000..19fcbcf4783f --- /dev/null +++ b/packages/api/src/auth/__tests__/parseAuthorizationHeader.test.ts @@ -0,0 +1,70 @@ +import type { APIGatewayProxyEvent } from 'aws-lambda' +import { test, expect, describe } from 'vitest' + +import { parseAuthorizationHeader } from '../index' + +describe('parseAuthorizationHeader', () => { + test('throws error if Authorization header is not valid', () => { + const invalidHeaders = [ + undefined, + null, + '', + 'Bearer', + 'Bearer ', + 'Bearer token with spaces', + 'Token', + 'Token ', + 'Token token with spaces', + ] + + invalidHeaders.forEach((header) => { + expect(() => + // @ts-expect-error That's what we're testing + parseAuthorizationHeader({ headers: { Authorization: header } }), + ).toThrowError('The `Authorization` header is not valid.') + }) + }) + + test('returns the schema and token from valid Authorization header', () => { + const validHeaders = [ + 'Bearer token', + 'Bearer 12345', + 'Token token', + 'Token 12345', + ] + + validHeaders.forEach((header) => { + // We only care about the headers in the event + const result = parseAuthorizationHeader({ + headers: { Authorization: header }, + } as unknown as APIGatewayProxyEvent) + + expect(result).toEqual({ + schema: header.split(' ')[0], + token: header.split(' ')[1], + }) + }) + }) + + test('Handles different lower-casing of the authorization header', () => { + const result = parseAuthorizationHeader({ + headers: { authorization: 'Bearer bazinga' }, + } as unknown as APIGatewayProxyEvent) + + expect(result).toEqual({ + schema: 'Bearer', + token: 'bazinga', + }) + }) + + test('Handles different capital-casing of the Authorization header', () => { + const result = parseAuthorizationHeader({ + headers: { Authorization: 'Bearer bazinga' }, + } as unknown as APIGatewayProxyEvent) + + expect(result).toEqual({ + schema: 'Bearer', + token: 'bazinga', + }) + }) +}) diff --git a/packages/api/src/auth/index.ts b/packages/api/src/auth/index.ts index 77fd6e7789f4..e76ec11b50af 100644 --- a/packages/api/src/auth/index.ts +++ b/packages/api/src/auth/index.ts @@ -33,7 +33,7 @@ export interface AuthorizationHeader { export const parseAuthorizationHeader = ( event: APIGatewayProxyEvent | Request ): AuthorizationHeader => { - const parts = getEventHeader(event, 'authorization')?.split(' ') + const parts = getEventHeader(event, 'Authorization')?.split(' ') if (parts?.length !== 2) { throw new Error('The `Authorization` header is not valid.') }