import { expect } from 'chai'; import * as jwk from 'json-web-key'; import { log } from '../../src/system'; import { Request, Response } from '../../src/http'; import { Roles, JWT, JWK } from '../../src/middleware'; import { getMockAPIEvent } from '../support/mockapievent'; import { Unauthorized, InternalError } from '../../src/http/errors'; import { generateJWT, generateCerts, generateSignedJWT } from '../support/jwt'; describe('The Roles middleware', () => { let event = getMockAPIEvent(); let request = new Request(event); let response = new Response(); it('should allow passing evaluators', async () => { let evaluator = async () => { return Promise.resolve(true); } let rolesMiddleware = new Roles([evaluator]); await rolesMiddleware.processRequest(request, response); }); it('should not allow non-passing roles', async () => { let evaluator = async () => { return Promise.resolve(true); } let failEvaluator = async () => { return Promise.resolve(false); } let rolesMiddleware = new Roles([evaluator, failEvaluator]); try { await rolesMiddleware.processRequest(request, response); throw new Error('Expected exception was not raised.'); } catch (err) { expect(err).to.be.instanceof(Unauthorized); } }); }); describe('The JWT middleware', () => { let secret = 'p@ssw0rd' let response = new Response(); let jwtMiddleware = new JWT(secret); it('should accept a valid password-based JWT', async () => { let token = generateJWT(secret); let event = getMockAPIEvent(); event.headers['Authorization'] = `Bearer ${token}`; let request = new Request(event); await jwtMiddleware.processRequest(request, response); }); it('should deny an invalid password-based JWT', async () => { let token = generateJWT(secret + 'foo'); let event = getMockAPIEvent(); event.headers['Authorization'] = `Bearer ${token}`; let request = new Request(event); try { await jwtMiddleware.processRequest(request, response); throw new Error('Expected exception was not raised.'); } catch (err) { expect(err).to.be.instanceof(Unauthorized); } }); describe('with a variety of bad Authorization headers', () => { let headerValues = [ 'Bearer foobar', 'Bearer', '123 foobar' ]; for (let header of headerValues) { let event = getMockAPIEvent(); event.headers['Authorization'] = header; let request = new Request(event); it(`should deny a header of ${header}`, async () => { try { await jwtMiddleware.processRequest(request, response); throw new Error('Expected exception was not raised.'); } catch (err) { expect(err).to.be.instanceof(Unauthorized); } }); } }); }); describe('The JWK middleware', () => { let event = getMockAPIEvent(); it('should throw an error if no keys are provided', () => { try { let jwkMiddleware = new JWK([]); throw new Error('Expected exception was not raised.'); } catch (err) { expect(err).to.be.instanceof(InternalError); } }); it('should accept a valid certificate-based JWT', async () => { let certs: any = await generateCerts(); let token = generateSignedJWT(certs.serviceKey); event.headers['Authorization'] = `Bearer ${token}`; let request = new Request(event); let response = new Response(); let jwks: any = jwk.fromPEM(certs.serviceKey); let jwkMiddleware = new JWK([jwks.toJSON()]); await jwkMiddleware.processRequest(request, response); }); it('should deny an invalid certificate-based JWT', async () => { let signingCerts: any = await generateCerts(); let validationCerts: any = await generateCerts(); let token = generateSignedJWT(signingCerts.serviceKey); event.headers['Authorization'] = `Bearer ${token}`; let request = new Request(event); let response = new Response(); let jwks: any = jwk.fromPEM(validationCerts.serviceKey); let jwkMiddleware = new JWK([jwks.toJSON()]); try { await jwkMiddleware.processRequest(request, response); throw new Error('Expected exception was not raised.'); } catch (err) { expect(err).to.be.instanceof(Unauthorized); } }); });