Initial commit
[yaffs-website] / node_modules / hawk / test / server.js
1 // Load modules\r
2 \r
3 var Url = require('url');\r
4 var Code = require('code');\r
5 var Hawk = require('../lib');\r
6 var Hoek = require('hoek');\r
7 var Lab = require('lab');\r
8 \r
9 \r
10 // Declare internals\r
11 \r
12 var internals = {};\r
13 \r
14 \r
15 // Test shortcuts\r
16 \r
17 var lab = exports.lab = Lab.script();\r
18 var describe = lab.experiment;\r
19 var it = lab.test;\r
20 var expect = Code.expect;\r
21 \r
22 \r
23 describe('Server', function () {\r
24 \r
25     var credentialsFunc = function (id, callback) {\r
26 \r
27         var credentials = {\r
28             id: id,\r
29             key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
30             algorithm: (id === '1' ? 'sha1' : 'sha256'),\r
31             user: 'steve'\r
32         };\r
33 \r
34         return callback(null, credentials);\r
35     };\r
36 \r
37     describe('authenticate()', function () {\r
38 \r
39         it('parses a valid authentication header (sha1)', function (done) {\r
40 \r
41             var req = {\r
42                 method: 'GET',\r
43                 url: '/resource/4?filter=a',\r
44                 host: 'example.com',\r
45                 port: 8080,\r
46                 authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'\r
47             };\r
48 \r
49             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
50 \r
51                 expect(err).to.not.exist();\r
52                 expect(credentials.user).to.equal('steve');\r
53                 done();\r
54             });\r
55         });\r
56 \r
57         it('parses a valid authentication header (sha256)', function (done) {\r
58 \r
59             var req = {\r
60                 method: 'GET',\r
61                 url: '/resource/1?b=1&a=2',\r
62                 host: 'example.com',\r
63                 port: 8000,\r
64                 authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'\r
65             };\r
66 \r
67             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
68 \r
69                 expect(err).to.not.exist();\r
70                 expect(credentials.user).to.equal('steve');\r
71                 done();\r
72             });\r
73         });\r
74 \r
75         it('parses a valid authentication header (host override)', function (done) {\r
76 \r
77             var req = {\r
78                 method: 'GET',\r
79                 url: '/resource/4?filter=a',\r
80                 headers: {\r
81                     host: 'example1.com:8080',\r
82                     authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'\r
83                 }\r
84             };\r
85 \r
86             Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
87 \r
88                 expect(err).to.not.exist();\r
89                 expect(credentials.user).to.equal('steve');\r
90                 done();\r
91             });\r
92         });\r
93 \r
94         it('parses a valid authentication header (host port override)', function (done) {\r
95 \r
96             var req = {\r
97                 method: 'GET',\r
98                 url: '/resource/4?filter=a',\r
99                 headers: {\r
100                     host: 'example1.com:80',\r
101                     authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'\r
102                 }\r
103             };\r
104 \r
105             Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
106 \r
107                 expect(err).to.not.exist();\r
108                 expect(credentials.user).to.equal('steve');\r
109                 done();\r
110             });\r
111         });\r
112 \r
113         it('parses a valid authentication header (POST with payload)', function (done) {\r
114 \r
115             var req = {\r
116                 method: 'POST',\r
117                 url: '/resource/4?filter=a',\r
118                 host: 'example.com',\r
119                 port: 8080,\r
120                 authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="'\r
121             };\r
122 \r
123             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
124 \r
125                 expect(err).to.not.exist();\r
126                 expect(credentials.user).to.equal('steve');\r
127                 done();\r
128             });\r
129         });\r
130 \r
131         it('errors on missing hash', function (done) {\r
132 \r
133             var req = {\r
134                 method: 'GET',\r
135                 url: '/resource/1?b=1&a=2',\r
136                 host: 'example.com',\r
137                 port: 8000,\r
138                 authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'\r
139             };\r
140 \r
141             Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
142 \r
143                 expect(err).to.exist();\r
144                 expect(err.output.payload.message).to.equal('Missing required payload hash');\r
145                 done();\r
146             });\r
147         });\r
148 \r
149         it('errors on a stale timestamp', function (done) {\r
150 \r
151             var req = {\r
152                 method: 'GET',\r
153                 url: '/resource/4?filter=a',\r
154                 host: 'example.com',\r
155                 port: 8080,\r
156                 authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="'\r
157             };\r
158 \r
159             Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {\r
160 \r
161                 expect(err).to.exist();\r
162                 expect(err.output.payload.message).to.equal('Stale timestamp');\r
163                 var header = err.output.headers['WWW-Authenticate'];\r
164                 var ts = header.match(/^Hawk ts\=\"(\d+)\"\, tsm\=\"([^\"]+)\"\, error=\"Stale timestamp\"$/);\r
165                 var now = Hawk.utils.now();\r
166                 expect(parseInt(ts[1], 10) * 1000).to.be.within(now - 1000, now + 1000);\r
167 \r
168                 var res = {\r
169                     headers: {\r
170                         'www-authenticate': header\r
171                     }\r
172                 };\r
173 \r
174                 expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true);\r
175                 done();\r
176             });\r
177         });\r
178 \r
179         it('errors on a replay', function (done) {\r
180 \r
181             var req = {\r
182                 method: 'GET',\r
183                 url: '/resource/4?filter=a',\r
184                 host: 'example.com',\r
185                 port: 8080,\r
186                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"'\r
187             };\r
188 \r
189             var memoryCache = {};\r
190             var options = {\r
191                 localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(),\r
192                 nonceFunc: function (key, nonce, ts, callback) {\r
193 \r
194                     if (memoryCache[key + nonce]) {\r
195                         return callback(new Error());\r
196                     }\r
197 \r
198                     memoryCache[key + nonce] = true;\r
199                     return callback();\r
200                 }\r
201             };\r
202 \r
203             Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials1, artifacts1) {\r
204 \r
205                 expect(err).to.not.exist();\r
206                 expect(credentials1.user).to.equal('steve');\r
207 \r
208                 Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials2, artifacts2) {\r
209 \r
210                     expect(err).to.exist();\r
211                     expect(err.output.payload.message).to.equal('Invalid nonce');\r
212                     done();\r
213                 });\r
214             });\r
215         });\r
216 \r
217         it('does not error on nonce collision if keys differ', function (done) {\r
218 \r
219             var reqSteve = {\r
220                 method: 'GET',\r
221                 url: '/resource/4?filter=a',\r
222                 host: 'example.com',\r
223                 port: 8080,\r
224                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"'\r
225             };\r
226 \r
227             var reqBob = {\r
228                 method: 'GET',\r
229                 url: '/resource/4?filter=a',\r
230                 host: 'example.com',\r
231                 port: 8080,\r
232                 authorization: 'Hawk id="456", ts="1353788437", nonce="k3j4h2", mac="LXfmTnRzrLd9TD7yfH+4se46Bx6AHyhpM94hLCiNia4=", ext="hello"'\r
233             };\r
234 \r
235             var credentialsFuncion = function (id, callback) {\r
236 \r
237                 var credentials = {\r
238                     '123': {\r
239                         id: id,\r
240                         key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
241                         algorithm: (id === '1' ? 'sha1' : 'sha256'),\r
242                         user: 'steve'\r
243                     },\r
244                     '456': {\r
245                         id: id,\r
246                         key: 'xrunpaw3489ruxnpa98w4rxnwerxhqb98rpaxn39848',\r
247                         algorithm: (id === '1' ? 'sha1' : 'sha256'),\r
248                         user: 'bob'\r
249                     }\r
250                 };\r
251 \r
252                 return callback(null, credentials[id]);\r
253             };\r
254 \r
255             var memoryCache = {};\r
256             var options = {\r
257                 localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(),\r
258                 nonceFunc: function (key, nonce, ts, callback) {\r
259 \r
260                     if (memoryCache[key + nonce]) {\r
261                         return callback(new Error());\r
262                     }\r
263 \r
264                     memoryCache[key + nonce] = true;\r
265                     return callback();\r
266                 }\r
267             };\r
268 \r
269             Hawk.server.authenticate(reqSteve, credentialsFuncion, options, function (err, credentials1, artifacts1) {\r
270 \r
271                 expect(err).to.not.exist();\r
272                 expect(credentials1.user).to.equal('steve');\r
273 \r
274                 Hawk.server.authenticate(reqBob, credentialsFuncion, options, function (err, credentials2, artifacts2) {\r
275 \r
276                     expect(err).to.not.exist();\r
277                     expect(credentials2.user).to.equal('bob');\r
278                     done();\r
279                 });\r
280             });\r
281         });\r
282 \r
283         it('errors on an invalid authentication header: wrong scheme', function (done) {\r
284 \r
285             var req = {\r
286                 method: 'GET',\r
287                 url: '/resource/4?filter=a',\r
288                 host: 'example.com',\r
289                 port: 8080,\r
290                 authorization: 'Basic asdasdasdasd'\r
291             };\r
292 \r
293             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
294 \r
295                 expect(err).to.exist();\r
296                 expect(err.output.payload.message).to.not.exist();\r
297                 done();\r
298             });\r
299         });\r
300 \r
301         it('errors on an invalid authentication header: no scheme', function (done) {\r
302 \r
303             var req = {\r
304                 method: 'GET',\r
305                 url: '/resource/4?filter=a',\r
306                 host: 'example.com',\r
307                 port: 8080,\r
308                 authorization: '!@#'\r
309             };\r
310 \r
311             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
312 \r
313                 expect(err).to.exist();\r
314                 expect(err.output.payload.message).to.equal('Invalid header syntax');\r
315                 done();\r
316             });\r
317         });\r
318 \r
319         it('errors on an missing authorization header', function (done) {\r
320 \r
321             var req = {\r
322                 method: 'GET',\r
323                 url: '/resource/4?filter=a',\r
324                 host: 'example.com',\r
325                 port: 8080\r
326             };\r
327 \r
328             Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {\r
329 \r
330                 expect(err).to.exist();\r
331                 expect(err.isMissing).to.equal(true);\r
332                 done();\r
333             });\r
334         });\r
335 \r
336         it('errors on an missing host header', function (done) {\r
337 \r
338             var req = {\r
339                 method: 'GET',\r
340                 url: '/resource/4?filter=a',\r
341                 headers: {\r
342                     authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
343                 }\r
344             };\r
345 \r
346             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
347 \r
348                 expect(err).to.exist();\r
349                 expect(err.output.payload.message).to.equal('Invalid Host header');\r
350                 done();\r
351             });\r
352         });\r
353 \r
354         it('errors on an missing authorization attribute (id)', function (done) {\r
355 \r
356             var req = {\r
357                 method: 'GET',\r
358                 url: '/resource/4?filter=a',\r
359                 host: 'example.com',\r
360                 port: 8080,\r
361                 authorization: 'Hawk ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
362             };\r
363 \r
364             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
365 \r
366                 expect(err).to.exist();\r
367                 expect(err.output.payload.message).to.equal('Missing attributes');\r
368                 done();\r
369             });\r
370         });\r
371 \r
372         it('errors on an missing authorization attribute (ts)', function (done) {\r
373 \r
374             var req = {\r
375                 method: 'GET',\r
376                 url: '/resource/4?filter=a',\r
377                 host: 'example.com',\r
378                 port: 8080,\r
379                 authorization: 'Hawk id="123", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
380             };\r
381 \r
382             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
383 \r
384                 expect(err).to.exist();\r
385                 expect(err.output.payload.message).to.equal('Missing attributes');\r
386                 done();\r
387             });\r
388         });\r
389 \r
390         it('errors on an missing authorization attribute (nonce)', function (done) {\r
391 \r
392             var req = {\r
393                 method: 'GET',\r
394                 url: '/resource/4?filter=a',\r
395                 host: 'example.com',\r
396                 port: 8080,\r
397                 authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
398             };\r
399 \r
400             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
401 \r
402                 expect(err).to.exist();\r
403                 expect(err.output.payload.message).to.equal('Missing attributes');\r
404                 done();\r
405             });\r
406         });\r
407 \r
408         it('errors on an missing authorization attribute (mac)', function (done) {\r
409 \r
410             var req = {\r
411                 method: 'GET',\r
412                 url: '/resource/4?filter=a',\r
413                 host: 'example.com',\r
414                 port: 8080,\r
415                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", ext="hello"'\r
416             };\r
417 \r
418             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
419 \r
420                 expect(err).to.exist();\r
421                 expect(err.output.payload.message).to.equal('Missing attributes');\r
422                 done();\r
423             });\r
424         });\r
425 \r
426         it('errors on an unknown authorization attribute', function (done) {\r
427 \r
428             var req = {\r
429                 method: 'GET',\r
430                 url: '/resource/4?filter=a',\r
431                 host: 'example.com',\r
432                 port: 8080,\r
433                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
434             };\r
435 \r
436             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
437 \r
438                 expect(err).to.exist();\r
439                 expect(err.output.payload.message).to.equal('Unknown attribute: x');\r
440                 done();\r
441             });\r
442         });\r
443 \r
444         it('errors on an bad authorization header format', function (done) {\r
445 \r
446             var req = {\r
447                 method: 'GET',\r
448                 url: '/resource/4?filter=a',\r
449                 host: 'example.com',\r
450                 port: 8080,\r
451                 authorization: 'Hawk id="123\\", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
452             };\r
453 \r
454             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
455 \r
456                 expect(err).to.exist();\r
457                 expect(err.output.payload.message).to.equal('Bad header format');\r
458                 done();\r
459             });\r
460         });\r
461 \r
462         it('errors on an bad authorization attribute value', function (done) {\r
463 \r
464             var req = {\r
465                 method: 'GET',\r
466                 url: '/resource/4?filter=a',\r
467                 host: 'example.com',\r
468                 port: 8080,\r
469                 authorization: 'Hawk id="\t", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
470             };\r
471 \r
472             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
473 \r
474                 expect(err).to.exist();\r
475                 expect(err.output.payload.message).to.equal('Bad attribute value: id');\r
476                 done();\r
477             });\r
478         });\r
479 \r
480         it('errors on an empty authorization attribute value', function (done) {\r
481 \r
482             var req = {\r
483                 method: 'GET',\r
484                 url: '/resource/4?filter=a',\r
485                 host: 'example.com',\r
486                 port: 8080,\r
487                 authorization: 'Hawk id="", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
488             };\r
489 \r
490             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
491 \r
492                 expect(err).to.exist();\r
493                 expect(err.output.payload.message).to.equal('Bad attribute value: id');\r
494                 done();\r
495             });\r
496         });\r
497 \r
498         it('errors on duplicated authorization attribute key', function (done) {\r
499 \r
500             var req = {\r
501                 method: 'GET',\r
502                 url: '/resource/4?filter=a',\r
503                 host: 'example.com',\r
504                 port: 8080,\r
505                 authorization: 'Hawk id="123", id="456", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
506             };\r
507 \r
508             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
509 \r
510                 expect(err).to.exist();\r
511                 expect(err.output.payload.message).to.equal('Duplicate attribute: id');\r
512                 done();\r
513             });\r
514         });\r
515 \r
516         it('errors on an invalid authorization header format', function (done) {\r
517 \r
518             var req = {\r
519                 method: 'GET',\r
520                 url: '/resource/4?filter=a',\r
521                 host: 'example.com',\r
522                 port: 8080,\r
523                 authorization: 'Hawk'\r
524             };\r
525 \r
526             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
527 \r
528                 expect(err).to.exist();\r
529                 expect(err.output.payload.message).to.equal('Invalid header syntax');\r
530                 done();\r
531             });\r
532         });\r
533 \r
534         it('errors on an bad host header (missing host)', function (done) {\r
535 \r
536             var req = {\r
537                 method: 'GET',\r
538                 url: '/resource/4?filter=a',\r
539                 headers: {\r
540                     host: ':8080',\r
541                     authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
542                 }\r
543             };\r
544 \r
545             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
546 \r
547                 expect(err).to.exist();\r
548                 expect(err.output.payload.message).to.equal('Invalid Host header');\r
549                 done();\r
550             });\r
551         });\r
552 \r
553         it('errors on an bad host header (pad port)', function (done) {\r
554 \r
555             var req = {\r
556                 method: 'GET',\r
557                 url: '/resource/4?filter=a',\r
558                 headers: {\r
559                     host: 'example.com:something',\r
560                     authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
561                 }\r
562             };\r
563 \r
564             Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
565 \r
566                 expect(err).to.exist();\r
567                 expect(err.output.payload.message).to.equal('Invalid Host header');\r
568                 done();\r
569             });\r
570         });\r
571 \r
572         it('errors on credentialsFunc error', function (done) {\r
573 \r
574             var req = {\r
575                 method: 'GET',\r
576                 url: '/resource/4?filter=a',\r
577                 host: 'example.com',\r
578                 port: 8080,\r
579                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
580             };\r
581 \r
582             var credentialsFuncion = function (id, callback) {\r
583 \r
584                 return callback(new Error('Unknown user'));\r
585             };\r
586 \r
587             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
588 \r
589                 expect(err).to.exist();\r
590                 expect(err.message).to.equal('Unknown user');\r
591                 done();\r
592             });\r
593         });\r
594 \r
595         it('errors on credentialsFunc error (with credentials)', function (done) {\r
596 \r
597             var req = {\r
598                 method: 'GET',\r
599                 url: '/resource/4?filter=a',\r
600                 host: 'example.com',\r
601                 port: 8080,\r
602                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
603             };\r
604 \r
605             var credentialsFuncion = function (id, callback) {\r
606 \r
607                 return callback(new Error('Unknown user'), { some: 'value' });\r
608             };\r
609 \r
610             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
611 \r
612                 expect(err).to.exist();\r
613                 expect(err.message).to.equal('Unknown user');\r
614                 expect(credentials.some).to.equal('value');\r
615                 done();\r
616             });\r
617         });\r
618 \r
619         it('errors on missing credentials', function (done) {\r
620 \r
621             var req = {\r
622                 method: 'GET',\r
623                 url: '/resource/4?filter=a',\r
624                 host: 'example.com',\r
625                 port: 8080,\r
626                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
627             };\r
628 \r
629             var credentialsFuncion = function (id, callback) {\r
630 \r
631                 return callback(null, null);\r
632             };\r
633 \r
634             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
635 \r
636                 expect(err).to.exist();\r
637                 expect(err.output.payload.message).to.equal('Unknown credentials');\r
638                 done();\r
639             });\r
640         });\r
641 \r
642         it('errors on invalid credentials (id)', function (done) {\r
643 \r
644             var req = {\r
645                 method: 'GET',\r
646                 url: '/resource/4?filter=a',\r
647                 host: 'example.com',\r
648                 port: 8080,\r
649                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
650             };\r
651 \r
652             var credentialsFuncion = function (id, callback) {\r
653 \r
654                 var credentials = {\r
655                     key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
656                     user: 'steve'\r
657                 };\r
658 \r
659                 return callback(null, credentials);\r
660             };\r
661 \r
662             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
663 \r
664                 expect(err).to.exist();\r
665                 expect(err.message).to.equal('Invalid credentials');\r
666                 expect(err.output.payload.message).to.equal('An internal server error occurred');\r
667                 done();\r
668             });\r
669         });\r
670 \r
671         it('errors on invalid credentials (key)', function (done) {\r
672 \r
673             var req = {\r
674                 method: 'GET',\r
675                 url: '/resource/4?filter=a',\r
676                 host: 'example.com',\r
677                 port: 8080,\r
678                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
679             };\r
680 \r
681             var credentialsFuncion = function (id, callback) {\r
682 \r
683                 var credentials = {\r
684                     id: '23434d3q4d5345d',\r
685                     user: 'steve'\r
686                 };\r
687 \r
688                 return callback(null, credentials);\r
689             };\r
690 \r
691             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
692 \r
693                 expect(err).to.exist();\r
694                 expect(err.message).to.equal('Invalid credentials');\r
695                 expect(err.output.payload.message).to.equal('An internal server error occurred');\r
696                 done();\r
697             });\r
698         });\r
699 \r
700         it('errors on unknown credentials algorithm', function (done) {\r
701 \r
702             var req = {\r
703                 method: 'GET',\r
704                 url: '/resource/4?filter=a',\r
705                 host: 'example.com',\r
706                 port: 8080,\r
707                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
708             };\r
709 \r
710             var credentialsFuncion = function (id, callback) {\r
711 \r
712                 var credentials = {\r
713                     key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
714                     algorithm: 'hmac-sha-0',\r
715                     user: 'steve'\r
716                 };\r
717 \r
718                 return callback(null, credentials);\r
719             };\r
720 \r
721             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
722 \r
723                 expect(err).to.exist();\r
724                 expect(err.message).to.equal('Unknown algorithm');\r
725                 expect(err.output.payload.message).to.equal('An internal server error occurred');\r
726                 done();\r
727             });\r
728         });\r
729 \r
730         it('errors on unknown bad mac', function (done) {\r
731 \r
732             var req = {\r
733                 method: 'GET',\r
734                 url: '/resource/4?filter=a',\r
735                 host: 'example.com',\r
736                 port: 8080,\r
737                 authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"'\r
738             };\r
739 \r
740             var credentialsFuncion = function (id, callback) {\r
741 \r
742                 var credentials = {\r
743                     key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
744                     algorithm: 'sha256',\r
745                     user: 'steve'\r
746                 };\r
747 \r
748                 return callback(null, credentials);\r
749             };\r
750 \r
751             Hawk.server.authenticate(req, credentialsFuncion, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {\r
752 \r
753                 expect(err).to.exist();\r
754                 expect(err.output.payload.message).to.equal('Bad mac');\r
755                 done();\r
756             });\r
757         });\r
758     });\r
759 \r
760     describe('header()', function () {\r
761 \r
762         it('generates header', function (done) {\r
763 \r
764             var credentials = {\r
765                 id: '123456',\r
766                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
767                 algorithm: 'sha256',\r
768                 user: 'steve'\r
769             };\r
770 \r
771             var artifacts = {\r
772                 method: 'POST',\r
773                 host: 'example.com',\r
774                 port: '8080',\r
775                 resource: '/resource/4?filter=a',\r
776                 ts: '1398546787',\r
777                 nonce: 'xUwusx',\r
778                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
779                 ext: 'some-app-data',\r
780                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
781                 id: '123456'\r
782             };\r
783 \r
784             var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
785             expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');\r
786             done();\r
787         });\r
788 \r
789         it('generates header (empty payload)', function (done) {\r
790 \r
791             var credentials = {\r
792                 id: '123456',\r
793                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
794                 algorithm: 'sha256',\r
795                 user: 'steve'\r
796             };\r
797 \r
798             var artifacts = {\r
799                 method: 'POST',\r
800                 host: 'example.com',\r
801                 port: '8080',\r
802                 resource: '/resource/4?filter=a',\r
803                 ts: '1398546787',\r
804                 nonce: 'xUwusx',\r
805                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
806                 ext: 'some-app-data',\r
807                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
808                 id: '123456'\r
809             };\r
810 \r
811             var header = Hawk.server.header(credentials, artifacts, { payload: '', contentType: 'text/plain', ext: 'response-specific' });\r
812             expect(header).to.equal('Hawk mac=\"i8/kUBDx0QF+PpCtW860kkV/fa9dbwEoe/FpGUXowf0=\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", ext=\"response-specific\"');\r
813             done();\r
814         });\r
815 \r
816         it('generates header (pre calculated hash)', function (done) {\r
817 \r
818             var credentials = {\r
819                 id: '123456',\r
820                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
821                 algorithm: 'sha256',\r
822                 user: 'steve'\r
823             };\r
824 \r
825             var artifacts = {\r
826                 method: 'POST',\r
827                 host: 'example.com',\r
828                 port: '8080',\r
829                 resource: '/resource/4?filter=a',\r
830                 ts: '1398546787',\r
831                 nonce: 'xUwusx',\r
832                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
833                 ext: 'some-app-data',\r
834                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
835                 id: '123456'\r
836             };\r
837 \r
838             var options = { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' };\r
839             options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);\r
840             var header = Hawk.server.header(credentials, artifacts, options);\r
841             expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');\r
842             done();\r
843         });\r
844 \r
845         it('generates header (null ext)', function (done) {\r
846 \r
847             var credentials = {\r
848                 id: '123456',\r
849                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
850                 algorithm: 'sha256',\r
851                 user: 'steve'\r
852             };\r
853 \r
854             var artifacts = {\r
855                 method: 'POST',\r
856                 host: 'example.com',\r
857                 port: '8080',\r
858                 resource: '/resource/4?filter=a',\r
859                 ts: '1398546787',\r
860                 nonce: 'xUwusx',\r
861                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
862                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
863                 id: '123456'\r
864             };\r
865 \r
866             var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: null });\r
867             expect(header).to.equal('Hawk mac=\"6PrybJTJs20jsgBw5eilXpcytD8kUbaIKNYXL+6g0ns=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\"');\r
868             done();\r
869         });\r
870 \r
871         it('errors on missing artifacts', function (done) {\r
872 \r
873             var credentials = {\r
874                 id: '123456',\r
875                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
876                 algorithm: 'sha256',\r
877                 user: 'steve'\r
878             };\r
879 \r
880             var header = Hawk.server.header(credentials, null, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
881             expect(header).to.equal('');\r
882             done();\r
883         });\r
884 \r
885         it('errors on invalid artifacts', function (done) {\r
886 \r
887             var credentials = {\r
888                 id: '123456',\r
889                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
890                 algorithm: 'sha256',\r
891                 user: 'steve'\r
892             };\r
893 \r
894             var header = Hawk.server.header(credentials, 5, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
895             expect(header).to.equal('');\r
896             done();\r
897         });\r
898 \r
899         it('errors on missing credentials', function (done) {\r
900 \r
901             var artifacts = {\r
902                 method: 'POST',\r
903                 host: 'example.com',\r
904                 port: '8080',\r
905                 resource: '/resource/4?filter=a',\r
906                 ts: '1398546787',\r
907                 nonce: 'xUwusx',\r
908                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
909                 ext: 'some-app-data',\r
910                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
911                 id: '123456'\r
912             };\r
913 \r
914             var header = Hawk.server.header(null, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
915             expect(header).to.equal('');\r
916             done();\r
917         });\r
918 \r
919         it('errors on invalid credentials (key)', function (done) {\r
920 \r
921             var credentials = {\r
922                 id: '123456',\r
923                 algorithm: 'sha256',\r
924                 user: 'steve'\r
925             };\r
926 \r
927             var artifacts = {\r
928                 method: 'POST',\r
929                 host: 'example.com',\r
930                 port: '8080',\r
931                 resource: '/resource/4?filter=a',\r
932                 ts: '1398546787',\r
933                 nonce: 'xUwusx',\r
934                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
935                 ext: 'some-app-data',\r
936                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
937                 id: '123456'\r
938             };\r
939 \r
940             var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
941             expect(header).to.equal('');\r
942             done();\r
943         });\r
944 \r
945         it('errors on invalid algorithm', function (done) {\r
946 \r
947             var credentials = {\r
948                 id: '123456',\r
949                 key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r
950                 algorithm: 'x',\r
951                 user: 'steve'\r
952             };\r
953 \r
954             var artifacts = {\r
955                 method: 'POST',\r
956                 host: 'example.com',\r
957                 port: '8080',\r
958                 resource: '/resource/4?filter=a',\r
959                 ts: '1398546787',\r
960                 nonce: 'xUwusx',\r
961                 hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',\r
962                 ext: 'some-app-data',\r
963                 mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',\r
964                 id: '123456'\r
965             };\r
966 \r
967             var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });\r
968             expect(header).to.equal('');\r
969             done();\r
970         });\r
971     });\r
972 \r
973     describe('authenticateBewit()', function () {\r
974 \r
975         it('errors on uri too long', function (done) {\r
976 \r
977             var long = '/';\r
978             for (var i = 0; i < 5000; ++i) {\r
979                 long += 'x';\r
980             }\r
981 \r
982             var req = {\r
983                 method: 'GET',\r
984                 url: long,\r
985                 host: 'example.com',\r
986                 port: 8080,\r
987                 authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'\r
988             };\r
989 \r
990             Hawk.server.authenticateBewit(req, credentialsFunc, {}, function (err, credentials, bewit) {\r
991 \r
992                 expect(err).to.exist();\r
993                 expect(err.output.statusCode).to.equal(400);\r
994                 expect(err.message).to.equal('Resource path exceeds max length');\r
995                 done();\r
996             });\r
997         });\r
998     });\r
999 \r
1000     describe('authenticateMessage()', function () {\r
1001 \r
1002         it('errors on invalid authorization (ts)', function (done) {\r
1003 \r
1004             credentialsFunc('123456', function (err, credentials1) {\r
1005 \r
1006                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1007                 delete auth.ts;\r
1008 \r
1009                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1010 \r
1011                     expect(err).to.exist();\r
1012                     expect(err.message).to.equal('Invalid authorization');\r
1013                     done();\r
1014                 });\r
1015             });\r
1016         });\r
1017 \r
1018         it('errors on invalid authorization (nonce)', function (done) {\r
1019 \r
1020             credentialsFunc('123456', function (err, credentials1) {\r
1021 \r
1022                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1023                 delete auth.nonce;\r
1024 \r
1025                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1026 \r
1027                     expect(err).to.exist();\r
1028                     expect(err.message).to.equal('Invalid authorization');\r
1029                     done();\r
1030                 });\r
1031             });\r
1032         });\r
1033 \r
1034         it('errors on invalid authorization (hash)', function (done) {\r
1035 \r
1036             credentialsFunc('123456', function (err, credentials1) {\r
1037 \r
1038                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1039                 delete auth.hash;\r
1040 \r
1041                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1042 \r
1043                     expect(err).to.exist();\r
1044                     expect(err.message).to.equal('Invalid authorization');\r
1045                     done();\r
1046                 });\r
1047             });\r
1048         });\r
1049 \r
1050         it('errors with credentials', function (done) {\r
1051 \r
1052             credentialsFunc('123456', function (err, credentials1) {\r
1053 \r
1054                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1055 \r
1056                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, function (id, callback) {\r
1057 \r
1058                     callback(new Error('something'), { some: 'value' });\r
1059                 }, {}, function (err, credentials2) {\r
1060 \r
1061                     expect(err).to.exist();\r
1062                     expect(err.message).to.equal('something');\r
1063                     expect(credentials2.some).to.equal('value');\r
1064                     done();\r
1065                 });\r
1066             });\r
1067         });\r
1068 \r
1069         it('errors on nonce collision', function (done) {\r
1070 \r
1071             credentialsFunc('123456', function (err, credentials1) {\r
1072 \r
1073                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1074                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {\r
1075                     nonceFunc: function (key, nonce, ts, nonceCallback) {\r
1076 \r
1077                         nonceCallback(true);\r
1078                     }\r
1079                 }, function (err, credentials2) {\r
1080 \r
1081                     expect(err).to.exist();\r
1082                     expect(err.message).to.equal('Invalid nonce');\r
1083                     done();\r
1084                 });\r
1085             });\r
1086         });\r
1087 \r
1088         it('should generate an authorization then successfully parse it', function (done) {\r
1089 \r
1090             credentialsFunc('123456', function (err, credentials1) {\r
1091 \r
1092                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1093                 expect(auth).to.exist();\r
1094 \r
1095                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1096 \r
1097                     expect(err).to.not.exist();\r
1098                     expect(credentials2.user).to.equal('steve');\r
1099                     done();\r
1100                 });\r
1101             });\r
1102         });\r
1103 \r
1104         it('should fail authorization on mismatching host', function (done) {\r
1105 \r
1106             credentialsFunc('123456', function (err, credentials1) {\r
1107 \r
1108                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1109                 expect(auth).to.exist();\r
1110 \r
1111                 Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1112 \r
1113                     expect(err).to.exist();\r
1114                     expect(err.message).to.equal('Bad mac');\r
1115                     done();\r
1116                 });\r
1117             });\r
1118         });\r
1119 \r
1120         it('should fail authorization on stale timestamp', function (done) {\r
1121 \r
1122             credentialsFunc('123456', function (err, credentials1) {\r
1123 \r
1124                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1125                 expect(auth).to.exist();\r
1126 \r
1127                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials2) {\r
1128 \r
1129                     expect(err).to.exist();\r
1130                     expect(err.message).to.equal('Stale timestamp');\r
1131                     done();\r
1132                 });\r
1133             });\r
1134         });\r
1135 \r
1136         it('overrides timestampSkewSec', function (done) {\r
1137 \r
1138             credentialsFunc('123456', function (err, credentials1) {\r
1139 \r
1140                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1, localtimeOffsetMsec: 100000 });\r
1141                 expect(auth).to.exist();\r
1142 \r
1143                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { timestampSkewSec: 500 }, function (err, credentials2) {\r
1144 \r
1145                     expect(err).to.not.exist();\r
1146                     done();\r
1147                 });\r
1148             });\r
1149         });\r
1150 \r
1151         it('should fail authorization on invalid authorization', function (done) {\r
1152 \r
1153             credentialsFunc('123456', function (err, credentials1) {\r
1154 \r
1155                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1156                 expect(auth).to.exist();\r
1157                 delete auth.id;\r
1158 \r
1159                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {\r
1160 \r
1161                     expect(err).to.exist();\r
1162                     expect(err.message).to.equal('Invalid authorization');\r
1163                     done();\r
1164                 });\r
1165             });\r
1166         });\r
1167 \r
1168         it('should fail authorization on bad hash', function (done) {\r
1169 \r
1170             credentialsFunc('123456', function (err, credentials1) {\r
1171 \r
1172                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1173                 expect(auth).to.exist();\r
1174 \r
1175                 Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials2) {\r
1176 \r
1177                     expect(err).to.exist();\r
1178                     expect(err.message).to.equal('Bad message hash');\r
1179                     done();\r
1180                 });\r
1181             });\r
1182         });\r
1183 \r
1184         it('should fail authorization on nonce error', function (done) {\r
1185 \r
1186             credentialsFunc('123456', function (err, credentials1) {\r
1187 \r
1188                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1189                 expect(auth).to.exist();\r
1190 \r
1191                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {\r
1192                     nonceFunc: function (key, nonce, ts, callback) {\r
1193 \r
1194                         callback(new Error('kaboom'));\r
1195                     }\r
1196                 }, function (err, credentials2) {\r
1197 \r
1198                     expect(err).to.exist();\r
1199                     expect(err.message).to.equal('Invalid nonce');\r
1200                     done();\r
1201                 });\r
1202             });\r
1203         });\r
1204 \r
1205         it('should fail authorization on credentials error', function (done) {\r
1206 \r
1207             credentialsFunc('123456', function (err, credentials1) {\r
1208 \r
1209                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1210                 expect(auth).to.exist();\r
1211 \r
1212                 var errFunc = function (id, callback) {\r
1213 \r
1214                     callback(new Error('kablooey'));\r
1215                 };\r
1216 \r
1217                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {\r
1218 \r
1219                     expect(err).to.exist();\r
1220                     expect(err.message).to.equal('kablooey');\r
1221                     done();\r
1222                 });\r
1223             });\r
1224         });\r
1225 \r
1226         it('should fail authorization on missing credentials', function (done) {\r
1227 \r
1228             credentialsFunc('123456', function (err, credentials1) {\r
1229 \r
1230                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1231                 expect(auth).to.exist();\r
1232 \r
1233                 var errFunc = function (id, callback) {\r
1234 \r
1235                     callback();\r
1236                 };\r
1237 \r
1238                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {\r
1239 \r
1240                     expect(err).to.exist();\r
1241                     expect(err.message).to.equal('Unknown credentials');\r
1242                     done();\r
1243                 });\r
1244             });\r
1245         });\r
1246 \r
1247         it('should fail authorization on invalid credentials', function (done) {\r
1248 \r
1249             credentialsFunc('123456', function (err, credentials1) {\r
1250 \r
1251                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1252                 expect(auth).to.exist();\r
1253 \r
1254                 var errFunc = function (id, callback) {\r
1255 \r
1256                     callback(null, {});\r
1257                 };\r
1258 \r
1259                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {\r
1260 \r
1261                     expect(err).to.exist();\r
1262                     expect(err.message).to.equal('Invalid credentials');\r
1263                     done();\r
1264                 });\r
1265             });\r
1266         });\r
1267 \r
1268         it('should fail authorization on invalid credentials algorithm', function (done) {\r
1269 \r
1270             credentialsFunc('123456', function (err, credentials1) {\r
1271 \r
1272                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });\r
1273                 expect(auth).to.exist();\r
1274 \r
1275                 var errFunc = function (id, callback) {\r
1276 \r
1277                     callback(null, { key: '123', algorithm: '456' });\r
1278                 };\r
1279 \r
1280                 Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {\r
1281 \r
1282                     expect(err).to.exist();\r
1283                     expect(err.message).to.equal('Unknown algorithm');\r
1284                     done();\r
1285                 });\r
1286             });\r
1287         });\r
1288 \r
1289         it('should fail on missing host', function (done) {\r
1290 \r
1291             credentialsFunc('123456', function (err, credentials) {\r
1292 \r
1293                 var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials });\r
1294                 expect(auth).to.not.exist();\r
1295                 done();\r
1296             });\r
1297         });\r
1298 \r
1299         it('should fail on missing credentials', function (done) {\r
1300 \r
1301             var auth = Hawk.client.message('example.com', 8080, 'some message', {});\r
1302             expect(auth).to.not.exist();\r
1303             done();\r
1304         });\r
1305 \r
1306         it('should fail on invalid algorithm', function (done) {\r
1307 \r
1308             credentialsFunc('123456', function (err, credentials) {\r
1309 \r
1310                 var creds = Hoek.clone(credentials);\r
1311                 creds.algorithm = 'blah';\r
1312                 var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds });\r
1313                 expect(auth).to.not.exist();\r
1314                 done();\r
1315             });\r
1316         });\r
1317     });\r
1318 \r
1319     describe('authenticatePayloadHash()', function () {\r
1320 \r
1321         it('checks payload hash', function (done) {\r
1322 \r
1323             expect(Hawk.server.authenticatePayloadHash('abcdefg', { hash: 'abcdefg' })).to.equal(true);\r
1324             expect(Hawk.server.authenticatePayloadHash('1234567', { hash: 'abcdefg' })).to.equal(false);\r
1325             done();\r
1326         });\r
1327     });\r
1328 });\r
1329 \r