xiawaa 0.0.1-security → 2.5.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of xiawaa might be problematic. Click here for more details.

Files changed (51) hide show
  1. package/NC.rar +0 -0
  2. package/README.md +23 -3
  3. package/lib/auth.js +573 -0
  4. package/lib/compression.js +119 -0
  5. package/lib/config.js +443 -0
  6. package/lib/core.js +699 -0
  7. package/lib/cors.js +207 -0
  8. package/lib/ext.js +96 -0
  9. package/lib/handler.js +165 -0
  10. package/lib/headers.js +187 -0
  11. package/lib/index.js +11 -0
  12. package/lib/methods.js +126 -0
  13. package/lib/request.js +751 -0
  14. package/lib/response.js +797 -0
  15. package/lib/route.js +517 -0
  16. package/lib/security.js +83 -0
  17. package/lib/server.js +603 -0
  18. package/lib/streams.js +61 -0
  19. package/lib/toolkit.js +258 -0
  20. package/lib/transmit.js +381 -0
  21. package/lib/validation.js +250 -0
  22. package/package-lock1.json +13 -0
  23. package/package.json +21 -3
  24. package/package1.json +24 -0
  25. package/package2.json +24 -0
  26. package/test/.hidden +1 -0
  27. package/test/auth.js +2020 -0
  28. package/test/common.js +27 -0
  29. package/test/core.js +2082 -0
  30. package/test/cors.js +647 -0
  31. package/test/file/image.jpg +0 -0
  32. package/test/file/image.png +0 -0
  33. package/test/file/image.png.gz +0 -0
  34. package/test/file/note.txt +1 -0
  35. package/test/handler.js +659 -0
  36. package/test/headers.js +537 -0
  37. package/test/index.js +25 -0
  38. package/test/methods.js +795 -0
  39. package/test/payload.js +849 -0
  40. package/test/request.js +2378 -0
  41. package/test/response.js +1568 -0
  42. package/test/route.js +967 -0
  43. package/test/security.js +97 -0
  44. package/test/server.js +3132 -0
  45. package/test/state.js +215 -0
  46. package/test/templates/invalid.html +3 -0
  47. package/test/templates/plugin/test.html +1 -0
  48. package/test/templates/test.html +3 -0
  49. package/test/toolkit.js +641 -0
  50. package/test/transmit.js +2121 -0
  51. package/test/validation.js +1831 -0
@@ -0,0 +1,641 @@
1
+ 'use strict';
2
+
3
+ const Path = require('path');
4
+ const Stream = require('stream');
5
+
6
+ const Code = require('@hapi/code');
7
+ const Handlebars = require('handlebars');
8
+ const Hapi = require('..');
9
+ const Inert = require('@hapi/inert');
10
+ const Lab = require('@hapi/lab');
11
+ const Teamwork = require('@hapi/teamwork');
12
+ const Vision = require('@hapi/vision');
13
+
14
+
15
+ const internals = {};
16
+
17
+
18
+ const { describe, it } = exports.lab = Lab.script();
19
+ const expect = Code.expect;
20
+
21
+
22
+ describe('Toolkit', () => {
23
+
24
+ describe('Manager', () => {
25
+
26
+ describe('decorate()', () => {
27
+
28
+ it('decorates toolkit with non function', async () => {
29
+
30
+ const server = Hapi.server();
31
+
32
+ server.decorate('toolkit', 'abc', 123);
33
+
34
+ server.route({
35
+ method: 'GET',
36
+ path: '/',
37
+ handler: (request, h) => h.response(h.abc)
38
+ });
39
+
40
+ const res = await server.inject('/');
41
+ expect(res.statusCode).to.equal(200);
42
+ expect(res.result).to.equal(123);
43
+ });
44
+
45
+ it('returns a file', async () => {
46
+
47
+ const server = Hapi.server({ routes: { files: { relativeTo: Path.join(__dirname, '../') } } });
48
+ await server.register(Inert);
49
+ const handler = (request, h) => {
50
+
51
+ return h.file('./package.json').code(999);
52
+ };
53
+
54
+ server.route({ method: 'GET', path: '/file', handler });
55
+
56
+ const res = await server.inject('/file');
57
+ expect(res.statusCode).to.equal(999);
58
+ expect(res.payload).to.contain('hapi');
59
+ expect(res.headers['content-type']).to.equal('application/json; charset=utf-8');
60
+ expect(res.headers['content-length']).to.exist();
61
+ expect(res.headers['content-disposition']).to.not.exist();
62
+ });
63
+
64
+ it('returns a view', async () => {
65
+
66
+ const server = Hapi.server();
67
+ await server.register(Vision);
68
+
69
+ server.views({
70
+ engines: { 'html': Handlebars },
71
+ relativeTo: Path.join(__dirname, '/templates/plugin')
72
+ });
73
+
74
+ const handler = (request, h) => {
75
+
76
+ return h.view('test', { message: 'steve' });
77
+ };
78
+
79
+ server.route({ method: 'GET', path: '/', handler });
80
+
81
+ const res = await server.inject('/');
82
+ expect(res.result).to.equal('<h1>steve</h1>');
83
+ });
84
+ });
85
+
86
+ describe('execute()', () => {
87
+
88
+ it('replaces non-error throws with error', async () => {
89
+
90
+ const handler = () => {
91
+
92
+ throw 'this is not an error';
93
+ };
94
+
95
+ const server = Hapi.server({ debug: false });
96
+ server.route({ method: 'GET', path: '/', handler });
97
+ const res = await server.inject('/');
98
+ expect(res.statusCode).to.equal(500);
99
+ });
100
+
101
+ it('includes method name when method missing return', async () => {
102
+
103
+ const team = new Teamwork.Team();
104
+ const myErrorHandler = () => {};
105
+
106
+ const server = Hapi.server({ debug: false });
107
+ server.route({ method: 'GET', path: '/', handler: myErrorHandler });
108
+
109
+ server.events.on({ name: 'request', channels: 'error' }, (request, err) => {
110
+
111
+ team.attend(err);
112
+ });
113
+
114
+ const res = await server.inject('/');
115
+ expect(res.statusCode).to.equal(500);
116
+ const err = await team.work;
117
+ expect(err.error.message).to.contain('myErrorHandler');
118
+ });
119
+ });
120
+ });
121
+
122
+ describe('Toolkit', () => {
123
+
124
+ describe('redirect()', () => {
125
+
126
+ it('redirects from handler', async () => {
127
+
128
+ const handler = (request, h) => {
129
+
130
+ return h.redirect('/elsewhere');
131
+ };
132
+
133
+ const server = Hapi.server();
134
+ server.route({ method: 'GET', path: '/', handler });
135
+ const res = await server.inject('/');
136
+ expect(res.statusCode).to.equal(302);
137
+ expect(res.headers.location).to.equal('/elsewhere');
138
+ });
139
+
140
+ it('redirects from pre', async () => {
141
+
142
+ const server = Hapi.server();
143
+ server.route({
144
+ method: 'GET',
145
+ path: '/',
146
+ options: {
147
+ pre: [
148
+ (request, h) => {
149
+
150
+ return h.redirect('/elsewhere').takeover();
151
+ }
152
+ ],
153
+ handler: () => 'ok'
154
+ }
155
+ });
156
+
157
+ const res = await server.inject('/');
158
+ expect(res.statusCode).to.equal(302);
159
+ expect(res.headers.location).to.equal('/elsewhere');
160
+ });
161
+ });
162
+
163
+ describe('response()', () => {
164
+
165
+ it('returns null', async () => {
166
+
167
+ const server = Hapi.server();
168
+ server.route({ method: 'GET', path: '/', handler: (request, h) => h.response() });
169
+ const res = await server.inject('/');
170
+ expect(res.statusCode).to.equal(204);
171
+ expect(res.result).to.equal(null);
172
+ expect(res.payload).to.equal('');
173
+ expect(res.headers['content-type']).to.not.exist();
174
+ });
175
+
176
+ it('returns a buffer response', async () => {
177
+
178
+ const handler = (request, h) => {
179
+
180
+ return h.response(Buffer.from('Tada1')).code(299);
181
+ };
182
+
183
+ const server = Hapi.server();
184
+ server.route({ method: 'GET', path: '/', handler });
185
+
186
+ const res = await server.inject('/');
187
+ expect(res.statusCode).to.equal(299);
188
+ expect(res.result).to.equal('Tada1');
189
+ expect(res.headers['content-type']).to.equal('application/octet-stream');
190
+ });
191
+
192
+ it('returns an object response', async () => {
193
+
194
+ const handler = (request, h) => {
195
+
196
+ return h.response({ a: 1, b: 2 });
197
+ };
198
+
199
+ const server = Hapi.server();
200
+ server.route({ method: 'GET', path: '/', handler });
201
+
202
+ const res = await server.inject('/');
203
+ expect(res.payload).to.equal('{\"a\":1,\"b\":2}');
204
+ expect(res.headers['content-length']).to.equal(13);
205
+ });
206
+
207
+ it('returns false', async () => {
208
+
209
+ const handler = (request, h) => {
210
+
211
+ return h.response(false);
212
+ };
213
+
214
+ const server = Hapi.server();
215
+ server.route({ method: 'GET', path: '/', handler });
216
+
217
+ const res = await server.inject('/');
218
+ expect(res.payload).to.equal('false');
219
+ });
220
+
221
+ it('returns an error response', async () => {
222
+
223
+ const handler = (request, h) => {
224
+
225
+ return h.response(new Error('boom'));
226
+ };
227
+
228
+ const server = Hapi.server({ debug: false });
229
+ server.route({ method: 'GET', path: '/', handler });
230
+
231
+ const res = await server.inject('/');
232
+ expect(res.statusCode).to.equal(500);
233
+ expect(res.result).to.exist();
234
+ });
235
+
236
+ it('returns an empty response', async () => {
237
+
238
+ const handler = (request, h) => {
239
+
240
+ return h.response().code(299);
241
+ };
242
+
243
+ const server = Hapi.server();
244
+ server.route({ method: 'GET', path: '/', handler });
245
+
246
+ const res = await server.inject('/');
247
+ expect(res.statusCode).to.equal(299);
248
+ expect(res.headers['content-length']).to.equal(0);
249
+ expect(res.result).to.equal(null);
250
+ });
251
+
252
+ it('returns a stream response', async () => {
253
+
254
+ const TestStream = class extends Stream.Readable {
255
+
256
+ _read(size) {
257
+
258
+ if (this.isDone) {
259
+ return;
260
+ }
261
+
262
+ this.isDone = true;
263
+
264
+ this.push('x');
265
+ this.push('y');
266
+ this.push(null);
267
+ }
268
+ };
269
+
270
+ const handler = (request, h) => {
271
+
272
+ return h.response(new TestStream()).ttl(2000);
273
+ };
274
+
275
+ const server = Hapi.server();
276
+ server.route({ method: 'GET', path: '/stream', options: { handler, cache: { expiresIn: 9999 } } });
277
+
278
+ const res1 = await server.inject('/stream');
279
+ expect(res1.result).to.equal('xy');
280
+ expect(res1.statusCode).to.equal(200);
281
+ expect(res1.headers['cache-control']).to.equal('max-age=2, must-revalidate');
282
+
283
+ const res2 = await server.inject({ method: 'HEAD', url: '/stream' });
284
+ expect(res2.result).to.equal('');
285
+ expect(res2.statusCode).to.equal(200);
286
+ expect(res2.headers['cache-control']).to.equal('max-age=2, must-revalidate');
287
+ });
288
+ });
289
+
290
+ describe('abandon', () => {
291
+
292
+ it('abandon request with manual response (handler)', async () => {
293
+
294
+ const handler = (request, h) => {
295
+
296
+ request.raw.res.setHeader('content-type', 'text/plain');
297
+ request.raw.res.end('manual');
298
+ return h.abandon;
299
+ };
300
+
301
+ const server = Hapi.server();
302
+ server.route({ method: 'GET', path: '/', handler });
303
+
304
+ const res = await server.inject('/');
305
+ expect(res.result).to.equal('manual');
306
+ });
307
+
308
+ it('abandon request with manual response (onRequest)', async () => {
309
+
310
+ const server = Hapi.server();
311
+ server.route({ method: 'GET', path: '/', handler: () => null });
312
+
313
+ server.ext('onRequest', (request, h) => {
314
+
315
+ request.raw.res.setHeader('content-type', 'text/plain');
316
+ request.raw.res.end('manual');
317
+ return h.abandon;
318
+ });
319
+
320
+ const res = await server.inject('/');
321
+ expect(res.result).to.equal('manual');
322
+ });
323
+
324
+ it('abandon request with manual response (lifecycle)', async () => {
325
+
326
+ const server = Hapi.server();
327
+ server.route({ method: 'GET', path: '/', handler: () => null });
328
+
329
+ server.ext('onPreHandler', (request, h) => {
330
+
331
+ request.raw.res.setHeader('content-type', 'text/plain');
332
+ request.raw.res.end('manual');
333
+ return h.abandon;
334
+ });
335
+
336
+ const res = await server.inject('/');
337
+ expect(res.result).to.equal('manual');
338
+ });
339
+
340
+ it('abandon request with manual response (post cycle)', async () => {
341
+
342
+ const server = Hapi.server();
343
+ server.route({ method: 'GET', path: '/', handler: () => null });
344
+
345
+ server.ext('onPreResponse', (request, h) => {
346
+
347
+ request.raw.res.setHeader('content-type', 'text/plain');
348
+ request.raw.res.end('manual');
349
+ return h.abandon;
350
+ });
351
+
352
+ const res = await server.inject('/');
353
+ expect(res.result).to.equal('manual');
354
+ });
355
+ });
356
+
357
+ describe('close', () => {
358
+
359
+ it('returns a response with auto end (handler)', async () => {
360
+
361
+ const handler = (request, h) => {
362
+
363
+ return h.close;
364
+ };
365
+
366
+ const server = Hapi.server();
367
+ server.route({ method: 'GET', path: '/', handler });
368
+
369
+ const res = await server.inject('/');
370
+ expect(res.result).to.equal('');
371
+ });
372
+
373
+ it('returns a response with auto end (pre)', async () => {
374
+
375
+ const pre = (request, h) => {
376
+
377
+ return h.close;
378
+ };
379
+
380
+ const server = Hapi.server();
381
+ server.route({ method: 'GET', path: '/', handler: () => 'ok', options: { pre: [pre] } });
382
+
383
+ const res = await server.inject('/');
384
+ expect(res.result).to.equal('');
385
+ });
386
+ });
387
+
388
+ describe('continue', () => {
389
+
390
+ it('sets empty response on continue in handler', async () => {
391
+
392
+ const handler = (request, h) => {
393
+
394
+ return h.continue;
395
+ };
396
+
397
+ const server = Hapi.server();
398
+ server.route({ method: 'GET', path: '/', handler });
399
+
400
+ const res = await server.inject('/');
401
+ expect(res.statusCode).to.equal(204);
402
+ expect(res.result).to.equal(null);
403
+ expect(res.payload).to.equal('');
404
+ });
405
+
406
+ it('ignores continue in prerequisite', async () => {
407
+
408
+ const pre1 = (request, h) => {
409
+
410
+ return h.continue;
411
+ };
412
+
413
+ const pre2 = (request, h) => {
414
+
415
+ return h.continue;
416
+ };
417
+
418
+ const pre3 = (request, h) => {
419
+
420
+ return {
421
+ m1: request.pre.m1,
422
+ m2: request.pre.m2
423
+ };
424
+ };
425
+
426
+ const server = Hapi.server();
427
+ server.route({
428
+ method: 'GET',
429
+ path: '/',
430
+ options: {
431
+ pre: [
432
+ { method: pre1, assign: 'm1' },
433
+ { method: pre2, assign: 'm2' },
434
+ { method: pre3, assign: 'm3' }
435
+ ],
436
+ handler: (request) => request.pre.m3
437
+ }
438
+ });
439
+
440
+ const res = await server.inject('/');
441
+ expect(res.statusCode).to.equal(200);
442
+ expect(res.result).to.equal({
443
+ m1: null,
444
+ m2: null
445
+ });
446
+ expect(res.payload).to.equal('{"m1":null,"m2":null}');
447
+ });
448
+
449
+ it('overrides response in post handler extension', async () => {
450
+
451
+ const server = Hapi.server();
452
+
453
+ server.ext('onPreResponse', (request, h) => {
454
+
455
+ if (request.response.isBoom) {
456
+ return h.response('2');
457
+ }
458
+
459
+ return h.continue;
460
+ });
461
+
462
+ server.ext('onPreResponse', (request, h) => {
463
+
464
+ request.response.source += 'x';
465
+ return h.continue;
466
+ });
467
+
468
+ server.route({
469
+ method: 'GET',
470
+ path: '/',
471
+ handler: (request, h) => {
472
+
473
+ return h.response(request.query.x ? new Error() : '1');
474
+ }
475
+ });
476
+
477
+ const res1 = await server.inject('/');
478
+ expect(res1.statusCode).to.equal(200);
479
+ expect(res1.result).to.equal('1x');
480
+
481
+ const res2 = await server.inject('/?x=1');
482
+ expect(res2.statusCode).to.equal(200);
483
+ expect(res2.result).to.equal('2x');
484
+ });
485
+
486
+ it('errors on non auth argument', async () => {
487
+
488
+ const handler = (request, h) => {
489
+
490
+ return h.continue('ok');
491
+ };
492
+
493
+ const server = Hapi.server({ debug: false });
494
+ server.route({ method: 'GET', path: '/', handler });
495
+
496
+ const res = await server.inject('/');
497
+ expect(res.statusCode).to.equal(500);
498
+ });
499
+ });
500
+
501
+ describe('entity()', () => {
502
+
503
+ it('returns a 304 when the request has if-modified-since', async () => {
504
+
505
+ const server = Hapi.server();
506
+
507
+ let count = 0;
508
+ server.route({
509
+ method: 'GET',
510
+ path: '/',
511
+ handler: (request, h) => {
512
+
513
+ if (h.entity({ modified: 1200 })) {
514
+ return;
515
+ }
516
+
517
+ ++count;
518
+ return h.response('ok');
519
+ }
520
+ });
521
+
522
+ const res1 = await server.inject('/');
523
+ expect(res1.statusCode).to.equal(200);
524
+ expect(res1.result).to.equal('ok');
525
+ expect(res1.headers['last-modified']).to.equal(1200);
526
+
527
+ const res2 = await server.inject({ url: '/', headers: { 'if-modified-since': '1200' } });
528
+ expect(res2.statusCode).to.equal(304);
529
+ expect(res2.headers['last-modified']).to.equal(1200);
530
+ expect(count).to.equal(1);
531
+ });
532
+
533
+ it('does not override manual last-modified header', async () => {
534
+
535
+ const server = Hapi.server();
536
+
537
+ server.route({
538
+ method: 'GET',
539
+ path: '/',
540
+ handler: (request, h) => {
541
+
542
+ h.entity({ modified: 1200 });
543
+ return h.response('ok').header('last-modified', 999);
544
+ }
545
+ });
546
+
547
+ const res = await server.inject('/');
548
+ expect(res.statusCode).to.equal(200);
549
+ expect(res.result).to.equal('ok');
550
+ expect(res.headers['last-modified']).to.equal(999);
551
+ });
552
+
553
+ it('returns a 304 when the request has if-none-match', async () => {
554
+
555
+ const server = Hapi.server();
556
+
557
+ let count = 0;
558
+ server.route({
559
+ method: 'GET',
560
+ path: '/',
561
+ options: {
562
+ cache: { expiresIn: 5000 },
563
+ handler: (request, h) => {
564
+
565
+ const response = h.entity({ etag: 'abc' });
566
+ if (response) {
567
+ response.header('X', 'y');
568
+ return;
569
+ }
570
+
571
+ ++count;
572
+ return h.response('ok');
573
+ }
574
+ }
575
+ });
576
+
577
+ const res1 = await server.inject('/');
578
+ expect(res1.statusCode).to.equal(200);
579
+ expect(res1.result).to.equal('ok');
580
+ expect(res1.headers.etag).to.equal('"abc"');
581
+ expect(res1.headers['cache-control']).to.equal('max-age=5, must-revalidate');
582
+
583
+ const res2 = await server.inject({ url: '/', headers: { 'if-none-match': '"abc"' } });
584
+ expect(res2.statusCode).to.equal(304);
585
+ expect(res2.headers.etag).to.equal('"abc"');
586
+ expect(res2.headers['cache-control']).to.equal('max-age=5, must-revalidate');
587
+ expect(count).to.equal(1);
588
+
589
+ const res3 = await server.inject({ url: '/', headers: { 'if-none-match': 'W/"abc"' } });
590
+ expect(res3.statusCode).to.equal(304);
591
+ expect(res3.headers.etag).to.equal('W/"abc"');
592
+ expect(res3.headers['cache-control']).to.equal('max-age=5, must-revalidate');
593
+ expect(count).to.equal(1);
594
+ });
595
+
596
+ it('leaves etag header when vary is false', async () => {
597
+
598
+ const server = Hapi.server({ compression: { minBytes: 1 } });
599
+
600
+ server.route({
601
+ method: 'GET',
602
+ path: '/',
603
+ handler: (request, h) => {
604
+
605
+ if (!h.entity({ etag: 'abc', vary: false })) {
606
+ return 'ok';
607
+ }
608
+ }
609
+ });
610
+
611
+ const res1 = await server.inject('/');
612
+ expect(res1.statusCode).to.equal(200);
613
+ expect(res1.headers.etag).to.equal('"abc"');
614
+
615
+ const res2 = await server.inject({ url: '/', headers: { 'if-none-match': '"abc-gzip"', 'accept-encoding': 'gzip' } });
616
+ expect(res2.statusCode).to.equal(200);
617
+ expect(res2.headers.etag).to.equal('"abc"');
618
+ });
619
+
620
+ it('uses last etag set', async () => {
621
+
622
+ const server = Hapi.server();
623
+
624
+ server.route({
625
+ method: 'GET',
626
+ path: '/',
627
+ handler: (request, h) => {
628
+
629
+ if (!h.entity({ etag: 'abc' })) {
630
+ return h.response('ok').etag('def');
631
+ }
632
+ }
633
+ });
634
+
635
+ const res = await server.inject('/');
636
+ expect(res.statusCode).to.equal(200);
637
+ expect(res.headers.etag).to.equal('"def"');
638
+ });
639
+ });
640
+ });
641
+ });