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 Hoek = require('hoek');
7
var Lab = require('lab');
8
var Browser = require('../lib/browser');
9
10
11
// Declare internals
12
13
var internals = {};
14
15
16
// Test shortcuts
17
18
var lab = exports.lab = Lab.script();
19
var describe = lab.experiment;
20
var it = lab.test;
21
var expect = Code.expect;
22
23
24
describe('Browser', 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
it('should generate a bewit then successfully authenticate it', function (done) {
39
40
var req = {
41
method: 'GET',
42
url: '/resource/4?a=1&b=2',
43
host: 'example.com',
44
port: 80
45
};
46
47
credentialsFunc('123456', function (err, credentials) {
48
49
var bewit = Browser.client.bewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100, ext: 'some-app-data' });
50
req.url += '&bewit=' + bewit;
51
52
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
53
54
expect(err).to.not.exist();
55
expect(credentials.user).to.equal('steve');
56
expect(attributes.ext).to.equal('some-app-data');
57
done();
58
});
59
});
60
});
61
62
it('should generate a bewit then successfully authenticate it (no ext)', function (done) {
63
64
var req = {
65
method: 'GET',
66
url: '/resource/4?a=1&b=2',
67
host: 'example.com',
68
port: 80
69
};
70
71
credentialsFunc('123456', function (err, credentials) {
72
73
var bewit = Browser.client.bewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100 });
74
req.url += '&bewit=' + bewit;
75
76
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
77
78
expect(err).to.not.exist();
79
expect(credentials.user).to.equal('steve');
80
done();
81
});
82
});
83
});
84
85
describe('#bewit', function () {
86
87
it('returns a valid bewit value', function (done) {
88
89
var credentials = {
90
id: '123456',
91
key: '2983d45yun89q',
92
algorithm: 'sha256'
93
};
94
95
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
96
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdca3NjeHdOUjJ0SnBQMVQxekRMTlBiQjVVaUtJVTl0T1NKWFRVZEc3WDloOD1ceGFuZHlhbmR6');
97
done();
98
});
99
100
it('returns a valid bewit value (explicit HTTP port)', function (done) {
101
102
var credentials = {
103
id: '123456',
104
key: '2983d45yun89q',
105
algorithm: 'sha256'
106
};
107
108
var bewit = Browser.client.bewit('http://example.com:8080/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
109
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcaFpiSjNQMmNLRW80a3kwQzhqa1pBa1J5Q1p1ZWc0V1NOYnhWN3ZxM3hIVT1ceGFuZHlhbmR6');
110
done();
111
});
112
113
it('returns a valid bewit value (explicit HTTPS port)', function (done) {
114
115
var credentials = {
116
id: '123456',
117
key: '2983d45yun89q',
118
algorithm: 'sha256'
119
};
120
121
var bewit = Browser.client.bewit('https://example.com:8043/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
122
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcL2t4UjhwK0xSaTdvQTRnUXc3cWlxa3BiVHRKYkR4OEtRMC9HRUwvVytTUT1ceGFuZHlhbmR6');
123
done();
124
});
125
126
it('returns a valid bewit value (null ext)', function (done) {
127
128
var credentials = {
129
id: '123456',
130
key: '2983d45yun89q',
131
algorithm: 'sha256'
132
};
133
134
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: null });
135
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcSUdZbUxnSXFMckNlOEN4dktQczRKbFdJQStValdKSm91d2dBUmlWaENBZz1c');
136
done();
137
});
138
139
it('errors on invalid options', function (done) {
140
141
var credentials = {
142
id: '123456',
143
key: '2983d45yun89q',
144
algorithm: 'sha256'
145
};
146
147
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', 4);
148
expect(bewit).to.equal('');
149
done();
150
});
151
152
it('errors on missing uri', function (done) {
153
154
var credentials = {
155
id: '123456',
156
key: '2983d45yun89q',
157
algorithm: 'sha256'
158
};
159
160
var bewit = Browser.client.bewit('', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
161
expect(bewit).to.equal('');
162
done();
163
});
164
165
it('errors on invalid uri', function (done) {
166
167
var credentials = {
168
id: '123456',
169
key: '2983d45yun89q',
170
algorithm: 'sha256'
171
};
172
173
var bewit = Browser.client.bewit(5, { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
174
expect(bewit).to.equal('');
175
done();
176
});
177
178
it('errors on invalid credentials (id)', function (done) {
179
180
var credentials = {
181
key: '2983d45yun89q',
182
algorithm: 'sha256'
183
};
184
185
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
186
expect(bewit).to.equal('');
187
done();
188
});
189
190
it('errors on missing credentials', function (done) {
191
192
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { ttlSec: 3000, ext: 'xandyandz' });
193
expect(bewit).to.equal('');
194
done();
195
});
196
197
it('errors on invalid credentials (key)', function (done) {
198
199
var credentials = {
200
id: '123456',
201
algorithm: 'sha256'
202
};
203
204
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
205
expect(bewit).to.equal('');
206
done();
207
});
208
209
it('errors on invalid algorithm', function (done) {
210
211
var credentials = {
212
id: '123456',
213
key: '2983d45yun89q',
214
algorithm: 'hmac-sha-0'
215
};
216
217
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, ext: 'xandyandz' });
218
expect(bewit).to.equal('');
219
done();
220
});
221
222
it('errors on missing options', function (done) {
223
224
var credentials = {
225
id: '123456',
226
key: '2983d45yun89q',
227
algorithm: 'hmac-sha-0'
228
};
229
230
var bewit = Browser.client.bewit('https://example.com/somewhere/over/the/rainbow');
231
expect(bewit).to.equal('');
232
done();
233
});
234
});
235
236
it('generates a header then successfully parse it (configuration)', function (done) {
237
238
var req = {
239
method: 'GET',
240
url: '/resource/4?filter=a',
241
host: 'example.com',
242
port: 8080
243
};
244
245
credentialsFunc('123456', function (err, credentials) {
246
247
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
248
expect(req.authorization).to.exist();
249
250
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
251
252
expect(err).to.not.exist();
253
expect(credentials.user).to.equal('steve');
254
expect(artifacts.ext).to.equal('some-app-data');
255
done();
256
});
257
});
258
});
259
260
it('generates a header then successfully parse it (node request)', function (done) {
261
262
var req = {
263
method: 'POST',
264
url: '/resource/4?filter=a',
265
headers: {
266
host: 'example.com:8080',
267
'content-type': 'text/plain;x=y'
268
}
269
};
270
271
var payload = 'some not so random text';
272
273
credentialsFunc('123456', function (err, credentials) {
274
275
var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
276
req.headers.authorization = reqHeader.field;
277
278
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
279
280
expect(err).to.not.exist();
281
expect(credentials.user).to.equal('steve');
282
expect(artifacts.ext).to.equal('some-app-data');
283
expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
284
285
var res = {
286
headers: {
287
'content-type': 'text/plain'
288
},
289
getResponseHeader: function (header) {
290
291
return res.headers[header.toLowerCase()];
292
}
293
};
294
295
res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
296
expect(res.headers['server-authorization']).to.exist();
297
298
expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(true);
299
done();
300
});
301
});
302
});
303
304
it('generates a header then successfully parse it (browserify)', function (done) {
305
306
var req = {
307
method: 'POST',
308
url: '/resource/4?filter=a',
309
headers: {
310
host: 'example.com:8080',
311
'content-type': 'text/plain;x=y'
312
}
313
};
314
315
var payload = 'some not so random text';
316
317
credentialsFunc('123456', function (err, credentials) {
318
319
var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
320
req.headers.authorization = reqHeader.field;
321
322
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
323
324
expect(err).to.not.exist();
325
expect(credentials.user).to.equal('steve');
326
expect(artifacts.ext).to.equal('some-app-data');
327
expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
328
329
var res = {
330
headers: {
331
'content-type': 'text/plain'
332
},
333
getHeader: function (header) {
334
335
return res.headers[header.toLowerCase()];
336
}
337
};
338
339
res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
340
expect(res.headers['server-authorization']).to.exist();
341
342
expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(true);
343
done();
344
});
345
});
346
});
347
348
it('generates a header then successfully parse it (time offset)', function (done) {
349
350
var req = {
351
method: 'GET',
352
url: '/resource/4?filter=a',
353
host: 'example.com',
354
port: 8080
355
};
356
357
credentialsFunc('123456', function (err, credentials) {
358
359
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', localtimeOffsetMsec: 100000 }).field;
360
expect(req.authorization).to.exist();
361
362
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials, artifacts) {
363
364
expect(err).to.not.exist();
365
expect(credentials.user).to.equal('steve');
366
expect(artifacts.ext).to.equal('some-app-data');
367
done();
368
});
369
});
370
});
371
372
it('generates a header then successfully parse it (no server header options)', function (done) {
373
374
var req = {
375
method: 'POST',
376
url: '/resource/4?filter=a',
377
headers: {
378
host: 'example.com:8080',
379
'content-type': 'text/plain;x=y'
380
}
381
};
382
383
var payload = 'some not so random text';
384
385
credentialsFunc('123456', function (err, credentials) {
386
387
var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
388
req.headers.authorization = reqHeader.field;
389
390
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
391
392
expect(err).to.not.exist();
393
expect(credentials.user).to.equal('steve');
394
expect(artifacts.ext).to.equal('some-app-data');
395
expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
396
397
var res = {
398
headers: {
399
'content-type': 'text/plain'
400
},
401
getResponseHeader: function (header) {
402
403
return res.headers[header.toLowerCase()];
404
}
405
};
406
407
res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts);
408
expect(res.headers['server-authorization']).to.exist();
409
410
expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
411
done();
412
});
413
});
414
});
415
416
it('generates a header then successfully parse it (no server header)', function (done) {
417
418
var req = {
419
method: 'POST',
420
url: '/resource/4?filter=a',
421
headers: {
422
host: 'example.com:8080',
423
'content-type': 'text/plain;x=y'
424
}
425
};
426
427
var payload = 'some not so random text';
428
429
credentialsFunc('123456', function (err, credentials) {
430
431
var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
432
req.headers.authorization = reqHeader.field;
433
434
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
435
436
expect(err).to.not.exist();
437
expect(credentials.user).to.equal('steve');
438
expect(artifacts.ext).to.equal('some-app-data');
439
expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
440
441
var res = {
442
headers: {
443
'content-type': 'text/plain'
444
},
445
getResponseHeader: function (header) {
446
447
return res.headers[header.toLowerCase()];
448
}
449
};
450
451
expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
452
done();
453
});
454
});
455
});
456
457
it('generates a header with stale ts and successfully authenticate on second call', function (done) {
458
459
var req = {
460
method: 'GET',
461
url: '/resource/4?filter=a',
462
host: 'example.com',
463
port: 8080
464
};
465
466
credentialsFunc('123456', function (err, credentials) {
467
468
Browser.utils.setNtpOffset(60 * 60 * 1000);
469
var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' });
470
req.authorization = header.field;
471
expect(req.authorization).to.exist();
472
473
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
474
475
expect(err).to.exist();
476
expect(err.message).to.equal('Stale timestamp');
477
478
var res = {
479
headers: {
480
'www-authenticate': err.output.headers['WWW-Authenticate']
481
},
482
getResponseHeader: function (header) {
483
484
return res.headers[header.toLowerCase()];
485
}
486
};
487
488
expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000);
489
expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true);
490
expect(Browser.utils.getNtpOffset()).to.equal(0);
491
492
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
493
expect(req.authorization).to.exist();
494
495
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
496
497
expect(err).to.not.exist();
498
expect(credentials.user).to.equal('steve');
499
expect(artifacts.ext).to.equal('some-app-data');
500
done();
501
});
502
});
503
});
504
});
505
506
it('generates a header with stale ts and successfully authenticate on second call (manual localStorage)', function (done) {
507
508
var req = {
509
method: 'GET',
510
url: '/resource/4?filter=a',
511
host: 'example.com',
512
port: 8080
513
};
514
515
credentialsFunc('123456', function (err, credentials) {
516
517
var localStorage = new Browser.internals.LocalStorage();
518
519
Browser.utils.setStorage(localStorage)
520
521
Browser.utils.setNtpOffset(60 * 60 * 1000);
522
var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' });
523
req.authorization = header.field;
524
expect(req.authorization).to.exist();
525
526
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
527
528
expect(err).to.exist();
529
expect(err.message).to.equal('Stale timestamp');
530
531
var res = {
532
headers: {
533
'www-authenticate': err.output.headers['WWW-Authenticate']
534
},
535
getResponseHeader: function (header) {
536
537
return res.headers[header.toLowerCase()];
538
}
539
};
540
541
expect(parseInt(localStorage.getItem('hawk_ntp_offset'))).to.equal(60 * 60 * 1000);
542
expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000);
543
expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true);
544
expect(Browser.utils.getNtpOffset()).to.equal(0);
545
expect(parseInt(localStorage.getItem('hawk_ntp_offset'))).to.equal(0);
546
547
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
548
expect(req.authorization).to.exist();
549
550
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
551
552
expect(err).to.not.exist();
553
expect(credentials.user).to.equal('steve');
554
expect(artifacts.ext).to.equal('some-app-data');
555
done();
556
});
557
});
558
});
559
});
560
561
it('generates a header then fails to parse it (missing server header hash)', function (done) {
562
563
var req = {
564
method: 'POST',
565
url: '/resource/4?filter=a',
566
headers: {
567
host: 'example.com:8080',
568
'content-type': 'text/plain;x=y'
569
}
570
};
571
572
var payload = 'some not so random text';
573
574
credentialsFunc('123456', function (err, credentials) {
575
576
var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
577
req.headers.authorization = reqHeader.field;
578
579
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
580
581
expect(err).to.not.exist();
582
expect(credentials.user).to.equal('steve');
583
expect(artifacts.ext).to.equal('some-app-data');
584
expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
585
586
var res = {
587
headers: {
588
'content-type': 'text/plain'
589
},
590
getResponseHeader: function (header) {
591
592
return res.headers[header.toLowerCase()];
593
}
594
};
595
596
res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts);
597
expect(res.headers['server-authorization']).to.exist();
598
599
expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(false);
600
done();
601
});
602
});
603
});
604
605
it('generates a header then successfully parse it (with hash)', function (done) {
606
607
var req = {
608
method: 'GET',
609
url: '/resource/4?filter=a',
610
host: 'example.com',
611
port: 8080
612
};
613
614
credentialsFunc('123456', function (err, credentials) {
615
616
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
617
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
618
619
expect(err).to.not.exist();
620
expect(credentials.user).to.equal('steve');
621
expect(artifacts.ext).to.equal('some-app-data');
622
done();
623
});
624
});
625
});
626
627
it('generates a header then successfully parse it then validate payload', function (done) {
628
629
var req = {
630
method: 'GET',
631
url: '/resource/4?filter=a',
632
host: 'example.com',
633
port: 8080
634
};
635
636
credentialsFunc('123456', function (err, credentials) {
637
638
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
639
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
640
641
expect(err).to.not.exist();
642
expect(credentials.user).to.equal('steve');
643
expect(artifacts.ext).to.equal('some-app-data');
644
expect(Hawk.server.authenticatePayload('hola!', credentials, artifacts)).to.be.true();
645
expect(Hawk.server.authenticatePayload('hello!', credentials, artifacts)).to.be.false();
646
done();
647
});
648
});
649
});
650
651
it('generates a header then successfully parse it (app)', function (done) {
652
653
var req = {
654
method: 'GET',
655
url: '/resource/4?filter=a',
656
host: 'example.com',
657
port: 8080
658
};
659
660
credentialsFunc('123456', function (err, credentials) {
661
662
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased' }).field;
663
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
664
665
expect(err).to.not.exist();
666
expect(credentials.user).to.equal('steve');
667
expect(artifacts.ext).to.equal('some-app-data');
668
expect(artifacts.app).to.equal('asd23ased');
669
done();
670
});
671
});
672
});
673
674
it('generates a header then successfully parse it (app, dlg)', function (done) {
675
676
var req = {
677
method: 'GET',
678
url: '/resource/4?filter=a',
679
host: 'example.com',
680
port: 8080
681
};
682
683
credentialsFunc('123456', function (err, credentials) {
684
685
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased', dlg: '23434szr3q4d' }).field;
686
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
687
688
expect(err).to.not.exist();
689
expect(credentials.user).to.equal('steve');
690
expect(artifacts.ext).to.equal('some-app-data');
691
expect(artifacts.app).to.equal('asd23ased');
692
expect(artifacts.dlg).to.equal('23434szr3q4d');
693
done();
694
});
695
});
696
});
697
698
it('generates a header then fail authentication due to bad hash', function (done) {
699
700
var req = {
701
method: 'GET',
702
url: '/resource/4?filter=a',
703
host: 'example.com',
704
port: 8080
705
};
706
707
credentialsFunc('123456', function (err, credentials) {
708
709
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
710
Hawk.server.authenticate(req, credentialsFunc, { payload: 'byebye!' }, function (err, credentials, artifacts) {
711
712
expect(err).to.exist();
713
expect(err.output.payload.message).to.equal('Bad payload hash');
714
done();
715
});
716
});
717
});
718
719
it('generates a header for one resource then fail to authenticate another', function (done) {
720
721
var req = {
722
method: 'GET',
723
url: '/resource/4?filter=a',
724
host: 'example.com',
725
port: 8080
726
};
727
728
credentialsFunc('123456', function (err, credentials) {
729
730
req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
731
req.url = '/something/else';
732
733
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
734
735
expect(err).to.exist();
736
expect(credentials).to.exist();
737
done();
738
});
739
});
740
});
741
742
describe('client', function () {
743
744
describe('#header', function () {
745
746
it('returns a valid authorization header (sha1)', function (done) {
747
748
var credentials = {
749
id: '123456',
750
key: '2983d45yun89q',
751
algorithm: 'sha1'
752
};
753
754
var header = Browser.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field;
755
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="');
756
done();
757
});
758
759
it('returns a valid authorization header (sha256)', function (done) {
760
761
var credentials = {
762
id: '123456',
763
key: '2983d45yun89q',
764
algorithm: 'sha256'
765
};
766
767
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
768
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="');
769
done();
770
});
771
772
it('returns a valid authorization header (empty payload)', function (done) {
773
774
var credentials = {
775
id: '123456',
776
key: '2983d45yun89q',
777
algorithm: 'sha1'
778
};
779
780
var header = Browser.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: '' }).field;
781
expect(header).to.equal('Hawk id=\"123456\", ts=\"1353809207\", nonce=\"Ygvqdz\", hash=\"404ghL7K+hfyhByKKejFBRGgTjU=\", ext=\"Bazinga!\", mac=\"Bh1sj1DOfFRWOdi3ww52nLCJdBE=\"');
782
done();
783
});
784
785
it('returns a valid authorization header (no ext)', function (done) {
786
787
var credentials = {
788
id: '123456',
789
key: '2983d45yun89q',
790
algorithm: 'sha256'
791
};
792
793
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
794
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
795
done();
796
});
797
798
it('returns a valid authorization header (null ext)', function (done) {
799
800
var credentials = {
801
id: '123456',
802
key: '2983d45yun89q',
803
algorithm: 'sha256'
804
};
805
806
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain', ext: null }).field;
807
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
808
done();
809
});
810
811
it('returns a valid authorization header (uri object)', function (done) {
812
813
var credentials = {
814
id: '123456',
815
key: '2983d45yun89q',
816
algorithm: 'sha256'
817
};
818
819
var uri = Browser.utils.parseUri('https://example.net/somewhere/over/the/rainbow');
820
var header = Browser.client.header(uri, 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
821
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
822
done();
823
});
824
825
it('errors on missing options', function (done) {
826
827
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST');
828
expect(header.field).to.equal('');
829
expect(header.err).to.equal('Invalid argument type');
830
done();
831
});
832
833
it('errors on empty uri', function (done) {
834
835
var credentials = {
836
id: '123456',
837
key: '2983d45yun89q',
838
algorithm: 'sha256'
839
};
840
841
var header = Browser.client.header('', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' });
842
expect(header.field).to.equal('');
843
expect(header.err).to.equal('Invalid argument type');
844
done();
845
});
846
847
it('errors on invalid uri', function (done) {
848
849
var credentials = {
850
id: '123456',
851
key: '2983d45yun89q',
852
algorithm: 'sha256'
853
};
854
855
var header = Browser.client.header(4, 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' });
856
expect(header.field).to.equal('');
857
expect(header.err).to.equal('Invalid argument type');
858
done();
859
});
860
861
it('errors on missing method', function (done) {
862
863
var credentials = {
864
id: '123456',
865
key: '2983d45yun89q',
866
algorithm: 'sha256'
867
};
868
869
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', '', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' });
870
expect(header.field).to.equal('');
871
expect(header.err).to.equal('Invalid argument type');
872
done();
873
});
874
875
it('errors on invalid method', function (done) {
876
877
var credentials = {
878
id: '123456',
879
key: '2983d45yun89q',
880
algorithm: 'sha256'
881
};
882
883
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 5, { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' });
884
expect(header.field).to.equal('');
885
expect(header.err).to.equal('Invalid argument type');
886
done();
887
});
888
889
it('errors on missing credentials', function (done) {
890
891
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { ext: 'Bazinga!', timestamp: 1353809207 });
892
expect(header.field).to.equal('');
893
expect(header.err).to.equal('Invalid credentials object');
894
done();
895
});
896
897
it('errors on invalid credentials (id)', function (done) {
898
899
var credentials = {
900
key: '2983d45yun89q',
901
algorithm: 'sha256'
902
};
903
904
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 });
905
expect(header.field).to.equal('');
906
expect(header.err).to.equal('Invalid credentials object');
907
done();
908
});
909
910
it('errors on invalid credentials (key)', function (done) {
911
912
var credentials = {
913
id: '123456',
914
algorithm: 'sha256'
915
};
916
917
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 });
918
expect(header.field).to.equal('');
919
expect(header.err).to.equal('Invalid credentials object');
920
done();
921
});
922
923
it('errors on invalid algorithm', function (done) {
924
925
var credentials = {
926
id: '123456',
927
key: '2983d45yun89q',
928
algorithm: 'hmac-sha-0'
929
};
930
931
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 });
932
expect(header.field).to.equal('');
933
expect(header.err).to.equal('Unknown algorithm');
934
done();
935
});
936
937
it('uses a pre-calculated payload hash', function (done) {
938
939
var credentials = {
940
id: '123456',
941
key: '2983d45yun89q',
942
algorithm: 'sha256'
943
};
944
945
var options = { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' };
946
options.hash = Browser.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
947
var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', options).field;
948
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="');
949
done();
950
});
951
});
952
953
describe('#authenticate', function () {
954
955
it('skips tsm validation when missing ts', function (done) {
956
957
var res = {
958
headers: {
959
'www-authenticate': 'Hawk error="Stale timestamp"'
960
},
961
getResponseHeader: function (header) {
962
963
return res.headers[header.toLowerCase()];
964
}
965
};
966
967
var credentials = {
968
id: '123456',
969
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
970
algorithm: 'sha256',
971
user: 'steve'
972
};
973
974
var artifacts = {
975
ts: 1402135580,
976
nonce: 'iBRB6t',
977
method: 'GET',
978
resource: '/resource/4?filter=a',
979
host: 'example.com',
980
port: '8080',
981
ext: 'some-app-data'
982
};
983
984
expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
985
done();
986
});
987
988
it('returns false on invalid header', function (done) {
989
990
var res = {
991
headers: {
992
'server-authorization': 'Hawk mac="abc", bad="xyz"'
993
},
994
getResponseHeader: function (header) {
995
996
return res.headers[header.toLowerCase()];
997
}
998
};
999
1000
expect(Browser.client.authenticate(res, {})).to.equal(false);
1001
done();
1002
});
1003
1004
it('returns false on invalid mac', function (done) {
1005
1006
var res = {
1007
headers: {
1008
'content-type': 'text/plain',
1009
'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
1010
},
1011
getResponseHeader: function (header) {
1012
1013
return res.headers[header.toLowerCase()];
1014
}
1015
};
1016
1017
var artifacts = {
1018
method: 'POST',
1019
host: 'example.com',
1020
port: '8080',
1021
resource: '/resource/4?filter=a',
1022
ts: '1362336900',
1023
nonce: 'eb5S_L',
1024
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
1025
ext: 'some-app-data',
1026
app: undefined,
1027
dlg: undefined,
1028
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
1029
id: '123456'
1030
};
1031
1032
var credentials = {
1033
id: '123456',
1034
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
1035
algorithm: 'sha256',
1036
user: 'steve'
1037
};
1038
1039
expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(false);
1040
done();
1041
});
1042
1043
it('returns true on ignoring hash', function (done) {
1044
1045
var res = {
1046
headers: {
1047
'content-type': 'text/plain',
1048
'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
1049
},
1050
getResponseHeader: function (header) {
1051
1052
return res.headers[header.toLowerCase()];
1053
}
1054
};
1055
1056
var artifacts = {
1057
method: 'POST',
1058
host: 'example.com',
1059
port: '8080',
1060
resource: '/resource/4?filter=a',
1061
ts: '1362336900',
1062
nonce: 'eb5S_L',
1063
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
1064
ext: 'some-app-data',
1065
app: undefined,
1066
dlg: undefined,
1067
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
1068
id: '123456'
1069
};
1070
1071
var credentials = {
1072
id: '123456',
1073
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
1074
algorithm: 'sha256',
1075
user: 'steve'
1076
};
1077
1078
expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
1079
done();
1080
});
1081
1082
it('errors on invalid WWW-Authenticate header format', function (done) {
1083
1084
var res = {
1085
headers: {
1086
'www-authenticate': 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"'
1087
},
1088
getResponseHeader: function (header) {
1089
1090
return res.headers[header.toLowerCase()];
1091
}
1092
};
1093
1094
expect(Browser.client.authenticate(res, {})).to.equal(false);
1095
done();
1096
});
1097
1098
it('errors on invalid WWW-Authenticate header format', function (done) {
1099
1100
var credentials = {
1101
id: '123456',
1102
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
1103
algorithm: 'sha256',
1104
user: 'steve'
1105
};
1106
1107
var res = {
1108
headers: {
1109
'www-authenticate': 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"'
1110
},
1111
getResponseHeader: function (header) {
1112
1113
return res.headers[header.toLowerCase()];
1114
}
1115
};
1116
1117
expect(Browser.client.authenticate(res, credentials)).to.equal(false);
1118
done();
1119
});
1120
});
1121
1122
describe('#message', function () {
1123
1124
it('generates an authorization then successfully parse it', function (done) {
1125
1126
credentialsFunc('123456', function (err, credentials) {
1127
1128
var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: credentials });
1129
expect(auth).to.exist();
1130
1131
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) {
1132
1133
expect(err).to.not.exist();
1134
expect(credentials.user).to.equal('steve');
1135
done();
1136
});
1137
});
1138
});
1139
1140
it('generates an authorization using custom nonce/timestamp', function (done) {
1141
1142
credentialsFunc('123456', function (err, credentials) {
1143
1144
var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: credentials, nonce: 'abc123', timestamp: 1398536270957 });
1145
expect(auth).to.exist();
1146
expect(auth.nonce).to.equal('abc123');
1147
expect(auth.ts).to.equal(1398536270957);
1148
done();
1149
});
1150
});
1151
1152
it('errors on missing host', function (done) {
1153
1154
credentialsFunc('123456', function (err, credentials) {
1155
1156
var auth = Browser.client.message(null, 8080, 'some message', { credentials: credentials });
1157
expect(auth).to.not.exist();
1158
done();
1159
});
1160
});
1161
1162
it('errors on invalid host', function (done) {
1163
1164
credentialsFunc('123456', function (err, credentials) {
1165
1166
var auth = Browser.client.message(5, 8080, 'some message', { credentials: credentials });
1167
expect(auth).to.not.exist();
1168
done();
1169
});
1170
});
1171
1172
it('errors on missing port', function (done) {
1173
1174
credentialsFunc('123456', function (err, credentials) {
1175
1176
var auth = Browser.client.message('example.com', 0, 'some message', { credentials: credentials });
1177
expect(auth).to.not.exist();
1178
done();
1179
});
1180
});
1181
1182
it('errors on invalid port', function (done) {
1183
1184
credentialsFunc('123456', function (err, credentials) {
1185
1186
var auth = Browser.client.message('example.com', 'a', 'some message', { credentials: credentials });
1187
expect(auth).to.not.exist();
1188
done();
1189
});
1190
});
1191
1192
it('errors on missing message', function (done) {
1193
1194
credentialsFunc('123456', function (err, credentials) {
1195
1196
var auth = Browser.client.message('example.com', 8080, undefined, { credentials: credentials });
1197
expect(auth).to.not.exist();
1198
done();
1199
});
1200
});
1201
1202
it('errors on null message', function (done) {
1203
1204
credentialsFunc('123456', function (err, credentials) {
1205
1206
var auth = Browser.client.message('example.com', 8080, null, { credentials: credentials });
1207
expect(auth).to.not.exist();
1208
done();
1209
});
1210
});
1211
1212
it('errors on invalid message', function (done) {
1213
1214
credentialsFunc('123456', function (err, credentials) {
1215
1216
var auth = Browser.client.message('example.com', 8080, 5, { credentials: credentials });
1217
expect(auth).to.not.exist();
1218
done();
1219
});
1220
});
1221
1222
it('errors on missing credentials', function (done) {
1223
1224
var auth = Browser.client.message('example.com', 8080, 'some message', {});
1225
expect(auth).to.not.exist();
1226
done();
1227
});
1228
1229
it('errors on missing options', function (done) {
1230
1231
var auth = Browser.client.message('example.com', 8080, 'some message');
1232
expect(auth).to.not.exist();
1233
done();
1234
});
1235
1236
it('errors on invalid credentials (id)', function (done) {
1237
1238
credentialsFunc('123456', function (err, credentials) {
1239
1240
var creds = Hoek.clone(credentials);
1241
delete creds.id;
1242
var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: creds });
1243
expect(auth).to.not.exist();
1244
done();
1245
});
1246
});
1247
1248
it('errors on invalid credentials (key)', function (done) {
1249
1250
credentialsFunc('123456', function (err, credentials) {
1251
1252
var creds = Hoek.clone(credentials);
1253
delete creds.key;
1254
var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: creds });
1255
expect(auth).to.not.exist();
1256
done();
1257
});
1258
});
1259
1260
it('errors on invalid algorithm', function (done) {
1261
1262
credentialsFunc('123456', function (err, credentials) {
1263
1264
var creds = Hoek.clone(credentials);
1265
creds.algorithm = 'blah';
1266
var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: creds });
1267
expect(auth).to.not.exist();
1268
done();
1269
});
1270
});
1271
});
1272
1273
describe('#authenticateTimestamp', function (done) {
1274
1275
it('validates a timestamp', function (done) {
1276
1277
credentialsFunc('123456', function (err, credentials) {
1278
1279
var tsm = Hawk.crypto.timestampMessage(credentials);
1280
expect(Browser.client.authenticateTimestamp(tsm, credentials)).to.equal(true);
1281
done();
1282
});
1283
});
1284
1285
it('validates a timestamp without updating local time', function (done) {
1286
1287
credentialsFunc('123456', function (err, credentials) {
1288
1289
var offset = Browser.utils.getNtpOffset();
1290
var tsm = Hawk.crypto.timestampMessage(credentials, 10000);
1291
expect(Browser.client.authenticateTimestamp(tsm, credentials, false)).to.equal(true);
1292
expect(offset).to.equal(Browser.utils.getNtpOffset());
1293
done();
1294
});
1295
});
1296
1297
it('detects a bad timestamp', function (done) {
1298
1299
credentialsFunc('123456', function (err, credentials) {
1300
1301
var tsm = Hawk.crypto.timestampMessage(credentials);
1302
tsm.ts = 4;
1303
expect(Browser.client.authenticateTimestamp(tsm, credentials)).to.equal(false);
1304
done();
1305
});
1306
});
1307
});
1308
});
1309
1310
describe('internals', function () {
1311
1312
describe('LocalStorage', function () {
1313
1314
it('goes through the full lifecycle', function (done) {
1315
1316
var storage = new Browser.internals.LocalStorage();
1317
expect(storage.length).to.equal(0);
1318
expect(storage.getItem('a')).to.equal(null);
1319
storage.setItem('a', 5);
1320
expect(storage.length).to.equal(1);
1321
expect(storage.key()).to.equal('a');
1322
expect(storage.key(0)).to.equal('a');
1323
expect(storage.getItem('a')).to.equal('5');
1324
storage.setItem('b', 'test');
1325
expect(storage.key()).to.equal('a');
1326
expect(storage.key(0)).to.equal('a');
1327
expect(storage.key(1)).to.equal('b');
1328
expect(storage.length).to.equal(2);
1329
expect(storage.getItem('b')).to.equal('test');
1330
storage.removeItem('a');
1331
expect(storage.length).to.equal(1);
1332
expect(storage.getItem('a')).to.equal(null);
1333
expect(storage.getItem('b')).to.equal('test');
1334
storage.clear();
1335
expect(storage.length).to.equal(0);
1336
expect(storage.getItem('a')).to.equal(null);
1337
expect(storage.getItem('b')).to.equal(null);
1338
done();
1339
});
1340
});
1341
});
1342
1343
describe('utils', function () {
1344
1345
describe('#setStorage', function () {
1346
1347
it('sets storage for the first time', function (done) {
1348
1349
Browser.utils.storage = new Browser.internals.LocalStorage(); // Reset state
1350
1351
expect(Browser.utils.storage.getItem('hawk_ntp_offset')).to.not.exist();
1352
Browser.utils.storage.setItem('test', '1');
1353
Browser.utils.setStorage(new Browser.internals.LocalStorage());
1354
expect(Browser.utils.storage.getItem('test')).to.not.exist();
1355
Browser.utils.storage.setItem('test', '2');
1356
expect(Browser.utils.storage.getItem('test')).to.equal('2');
1357
done();
1358
});
1359
});
1360
1361
describe('#setNtpOffset', function (done) {
1362
1363
it('catches localStorage errors', function (done) {
1364
1365
var orig = Browser.utils.storage.setItem;
1366
var error = console.error;
1367
var count = 0;
1368
console.error = function () { if (count++ === 2) { console.error = error; } };
1369
Browser.utils.storage.setItem = function () {
1370
1371
Browser.utils.storage.setItem = orig;
1372
throw new Error()
1373
};
1374
1375
expect(function () {
1376
Browser.utils.setNtpOffset(100);
1377
}).not.to.throw();
1378
1379
done();
1380
});
1381
});
1382
1383
describe('#parseAuthorizationHeader', function (done) {
1384
1385
it('returns null on missing header', function (done) {
1386
1387
expect(Browser.utils.parseAuthorizationHeader()).to.equal(null);
1388
done();
1389
});
1390
1391
it('returns null on bad header syntax (structure)', function (done) {
1392
1393
expect(Browser.utils.parseAuthorizationHeader('Hawk')).to.equal(null);
1394
done();
1395
});
1396
1397
it('returns null on bad header syntax (parts)', function (done) {
1398
1399
expect(Browser.utils.parseAuthorizationHeader(' ')).to.equal(null);
1400
done();
1401
});
1402
1403
it('returns null on bad scheme name', function (done) {
1404
1405
expect(Browser.utils.parseAuthorizationHeader('Basic asdasd')).to.equal(null);
1406
done();
1407
});
1408
1409
it('returns null on bad attribute value', function (done) {
1410
1411
expect(Browser.utils.parseAuthorizationHeader('Hawk test="\t"', ['test'])).to.equal(null);
1412
done();
1413
});
1414
1415
it('returns null on duplicated attribute', function (done) {
1416
1417
expect(Browser.utils.parseAuthorizationHeader('Hawk test="a", test="b"', ['test'])).to.equal(null);
1418
done();
1419
});
1420
});
1421
1422
describe('#parseUri', function () {
1423
1424
it('returns empty port when unknown scheme', function (done) {
1425
1426
var uri = Browser.utils.parseUri('ftp://domain');
1427
expect(uri.port).to.equal('');
1428
done();
1429
});
1430
1431
it('returns default port when missing', function (done) {
1432
1433
var uri = Browser.utils.parseUri('http://');
1434
expect(uri.port).to.equal('80');
1435
done();
1436
});
1437
});
1438
1439
var str = "https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=url";
1440
var base64str = "aHR0cHM6Ly93d3cuZ29vZ2xlLmNhL3dlYmhwP3NvdXJjZWlkPWNocm9tZS1pbnN0YW50Jmlvbj0xJmVzcHY9MiZpZT1VVEYtOCNxPXVybA";
1441
1442
describe('#base64urlEncode', function () {
1443
1444
it('should base64 URL-safe decode a string', function (done) {
1445
1446
expect(Browser.utils.base64urlEncode(str)).to.equal(base64str);
1447
done();
1448
});
1449
1450
});
1451
1452
});
1453
});
1454
1455