diff --git a/src/index.spec.ts b/src/index.spec.ts index e161364..00a776d 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -4,6 +4,7 @@ import { EncryptionAlgorithms } from './interfaces/IAuthOptions' import JWT from 'jsonwebtoken' import createHttpError from 'http-errors' +import { IAuthorizedEvent } from './interfaces/IAuthorizedEvent' describe('JWTAuthMiddleware', () => { beforeAll(() => { @@ -54,6 +55,68 @@ describe('JWTAuthMiddleware', () => { ).toEqual(undefined) }) + it('saves token information to event.auth if token is valid', async () => { + const next = jest.fn() + const options = { + algorithm: EncryptionAlgorithms.HS256, + secretOrPublicKey: 'secret' + } + const data = { userId: 1 } + const token = JWT.sign(data, options.secretOrPublicKey, { + algorithm: options.algorithm + }) + const event: IAuthorizedEvent = { + headers: { + Authorization: `Bearer ${token}` + }, + httpMethod: 'GET' + } + await JWTAuthMiddleware(options).before( + { + event, + context: {} as any, + response: null, + error: {} as Error, + callback: jest.fn() + }, + next + ) + expect(event.auth).toEqual({ ...data, iat: expect.any(Number) }) + }) + + it('rejects if event.auth is already filled', async () => { + const next = jest.fn() + const options = { + algorithm: EncryptionAlgorithms.HS256, + secretOrPublicKey: 'secret' + } + const data = { userId: 1 } + const token = JWT.sign(data, options.secretOrPublicKey, { + algorithm: options.algorithm + }) + const event: IAuthorizedEvent = { + auth: {}, + headers: { + Authorization: `Bearer ${token}` + }, + httpMethod: 'GET' + } + await expect( + JWTAuthMiddleware(options).before( + { + event, + context: {} as any, + response: null, + error: {} as Error, + callback: jest.fn() + }, + next + ) + ).rejects.toEqual( + createHttpError(400, 'The events auth property has to be empty') + ) + }) + it('rejects if Authorization header is malformed', async () => { const next = jest.fn() const options = { @@ -134,9 +197,7 @@ describe('JWTAuthMiddleware', () => { }, next ) - ).rejects.toEqual( - createHttpError(401, 'Invalid token') - ) + ).rejects.toEqual(createHttpError(401, 'Invalid token')) }) }) }) diff --git a/src/index.ts b/src/index.ts index acf7442..2ad6d5f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,7 +4,11 @@ import { IAuthorizedEvent, isAuthorizedEvent } from './interfaces/IAuthorizedEvent' -import { IAuthOptions, isAuthOptions } from './interfaces/IAuthOptions' +import { + EncryptionAlgorithms, + IAuthOptions, + isAuthOptions +} from './interfaces/IAuthOptions' import createHttpError from 'http-errors' import jwt from 'jsonwebtoken' // import createHttpError from 'http-errors' @@ -30,6 +34,9 @@ export class JWTAuthMiddleware { public before: MiddlewareFunction = async ({ event }: HandlerLambda) => { + if (event && event.auth !== undefined) { + throw createHttpError(400, 'The events auth property has to be empty') + } this.logger('Checking whether event contains authorization data') if (!isAuthorizedEvent(event)) { this.logger('No authorization data found') @@ -44,10 +51,9 @@ export class JWTAuthMiddleware { const token = parts[1] try { - jwt.verify(token, this.options.secretOrPublicKey, { + event.auth = jwt.verify(token, this.options.secretOrPublicKey, { algorithms: [this.options.algorithm] }) - // context.identity } catch (err) { throw createHttpError(401, 'Invalid token') } @@ -55,3 +61,8 @@ export class JWTAuthMiddleware { } export default JWTAuthMiddleware.create +export { EncryptionAlgorithms, IAuthOptions, isAuthOptions } +export { + IAuthorizedEvent, + isAuthorizedEvent +} from './interfaces/IAuthorizedEvent' diff --git a/src/interfaces/IAuthorizedEvent.spec.ts b/src/interfaces/IAuthorizedEvent.spec.ts index 0456d6b..ea841c8 100644 --- a/src/interfaces/IAuthorizedEvent.spec.ts +++ b/src/interfaces/IAuthorizedEvent.spec.ts @@ -4,6 +4,7 @@ describe('IAuthorizedEvent', () => { describe('interface', () => { it('accepts data that has an httpMethod and an Authorization header', () => { const event: IAuthorizedEvent = { + auth: {}, headers: { Authorization: 'Bearer TOKEN' }, diff --git a/src/interfaces/IAuthorizedEvent.ts b/src/interfaces/IAuthorizedEvent.ts index c50c514..08ae5ca 100644 --- a/src/interfaces/IAuthorizedEvent.ts +++ b/src/interfaces/IAuthorizedEvent.ts @@ -1,5 +1,7 @@ /** An event that can be checked for authorization with middly-middleware-jwt-auth */ export interface IAuthorizedEvent { + /** Authorization information added by this middleware from a JWT. Has to be undefined before hitting the middleware. */ + auth?: any headers: { /** * The authorization token to check