UNPKG

6.49 kBJavaScriptView Raw
1'use strict';
2
3var expect = require('chai').expect;
4var winston = require('winston');
5var cache = require('../lib/cache');
6var errors = require('@leisurelink/http-equiv-errors');
7var httpMocks = require('node-mocks-http');
8
9var SignatureParser = require('../lib/signature-parser');
10
11describe('SignatureParser', function(){
12 var parser, mockAuthentic, mockHttpSignature;
13 var mockRequest, parsedRequest, keyResponse;
14
15 beforeEach(function(){
16 cache.disable();
17 mockHttpSignature = {
18 parseRequest: function() { return parsedRequest; },
19 verifySignature: function() { return true; }
20 };
21 mockAuthentic = {
22 getEndpointKey: function(lang, endpointId, keyId, cb) { cb(null, keyResponse.response, keyResponse.body); }
23 };
24
25 parsedRequest = { params: { keyId: 'some-endpoint/some-key', headers: ['host', 'date', 'request-line'] } };
26 keyResponse = { response: { statusCode: 200 }, body: { result: { key: '---PUBLIC KEY---' } } };
27 mockRequest = httpMocks.createRequest({
28 method: 'GET',
29 url: '/some/endpoint'
30 });
31 mockRequest.headers.authorization = 'authorization';
32 mockRequest.headers.host = 'some host';
33 mockRequest.headers.date = '2015-11-01';
34
35 });
36
37 describe('#parse', function(){
38 describe('given strict parsing', function(){
39 beforeEach(function(){
40 parser = SignatureParser(mockHttpSignature, mockAuthentic, winston, false);
41 });
42 it('should return parsed signature', function(){
43 return parser.parse(mockRequest).then(function(val){
44 expect(val).to.eql(parsedRequest);
45 });
46 });
47 it('should return null when parsed signature is null', function(){
48 parsedRequest = null;
49 return parser.parse(mockRequest).then(function(val){
50 expect(val).to.be.null;
51 });
52 });
53 it('should return parsed signature when parsed signature is missing params', function(){
54 parsedRequest.params = undefined;
55 return parser.parse(mockRequest).then(function(val){
56 expect(val).to.eql(parsedRequest);
57 });
58 });
59 it('should return parsed signature when parsed signature is missing keyId', function(){
60 parsedRequest.params.keyId = undefined;
61 return parser.parse(mockRequest).then(function(val){
62 expect(val).to.eql(parsedRequest);
63 });
64 });
65 it('should return null when parsing request throws error', function(){
66 mockHttpSignature.parseRequest = function(){ throw new Error('fake error'); };
67 return parser.parse(mockRequest).then(function(val){
68 expect(val).to.be.null;
69 });
70 });
71 it('should return error when authentic returns error', function(){
72 mockAuthentic.getEndpointKey = function(_, __, ___, cb) { cb(new Error('fake error')); };
73 return parser.parse(mockRequest).then(function(){
74 throw new Error('Expected failure, got success');
75 }).catch(function(err){
76 expect(err).to.be.ok;
77 });
78 });
79 it('should return UnauthorizedError when key is not found', function(){
80 keyResponse.body.result.key = undefined;
81 return parser.parse(mockRequest).then(function(){
82 throw new Error('Expected failure, got success');
83 }).catch(errors.UnauthorizedError, function(err){
84 expect(err).to.be.ok;
85 expect(err.message).to.eql('authentic:signing-key-not-found');
86 });
87 });
88 it('should return null when request is missing required headers', function(){
89 parsedRequest.params.headers = ['date'];
90 return parser.parse(mockRequest).then(function(val){
91 expect(val).to.be.null;
92 });
93 });
94 it('should return UnauthorizedError when signature is not verified', function(){
95 mockHttpSignature.verifySignature = function() { return false; };
96 return parser.parse(mockRequest).then(function(){
97 throw new Error('Expected failure, got success');
98 }).catch(errors.UnauthorizedError, function(err){
99 expect(err).to.be.ok;
100 expect(err.message).to.eql('authentic:signature-inauthentic');
101 });
102 });
103 });
104
105 describe('given lax parsing', function(){
106 beforeEach(function(){
107 parser = SignatureParser(mockHttpSignature, mockAuthentic, winston, true);
108 });
109 describe('with request that still contains signature', function(){
110 it('should return parsed signature', function(){
111 return parser.parse(mockRequest).then(function(val){
112 expect(val).to.eql(parsedRequest);
113 });
114 });
115 it('should return parsed signature when signature is not verified', function(){
116 mockHttpSignature.verifySignature = function() { return false; };
117 return parser.parse(mockRequest).then(function(val){
118 expect(val).to.eql(parsedRequest);
119 });
120 });
121 });
122 describe('with request that has signature fields in the header', function(){
123 var keyId = 'some-endpoint/some-key';
124 var jwt = 'somejwt';
125
126 beforeEach(function(){
127 mockRequest.headers = {
128 'x-lax-key-id': keyId,
129 'x-lax-headers': 'host date request-line',
130 'x-lax-jwt': jwt
131 };
132 mockHttpSignature.parseRequest = function() { return null; };
133 });
134 it('should return parsed request', function(){
135 return parser.parse(mockRequest).then(function(val){
136 expect(val).to.eql({
137 scheme: 'LaxSignature',
138 params: {
139 keyId: keyId,
140 algorithm: 'fake',
141 headers: ['host', 'date', 'request-line'],
142 jwt: jwt,
143 signature: 'fake'
144 },
145 signingString: 'fake'
146 });
147 });
148 });
149 it('should return parsed request when http signature throws error', function(){
150 mockHttpSignature.parseRequest = function() { throw new Error('fake error'); };
151 return parser.parse(mockRequest).then(function(val){
152 expect(val).to.eql({
153 scheme: 'LaxSignature',
154 params: {
155 keyId: keyId,
156 algorithm: 'fake',
157 headers: ['host', 'date', 'request-line'],
158 jwt: jwt,
159 signature: 'fake'
160 },
161 signingString: 'fake'
162 });
163 });
164 });
165 });
166 });
167 });
168});