Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81146 views
1
// Load modules
2
3
var Url = require('url');
4
var Code = require('code');
5
var Hawk = require('../lib');
6
var Lab = require('lab');
7
8
9
// Declare internals
10
11
var internals = {};
12
13
14
// Test shortcuts
15
16
var lab = exports.lab = Lab.script();
17
var describe = lab.experiment;
18
var it = lab.test;
19
var expect = Code.expect;
20
21
22
describe('Hawk', function () {
23
24
describe('server', function () {
25
26
var credentialsFunc = function (id, callback) {
27
28
var credentials = {
29
id: id,
30
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
31
algorithm: (id === '1' ? 'sha1' : 'sha256'),
32
user: 'steve'
33
};
34
35
return callback(null, credentials);
36
};
37
38
describe('#authenticate', function () {
39
40
it('parses a valid authentication header (sha1)', function (done) {
41
42
var req = {
43
method: 'GET',
44
url: '/resource/4?filter=a',
45
host: 'example.com',
46
port: 8080,
47
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
48
};
49
50
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
51
52
expect(err).to.not.exist();
53
expect(credentials.user).to.equal('steve');
54
done();
55
});
56
});
57
58
it('parses a valid authentication header (sha256)', function (done) {
59
60
var req = {
61
method: 'GET',
62
url: '/resource/1?b=1&a=2',
63
host: 'example.com',
64
port: 8000,
65
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'
66
};
67
68
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
69
70
expect(err).to.not.exist();
71
expect(credentials.user).to.equal('steve');
72
done();
73
});
74
});
75
76
it('parses a valid authentication header (host override)', function (done) {
77
78
var req = {
79
method: 'GET',
80
url: '/resource/4?filter=a',
81
headers: {
82
host: 'example1.com:8080',
83
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
84
}
85
};
86
87
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
88
89
expect(err).to.not.exist();
90
expect(credentials.user).to.equal('steve');
91
done();
92
});
93
});
94
95
it('parses a valid authentication header (host port override)', function (done) {
96
97
var req = {
98
method: 'GET',
99
url: '/resource/4?filter=a',
100
headers: {
101
host: 'example1.com:80',
102
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"'
103
}
104
};
105
106
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
107
108
expect(err).to.not.exist();
109
expect(credentials.user).to.equal('steve');
110
done();
111
});
112
});
113
114
it('parses a valid authentication header (POST with payload)', function (done) {
115
116
var req = {
117
method: 'POST',
118
url: '/resource/4?filter=a',
119
host: 'example.com',
120
port: 8080,
121
authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="'
122
};
123
124
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
125
126
expect(err).to.not.exist();
127
expect(credentials.user).to.equal('steve');
128
done();
129
});
130
});
131
132
it('errors on missing hash', function (done) {
133
134
var req = {
135
method: 'GET',
136
url: '/resource/1?b=1&a=2',
137
host: 'example.com',
138
port: 8000,
139
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"'
140
};
141
142
Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
143
144
expect(err).to.exist();
145
expect(err.output.payload.message).to.equal('Missing required payload hash');
146
done();
147
});
148
});
149
150
it('errors on a stale timestamp', function (done) {
151
152
var req = {
153
method: 'GET',
154
url: '/resource/4?filter=a',
155
host: 'example.com',
156
port: 8080,
157
authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="'
158
};
159
160
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
161
162
expect(err).to.exist();
163
expect(err.output.payload.message).to.equal('Stale timestamp');
164
var header = err.output.headers['WWW-Authenticate'];
165
var ts = header.match(/^Hawk ts\=\"(\d+)\"\, tsm\=\"([^\"]+)\"\, error=\"Stale timestamp\"$/);
166
var now = Hawk.utils.now();
167
expect(parseInt(ts[1], 10) * 1000).to.be.within(now - 1000, now + 1000);
168
169
var res = {
170
headers: {
171
'www-authenticate': header
172
}
173
};
174
175
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true);
176
done();
177
});
178
});
179
180
it('errors on a replay', function (done) {
181
182
var req = {
183
method: 'GET',
184
url: '/resource/4?filter=a',
185
host: 'example.com',
186
port: 8080,
187
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"'
188
};
189
190
var memoryCache = {};
191
var options = {
192
localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(),
193
nonceFunc: function (nonce, ts, callback) {
194
195
if (memoryCache[nonce]) {
196
return callback(new Error());
197
}
198
199
memoryCache[nonce] = true;
200
return callback();
201
}
202
};
203
204
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) {
205
206
expect(err).to.not.exist();
207
expect(credentials.user).to.equal('steve');
208
209
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) {
210
211
expect(err).to.exist();
212
expect(err.output.payload.message).to.equal('Invalid nonce');
213
done();
214
});
215
});
216
});
217
218
it('errors on an invalid authentication header: wrong scheme', function (done) {
219
220
var req = {
221
method: 'GET',
222
url: '/resource/4?filter=a',
223
host: 'example.com',
224
port: 8080,
225
authorization: 'Basic asdasdasdasd'
226
};
227
228
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
229
230
expect(err).to.exist();
231
expect(err.output.payload.message).to.not.exist();
232
done();
233
});
234
});
235
236
it('errors on an invalid authentication header: no scheme', function (done) {
237
238
var req = {
239
method: 'GET',
240
url: '/resource/4?filter=a',
241
host: 'example.com',
242
port: 8080,
243
authorization: '!@#'
244
};
245
246
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
247
248
expect(err).to.exist();
249
expect(err.output.payload.message).to.equal('Invalid header syntax');
250
done();
251
});
252
});
253
254
it('errors on an missing authorization header', function (done) {
255
256
var req = {
257
method: 'GET',
258
url: '/resource/4?filter=a',
259
host: 'example.com',
260
port: 8080
261
};
262
263
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
264
265
expect(err).to.exist();
266
expect(err.isMissing).to.equal(true);
267
done();
268
});
269
});
270
271
it('errors on an missing host header', function (done) {
272
273
var req = {
274
method: 'GET',
275
url: '/resource/4?filter=a',
276
headers: {
277
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
278
}
279
};
280
281
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
282
283
expect(err).to.exist();
284
expect(err.output.payload.message).to.equal('Invalid Host header');
285
done();
286
});
287
});
288
289
it('errors on an missing authorization attribute (id)', function (done) {
290
291
var req = {
292
method: 'GET',
293
url: '/resource/4?filter=a',
294
host: 'example.com',
295
port: 8080,
296
authorization: 'Hawk ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
297
};
298
299
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
300
301
expect(err).to.exist();
302
expect(err.output.payload.message).to.equal('Missing attributes');
303
done();
304
});
305
});
306
307
it('errors on an missing authorization attribute (ts)', function (done) {
308
309
var req = {
310
method: 'GET',
311
url: '/resource/4?filter=a',
312
host: 'example.com',
313
port: 8080,
314
authorization: 'Hawk id="123", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
315
};
316
317
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
318
319
expect(err).to.exist();
320
expect(err.output.payload.message).to.equal('Missing attributes');
321
done();
322
});
323
});
324
325
it('errors on an missing authorization attribute (nonce)', function (done) {
326
327
var req = {
328
method: 'GET',
329
url: '/resource/4?filter=a',
330
host: 'example.com',
331
port: 8080,
332
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
333
};
334
335
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
336
337
expect(err).to.exist();
338
expect(err.output.payload.message).to.equal('Missing attributes');
339
done();
340
});
341
});
342
343
it('errors on an missing authorization attribute (mac)', function (done) {
344
345
var req = {
346
method: 'GET',
347
url: '/resource/4?filter=a',
348
host: 'example.com',
349
port: 8080,
350
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", ext="hello"'
351
};
352
353
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
354
355
expect(err).to.exist();
356
expect(err.output.payload.message).to.equal('Missing attributes');
357
done();
358
});
359
});
360
361
it('errors on an unknown authorization attribute', function (done) {
362
363
var req = {
364
method: 'GET',
365
url: '/resource/4?filter=a',
366
host: 'example.com',
367
port: 8080,
368
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
369
};
370
371
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
372
373
expect(err).to.exist();
374
expect(err.output.payload.message).to.equal('Unknown attribute: x');
375
done();
376
});
377
});
378
379
it('errors on an bad authorization header format', function (done) {
380
381
var req = {
382
method: 'GET',
383
url: '/resource/4?filter=a',
384
host: 'example.com',
385
port: 8080,
386
authorization: 'Hawk id="123\\", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
387
};
388
389
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
390
391
expect(err).to.exist();
392
expect(err.output.payload.message).to.equal('Bad header format');
393
done();
394
});
395
});
396
397
it('errors on an bad authorization attribute value', function (done) {
398
399
var req = {
400
method: 'GET',
401
url: '/resource/4?filter=a',
402
host: 'example.com',
403
port: 8080,
404
authorization: 'Hawk id="\t", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
405
};
406
407
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
408
409
expect(err).to.exist();
410
expect(err.output.payload.message).to.equal('Bad attribute value: id');
411
done();
412
});
413
});
414
415
it('errors on an empty authorization attribute value', function (done) {
416
417
var req = {
418
method: 'GET',
419
url: '/resource/4?filter=a',
420
host: 'example.com',
421
port: 8080,
422
authorization: 'Hawk id="", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
423
};
424
425
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
426
427
expect(err).to.exist();
428
expect(err.output.payload.message).to.equal('Bad attribute value: id');
429
done();
430
});
431
});
432
433
it('errors on duplicated authorization attribute key', function (done) {
434
435
var req = {
436
method: 'GET',
437
url: '/resource/4?filter=a',
438
host: 'example.com',
439
port: 8080,
440
authorization: 'Hawk id="123", id="456", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
441
};
442
443
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
444
445
expect(err).to.exist();
446
expect(err.output.payload.message).to.equal('Duplicate attribute: id');
447
done();
448
});
449
});
450
451
it('errors on an invalid authorization header format', function (done) {
452
453
var req = {
454
method: 'GET',
455
url: '/resource/4?filter=a',
456
host: 'example.com',
457
port: 8080,
458
authorization: 'Hawk'
459
};
460
461
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
462
463
expect(err).to.exist();
464
expect(err.output.payload.message).to.equal('Invalid header syntax');
465
done();
466
});
467
});
468
469
it('errors on an bad host header (missing host)', function (done) {
470
471
var req = {
472
method: 'GET',
473
url: '/resource/4?filter=a',
474
headers: {
475
host: ':8080',
476
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
477
}
478
};
479
480
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
481
482
expect(err).to.exist();
483
expect(err.output.payload.message).to.equal('Invalid Host header');
484
done();
485
});
486
});
487
488
it('errors on an bad host header (pad port)', function (done) {
489
490
var req = {
491
method: 'GET',
492
url: '/resource/4?filter=a',
493
headers: {
494
host: 'example.com:something',
495
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
496
}
497
};
498
499
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
500
501
expect(err).to.exist();
502
expect(err.output.payload.message).to.equal('Invalid Host header');
503
done();
504
});
505
});
506
507
it('errors on credentialsFunc error', function (done) {
508
509
var req = {
510
method: 'GET',
511
url: '/resource/4?filter=a',
512
host: 'example.com',
513
port: 8080,
514
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
515
};
516
517
var credentialsFunc = function (id, callback) {
518
519
return callback(new Error('Unknown user'));
520
};
521
522
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
523
524
expect(err).to.exist();
525
expect(err.message).to.equal('Unknown user');
526
done();
527
});
528
});
529
530
it('errors on credentialsFunc error (with credentials)', function (done) {
531
532
var req = {
533
method: 'GET',
534
url: '/resource/4?filter=a',
535
host: 'example.com',
536
port: 8080,
537
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
538
};
539
540
var credentialsFunc = function (id, callback) {
541
542
return callback(new Error('Unknown user'), { some: 'value' });
543
};
544
545
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
546
547
expect(err).to.exist();
548
expect(err.message).to.equal('Unknown user');
549
expect(credentials.some).to.equal('value');
550
done();
551
});
552
});
553
554
it('errors on missing credentials', function (done) {
555
556
var req = {
557
method: 'GET',
558
url: '/resource/4?filter=a',
559
host: 'example.com',
560
port: 8080,
561
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
562
};
563
564
var credentialsFunc = function (id, callback) {
565
566
return callback(null, null);
567
};
568
569
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
570
571
expect(err).to.exist();
572
expect(err.output.payload.message).to.equal('Unknown credentials');
573
done();
574
});
575
});
576
577
it('errors on invalid credentials (id)', function (done) {
578
579
var req = {
580
method: 'GET',
581
url: '/resource/4?filter=a',
582
host: 'example.com',
583
port: 8080,
584
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
585
};
586
587
var credentialsFunc = function (id, callback) {
588
589
var credentials = {
590
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
591
user: 'steve'
592
};
593
594
return callback(null, credentials);
595
};
596
597
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
598
599
expect(err).to.exist();
600
expect(err.message).to.equal('Invalid credentials');
601
expect(err.output.payload.message).to.equal('An internal server error occurred');
602
done();
603
});
604
});
605
606
it('errors on invalid credentials (key)', function (done) {
607
608
var req = {
609
method: 'GET',
610
url: '/resource/4?filter=a',
611
host: 'example.com',
612
port: 8080,
613
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
614
};
615
616
var credentialsFunc = function (id, callback) {
617
618
var credentials = {
619
id: '23434d3q4d5345d',
620
user: 'steve'
621
};
622
623
return callback(null, credentials);
624
};
625
626
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
627
628
expect(err).to.exist();
629
expect(err.message).to.equal('Invalid credentials');
630
expect(err.output.payload.message).to.equal('An internal server error occurred');
631
done();
632
});
633
});
634
635
it('errors on unknown credentials algorithm', function (done) {
636
637
var req = {
638
method: 'GET',
639
url: '/resource/4?filter=a',
640
host: 'example.com',
641
port: 8080,
642
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
643
};
644
645
var credentialsFunc = function (id, callback) {
646
647
var credentials = {
648
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
649
algorithm: 'hmac-sha-0',
650
user: 'steve'
651
};
652
653
return callback(null, credentials);
654
};
655
656
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
657
658
expect(err).to.exist();
659
expect(err.message).to.equal('Unknown algorithm');
660
expect(err.output.payload.message).to.equal('An internal server error occurred');
661
done();
662
});
663
});
664
665
it('errors on unknown bad mac', function (done) {
666
667
var req = {
668
method: 'GET',
669
url: '/resource/4?filter=a',
670
host: 'example.com',
671
port: 8080,
672
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"'
673
};
674
675
var credentialsFunc = function (id, callback) {
676
677
var credentials = {
678
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
679
algorithm: 'sha256',
680
user: 'steve'
681
};
682
683
return callback(null, credentials);
684
};
685
686
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) {
687
688
expect(err).to.exist();
689
expect(err.output.payload.message).to.equal('Bad mac');
690
done();
691
});
692
});
693
});
694
695
describe('#header', function () {
696
697
it('generates header', function (done) {
698
699
var credentials = {
700
id: '123456',
701
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
702
algorithm: 'sha256',
703
user: 'steve'
704
};
705
706
var artifacts = {
707
method: 'POST',
708
host: 'example.com',
709
port: '8080',
710
resource: '/resource/4?filter=a',
711
ts: '1398546787',
712
nonce: 'xUwusx',
713
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
714
ext: 'some-app-data',
715
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
716
id: '123456'
717
};
718
719
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
720
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');
721
done();
722
});
723
724
it('generates header (empty payload)', function (done) {
725
726
var credentials = {
727
id: '123456',
728
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
729
algorithm: 'sha256',
730
user: 'steve'
731
};
732
733
var artifacts = {
734
method: 'POST',
735
host: 'example.com',
736
port: '8080',
737
resource: '/resource/4?filter=a',
738
ts: '1398546787',
739
nonce: 'xUwusx',
740
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
741
ext: 'some-app-data',
742
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
743
id: '123456'
744
};
745
746
var header = Hawk.server.header(credentials, artifacts, { payload: '', contentType: 'text/plain', ext: 'response-specific' });
747
expect(header).to.equal('Hawk mac=\"i8/kUBDx0QF+PpCtW860kkV/fa9dbwEoe/FpGUXowf0=\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", ext=\"response-specific\"');
748
done();
749
});
750
751
it('generates header (pre calculated hash)', function (done) {
752
753
var credentials = {
754
id: '123456',
755
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
756
algorithm: 'sha256',
757
user: 'steve'
758
};
759
760
var artifacts = {
761
method: 'POST',
762
host: 'example.com',
763
port: '8080',
764
resource: '/resource/4?filter=a',
765
ts: '1398546787',
766
nonce: 'xUwusx',
767
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
768
ext: 'some-app-data',
769
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
770
id: '123456'
771
};
772
773
var options = { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' };
774
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
775
var header = Hawk.server.header(credentials, artifacts, options);
776
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"');
777
done();
778
});
779
780
it('generates header (null ext)', function (done) {
781
782
var credentials = {
783
id: '123456',
784
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
785
algorithm: 'sha256',
786
user: 'steve'
787
};
788
789
var artifacts = {
790
method: 'POST',
791
host: 'example.com',
792
port: '8080',
793
resource: '/resource/4?filter=a',
794
ts: '1398546787',
795
nonce: 'xUwusx',
796
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
797
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
798
id: '123456'
799
};
800
801
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: null });
802
expect(header).to.equal('Hawk mac=\"6PrybJTJs20jsgBw5eilXpcytD8kUbaIKNYXL+6g0ns=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\"');
803
done();
804
});
805
806
it('errors on missing artifacts', function (done) {
807
808
var credentials = {
809
id: '123456',
810
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
811
algorithm: 'sha256',
812
user: 'steve'
813
};
814
815
var header = Hawk.server.header(credentials, null, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
816
expect(header).to.equal('');
817
done();
818
});
819
820
it('errors on invalid artifacts', function (done) {
821
822
var credentials = {
823
id: '123456',
824
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
825
algorithm: 'sha256',
826
user: 'steve'
827
};
828
829
var header = Hawk.server.header(credentials, 5, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
830
expect(header).to.equal('');
831
done();
832
});
833
834
it('errors on missing credentials', function (done) {
835
836
var artifacts = {
837
method: 'POST',
838
host: 'example.com',
839
port: '8080',
840
resource: '/resource/4?filter=a',
841
ts: '1398546787',
842
nonce: 'xUwusx',
843
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
844
ext: 'some-app-data',
845
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
846
id: '123456'
847
};
848
849
var header = Hawk.server.header(null, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
850
expect(header).to.equal('');
851
done();
852
});
853
854
it('errors on invalid credentials (key)', function (done) {
855
856
var credentials = {
857
id: '123456',
858
algorithm: 'sha256',
859
user: 'steve'
860
};
861
862
var artifacts = {
863
method: 'POST',
864
host: 'example.com',
865
port: '8080',
866
resource: '/resource/4?filter=a',
867
ts: '1398546787',
868
nonce: 'xUwusx',
869
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
870
ext: 'some-app-data',
871
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
872
id: '123456'
873
};
874
875
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
876
expect(header).to.equal('');
877
done();
878
});
879
880
it('errors on invalid algorithm', function (done) {
881
882
var credentials = {
883
id: '123456',
884
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
885
algorithm: 'x',
886
user: 'steve'
887
};
888
889
var artifacts = {
890
method: 'POST',
891
host: 'example.com',
892
port: '8080',
893
resource: '/resource/4?filter=a',
894
ts: '1398546787',
895
nonce: 'xUwusx',
896
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
897
ext: 'some-app-data',
898
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=',
899
id: '123456'
900
};
901
902
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
903
expect(header).to.equal('');
904
done();
905
});
906
});
907
908
describe('#authenticateMessage', function () {
909
910
it('errors on invalid authorization (ts)', function (done) {
911
912
credentialsFunc('123456', function (err, credentials) {
913
914
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials });
915
delete auth.ts;
916
917
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) {
918
919
expect(err).to.exist();
920
expect(err.message).to.equal('Invalid authorization');
921
done();
922
});
923
});
924
});
925
926
it('errors on invalid authorization (nonce)', function (done) {
927
928
credentialsFunc('123456', function (err, credentials) {
929
930
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials });
931
delete auth.nonce;
932
933
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) {
934
935
expect(err).to.exist();
936
expect(err.message).to.equal('Invalid authorization');
937
done();
938
});
939
});
940
});
941
942
it('errors on invalid authorization (hash)', function (done) {
943
944
credentialsFunc('123456', function (err, credentials) {
945
946
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials });
947
delete auth.hash;
948
949
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) {
950
951
expect(err).to.exist();
952
expect(err.message).to.equal('Invalid authorization');
953
done();
954
});
955
});
956
});
957
958
it('errors with credentials', function (done) {
959
960
credentialsFunc('123456', function (err, credentials) {
961
962
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials });
963
964
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, function (id, callback) { callback(new Error('something'), { some: 'value' }); }, {}, function (err, credentials) {
965
966
expect(err).to.exist();
967
expect(err.message).to.equal('something');
968
expect(credentials.some).to.equal('value');
969
done();
970
});
971
});
972
});
973
});
974
975
describe('#authenticatePayloadHash', function () {
976
977
it('checks payload hash', function (done) {
978
979
expect(Hawk.server.authenticatePayloadHash('abcdefg', { hash: 'abcdefg' })).to.equal(true);
980
expect(Hawk.server.authenticatePayloadHash('1234567', { hash: 'abcdefg' })).to.equal(false);
981
done();
982
});
983
});
984
});
985
});
986
987