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,119 @@
1
+ 'use strict';
2
+
3
+ const Zlib = require('zlib');
4
+
5
+ const Accept = require('@hapi/accept');
6
+ const Bounce = require('@hapi/bounce');
7
+ const Hoek = require('@hapi/hoek');
8
+
9
+
10
+ const internals = {
11
+ common: ['gzip, deflate', 'deflate, gzip', 'gzip', 'deflate', 'gzip, deflate, br']
12
+ };
13
+
14
+
15
+ exports = module.exports = internals.Compression = class {
16
+
17
+ decoders = {
18
+ gzip: (options) => Zlib.createGunzip(options),
19
+ deflate: (options) => Zlib.createInflate(options)
20
+ };
21
+
22
+ encodings = ['identity', 'gzip', 'deflate'];
23
+
24
+ encoders = {
25
+ identity: null,
26
+ gzip: (options) => Zlib.createGzip(options),
27
+ deflate: (options) => Zlib.createDeflate(options)
28
+ };
29
+
30
+ #common = null;
31
+
32
+ constructor() {
33
+
34
+ this._updateCommons();
35
+ }
36
+
37
+ _updateCommons() {
38
+
39
+ this.#common = new Map();
40
+
41
+ for (const header of internals.common) {
42
+ this.#common.set(header, Accept.encoding(header, this.encodings));
43
+ }
44
+ }
45
+
46
+ addEncoder(encoding, encoder) {
47
+
48
+ Hoek.assert(this.encoders[encoding] === undefined, `Cannot override existing encoder for ${encoding}`);
49
+ Hoek.assert(typeof encoder === 'function', `Invalid encoder function for ${encoding}`);
50
+ this.encoders[encoding] = encoder;
51
+ this.encodings.unshift(encoding);
52
+ this._updateCommons();
53
+ }
54
+
55
+ addDecoder(encoding, decoder) {
56
+
57
+ Hoek.assert(this.decoders[encoding] === undefined, `Cannot override existing decoder for ${encoding}`);
58
+ Hoek.assert(typeof decoder === 'function', `Invalid decoder function for ${encoding}`);
59
+ this.decoders[encoding] = decoder;
60
+ }
61
+
62
+ accept(request) {
63
+
64
+ const header = request.headers['accept-encoding'];
65
+ if (!header) {
66
+ return 'identity';
67
+ }
68
+
69
+ const common = this.#common.get(header);
70
+ if (common) {
71
+ return common;
72
+ }
73
+
74
+ try {
75
+ return Accept.encoding(header, this.encodings);
76
+ }
77
+ catch (err) {
78
+ Bounce.rethrow(err, 'system');
79
+ err.header = header;
80
+ request._log(['accept-encoding', 'error'], err);
81
+ return 'identity';
82
+ }
83
+ }
84
+
85
+ encoding(response, length) {
86
+
87
+ if (response.settings.compressed) {
88
+ response.headers['content-encoding'] = response.settings.compressed;
89
+ return null;
90
+ }
91
+
92
+ const request = response.request;
93
+ if (!request._core.settings.compression ||
94
+ length !== null && length < request._core.settings.compression.minBytes) {
95
+
96
+ return null;
97
+ }
98
+
99
+ const mime = request._core.mime.type(response.headers['content-type'] || 'application/octet-stream');
100
+ if (!mime.compressible) {
101
+ return null;
102
+ }
103
+
104
+ response.vary('accept-encoding');
105
+
106
+ if (response.headers['content-encoding']) {
107
+ return null;
108
+ }
109
+
110
+ return request.info.acceptEncoding === 'identity' ? null : request.info.acceptEncoding;
111
+ }
112
+
113
+ encoder(request, encoding) {
114
+
115
+ const encoder = this.encoders[encoding];
116
+ Hoek.assert(encoder !== undefined, `Unknown encoding ${encoding}`);
117
+ return encoder(request.route.settings.compression[encoding]);
118
+ }
119
+ };
package/lib/config.js ADDED
@@ -0,0 +1,443 @@
1
+ 'use strict';
2
+
3
+ const Os = require('os');
4
+
5
+ const Validate = require('@hapi/validate');
6
+
7
+
8
+ const internals = {};
9
+
10
+
11
+ exports.symbol = Symbol('hapi-response');
12
+
13
+
14
+ exports.apply = function (type, options, ...message) {
15
+
16
+ const result = internals[type].validate(options);
17
+
18
+ if (result.error) {
19
+ throw new Error(`Invalid ${type} options ${message.length ? '(' + message.join(' ') + ')' : ''} ${result.error.annotate()}`);
20
+ }
21
+
22
+ return result.value;
23
+ };
24
+
25
+
26
+ exports.enable = function (options) {
27
+
28
+ const settings = options ? Object.assign({}, options) : {}; // Shallow cloned
29
+
30
+ if (settings.security === true) {
31
+ settings.security = {};
32
+ }
33
+
34
+ if (settings.cors === true) {
35
+ settings.cors = {};
36
+ }
37
+
38
+ return settings;
39
+ };
40
+
41
+
42
+ internals.access = Validate.object({
43
+ entity: Validate.valid('user', 'app', 'any'),
44
+ scope: [false, Validate.array().items(Validate.string()).single().min(1)]
45
+ });
46
+
47
+
48
+ internals.auth = Validate.alternatives([
49
+ Validate.string(),
50
+ internals.access.keys({
51
+ mode: Validate.valid('required', 'optional', 'try'),
52
+ strategy: Validate.string(),
53
+ strategies: Validate.array().items(Validate.string()).min(1),
54
+ access: Validate.array().items(internals.access.min(1)).single().min(1),
55
+ payload: [
56
+ Validate.valid('required', 'optional'),
57
+ Validate.boolean()
58
+ ]
59
+ })
60
+ .without('strategy', 'strategies')
61
+ .without('access', ['scope', 'entity'])
62
+ ]);
63
+
64
+
65
+ internals.event = Validate.object({
66
+ method: Validate.array().items(Validate.function()).single(),
67
+ options: Validate.object({
68
+ before: Validate.array().items(Validate.string()).single(),
69
+ after: Validate.array().items(Validate.string()).single(),
70
+ bind: Validate.any(),
71
+ sandbox: Validate.valid('server', 'plugin'),
72
+ timeout: Validate.number().integer().min(1)
73
+ })
74
+ .default({})
75
+ });
76
+
77
+
78
+ internals.exts = Validate.array()
79
+ .items(internals.event.keys({ type: Validate.string().required() })).single();
80
+
81
+
82
+ internals.failAction = Validate.alternatives([
83
+ Validate.valid('error', 'log', 'ignore'),
84
+ Validate.function()
85
+ ])
86
+ .default('error');
87
+
88
+
89
+ internals.routeBase = Validate.object({
90
+ app: Validate.object().allow(null),
91
+ auth: internals.auth.allow(false),
92
+ bind: Validate.object().allow(null),
93
+ cache: Validate.object({
94
+ expiresIn: Validate.number(),
95
+ expiresAt: Validate.string(),
96
+ privacy: Validate.valid('default', 'public', 'private'),
97
+ statuses: Validate.array().items(Validate.number().integer().min(200)).min(1).single().default([200, 204]),
98
+ otherwise: Validate.string().default('no-cache')
99
+ })
100
+ .allow(false)
101
+ .default(),
102
+ compression: Validate.object()
103
+ .pattern(/.+/, Validate.object())
104
+ .default(),
105
+ cors: Validate.object({
106
+ origin: Validate.array().min(1).allow('ignore').default(['*']),
107
+ maxAge: Validate.number().default(86400),
108
+ headers: Validate.array().items(Validate.string()).default(['Accept', 'Authorization', 'Content-Type', 'If-None-Match']),
109
+ additionalHeaders: Validate.array().items(Validate.string()).default([]),
110
+ exposedHeaders: Validate.array().items(Validate.string()).default(['WWW-Authenticate', 'Server-Authorization']),
111
+ additionalExposedHeaders: Validate.array().items(Validate.string()).default([]),
112
+ credentials: Validate.boolean().when('origin', { is: 'ignore', then: false }).default(false)
113
+ })
114
+ .allow(false, true)
115
+ .default(false),
116
+ ext: Validate.object({
117
+ onPreAuth: Validate.array().items(internals.event).single(),
118
+ onCredentials: Validate.array().items(internals.event).single(),
119
+ onPostAuth: Validate.array().items(internals.event).single(),
120
+ onPreHandler: Validate.array().items(internals.event).single(),
121
+ onPostHandler: Validate.array().items(internals.event).single(),
122
+ onPreResponse: Validate.array().items(internals.event).single(),
123
+ onPostResponse: Validate.array().items(internals.event).single()
124
+ })
125
+ .default({}),
126
+ files: Validate.object({
127
+ relativeTo: Validate.string().pattern(/^([\/\.])|([A-Za-z]:\\)|(\\\\)/).default('.')
128
+ })
129
+ .default(),
130
+ json: Validate.object({
131
+ replacer: Validate.alternatives(Validate.function(), Validate.array()).allow(null).default(null),
132
+ space: Validate.number().allow(null).default(null),
133
+ suffix: Validate.string().allow(null).default(null),
134
+ escape: Validate.boolean().default(false)
135
+ })
136
+ .default(),
137
+ jsonp: Validate.string(),
138
+ log: Validate.object({
139
+ collect: Validate.boolean().default(false)
140
+ })
141
+ .default(),
142
+ payload: Validate.object({
143
+ output: Validate.valid('data', 'stream', 'file').default('data'),
144
+ parse: Validate.boolean().allow('gunzip').default(true),
145
+ multipart: Validate.object({
146
+ output: Validate.valid('data', 'stream', 'file', 'annotated').required()
147
+ })
148
+ .default(false)
149
+ .allow(true, false),
150
+ allow: Validate.array().items(Validate.string()).single(),
151
+ override: Validate.string(),
152
+ protoAction: Validate.valid('error', 'remove', 'ignore').default('error'),
153
+ maxBytes: Validate.number().integer().positive().default(1024 * 1024),
154
+ uploads: Validate.string().default(Os.tmpdir()),
155
+ failAction: internals.failAction,
156
+ timeout: Validate.number().integer().positive().allow(false).default(10 * 1000),
157
+ defaultContentType: Validate.string().default('application/json'),
158
+ compression: Validate.object()
159
+ .pattern(/.+/, Validate.object())
160
+ .default()
161
+ })
162
+ .default(),
163
+ plugins: Validate.object(),
164
+ response: Validate.object({
165
+ disconnectStatusCode: Validate.number().integer().min(400).default(499),
166
+ emptyStatusCode: Validate.valid(200, 204).default(204),
167
+ failAction: internals.failAction,
168
+ modify: Validate.boolean(),
169
+ options: Validate.object(),
170
+ ranges: Validate.boolean().default(true),
171
+ sample: Validate.number().min(0).max(100).when('modify', { then: Validate.forbidden() }),
172
+ schema: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(true, false),
173
+ status: Validate.object().pattern(/\d\d\d/, Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(true, false))
174
+ })
175
+ .default(),
176
+ security: Validate.object({
177
+ hsts: Validate.alternatives([
178
+ Validate.object({
179
+ maxAge: Validate.number(),
180
+ includeSubdomains: Validate.boolean(),
181
+ includeSubDomains: Validate.boolean(),
182
+ preload: Validate.boolean()
183
+ }),
184
+ Validate.boolean(),
185
+ Validate.number()
186
+ ])
187
+ .default(15768000),
188
+ xframe: Validate.alternatives([
189
+ Validate.boolean(),
190
+ Validate.valid('sameorigin', 'deny'),
191
+ Validate.object({
192
+ rule: Validate.valid('sameorigin', 'deny', 'allow-from'),
193
+ source: Validate.string()
194
+ })
195
+ ])
196
+ .default('deny'),
197
+ xss: Validate.boolean().default(true),
198
+ noOpen: Validate.boolean().default(true),
199
+ noSniff: Validate.boolean().default(true),
200
+ referrer: Validate.alternatives([
201
+ Validate.boolean().valid(false),
202
+ Validate.valid('', 'no-referrer', 'no-referrer-when-downgrade',
203
+ 'unsafe-url', 'same-origin', 'origin', 'strict-origin',
204
+ 'origin-when-cross-origin', 'strict-origin-when-cross-origin')
205
+ ])
206
+ .default(false)
207
+ })
208
+ .allow(null, false, true)
209
+ .default(false),
210
+ state: Validate.object({
211
+ parse: Validate.boolean().default(true),
212
+ failAction: internals.failAction
213
+ })
214
+ .default(),
215
+ timeout: Validate.object({
216
+ socket: Validate.number().integer().positive().allow(false),
217
+ server: Validate.number().integer().positive().allow(false).default(false)
218
+ })
219
+ .default(),
220
+ validate: Validate.object({
221
+ headers: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(null, true),
222
+ params: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(null, true),
223
+ query: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(null, false, true),
224
+ payload: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(null, false, true),
225
+ state: Validate.alternatives(Validate.object(), Validate.array(), Validate.function()).allow(null, false, true),
226
+ failAction: internals.failAction,
227
+ errorFields: Validate.object(),
228
+ options: Validate.object().default(),
229
+ validator: Validate.object()
230
+ })
231
+ .default()
232
+ });
233
+
234
+
235
+ internals.server = Validate.object({
236
+ address: Validate.string().hostname(),
237
+ app: Validate.object().allow(null),
238
+ autoListen: Validate.boolean(),
239
+ cache: Validate.allow(null), // Validated elsewhere
240
+ compression: Validate.object({
241
+ minBytes: Validate.number().min(1).integer().default(1024)
242
+ })
243
+ .allow(false)
244
+ .default(),
245
+ debug: Validate.object({
246
+ request: Validate.array().items(Validate.string()).single().allow(false).default(['implementation']),
247
+ log: Validate.array().items(Validate.string()).single().allow(false)
248
+ })
249
+ .allow(false)
250
+ .default(),
251
+ host: Validate.string().hostname().allow(null),
252
+ info: Validate.object({
253
+ remote: Validate.boolean().default(false)
254
+ })
255
+ .default({}),
256
+ listener: Validate.any(),
257
+ load: Validate.object({
258
+ sampleInterval: Validate.number().integer().min(0).default(0)
259
+ })
260
+ .unknown()
261
+ .default(),
262
+ mime: Validate.object().empty(null).default(),
263
+ operations: Validate.object({
264
+ cleanStop: Validate.boolean().default(true)
265
+ })
266
+ .default(),
267
+ plugins: Validate.object(),
268
+ port: Validate.alternatives([
269
+ Validate.number().integer().min(0), // TCP port
270
+ Validate.string().pattern(/\//), // Unix domain socket
271
+ Validate.string().pattern(/^\\\\\.\\pipe\\/) // Windows named pipe
272
+ ])
273
+ .allow(null),
274
+ query: Validate.object({
275
+ parser: Validate.function()
276
+ })
277
+ .default(),
278
+ router: Validate.object({
279
+ isCaseSensitive: Validate.boolean().default(true),
280
+ stripTrailingSlash: Validate.boolean().default(false)
281
+ })
282
+ .default(),
283
+ routes: internals.routeBase.default(),
284
+ state: Validate.object(), // Cookie defaults
285
+ tls: Validate.alternatives([
286
+ Validate.object().allow(null),
287
+ Validate.boolean()
288
+ ]),
289
+ uri: Validate.string().pattern(/[^/]$/)
290
+ });
291
+
292
+
293
+ internals.vhost = Validate.alternatives([
294
+ Validate.string().hostname(),
295
+ Validate.array().items(Validate.string().hostname()).min(1)
296
+ ]);
297
+
298
+
299
+ internals.handler = Validate.alternatives([
300
+ Validate.function(),
301
+ Validate.object().length(1)
302
+ ]);
303
+
304
+
305
+ internals.route = Validate.object({
306
+ method: Validate.string().pattern(/^[a-zA-Z0-9!#\$%&'\*\+\-\.^_`\|~]+$/).required(),
307
+ path: Validate.string().required(),
308
+ rules: Validate.object(),
309
+ vhost: internals.vhost,
310
+
311
+ // Validated in route construction
312
+
313
+ handler: Validate.any(),
314
+ options: Validate.any(),
315
+ config: Validate.any() // Backwards compatibility
316
+ })
317
+ .without('config', 'options');
318
+
319
+
320
+ internals.pre = [
321
+ Validate.function(),
322
+ Validate.object({
323
+ method: Validate.alternatives(Validate.string(), Validate.function()).required(),
324
+ assign: Validate.string(),
325
+ mode: Validate.valid('serial', 'parallel'),
326
+ failAction: internals.failAction
327
+ })
328
+ ];
329
+
330
+
331
+ internals.routeConfig = internals.routeBase.keys({
332
+ description: Validate.string(),
333
+ id: Validate.string(),
334
+ isInternal: Validate.boolean(),
335
+ notes: [
336
+ Validate.string(),
337
+ Validate.array().items(Validate.string())
338
+ ],
339
+ pre: Validate.array().items(...internals.pre.concat(Validate.array().items(...internals.pre).min(1))),
340
+ tags: [
341
+ Validate.string(),
342
+ Validate.array().items(Validate.string())
343
+ ]
344
+ });
345
+
346
+
347
+ internals.cacheConfig = Validate.alternatives([
348
+ Validate.function(),
349
+ Validate.object({
350
+ name: Validate.string().invalid('_default'),
351
+ shared: Validate.boolean(),
352
+ provider: [
353
+ Validate.function(),
354
+ {
355
+ constructor: Validate.function().required(),
356
+ options: Validate.object({
357
+ partition: Validate.string().default('hapi-cache')
358
+ })
359
+ .unknown() // Catbox client validates other keys
360
+ .default({})
361
+ }
362
+ ],
363
+ engine: Validate.object()
364
+ })
365
+ .xor('provider', 'engine')
366
+ ]);
367
+
368
+
369
+ internals.cache = Validate.array().items(internals.cacheConfig).min(1).single();
370
+
371
+
372
+ internals.cachePolicy = Validate.object({
373
+ cache: Validate.string().allow(null).allow(''),
374
+ segment: Validate.string(),
375
+ shared: Validate.boolean()
376
+ })
377
+ .unknown(); // Catbox policy validates other keys
378
+
379
+
380
+ internals.method = Validate.object({
381
+ bind: Validate.object().allow(null),
382
+ generateKey: Validate.function(),
383
+ cache: internals.cachePolicy
384
+ });
385
+
386
+
387
+ internals.methodObject = Validate.object({
388
+ name: Validate.string().required(),
389
+ method: Validate.function().required(),
390
+ options: Validate.object()
391
+ });
392
+
393
+
394
+ internals.register = Validate.object({
395
+ once: true,
396
+ routes: Validate.object({
397
+ prefix: Validate.string().pattern(/^\/.+/),
398
+ vhost: internals.vhost
399
+ })
400
+ .default({})
401
+ });
402
+
403
+
404
+ internals.semver = Validate.string();
405
+
406
+
407
+ internals.plugin = internals.register.keys({
408
+ options: Validate.any(),
409
+ plugin: Validate.object({
410
+ register: Validate.function().required(),
411
+ name: Validate.string().when('pkg.name', { is: Validate.exist(), otherwise: Validate.required() }),
412
+ version: Validate.string(),
413
+ multiple: Validate.boolean().default(false),
414
+ dependencies: [
415
+ Validate.array().items(Validate.string()).single(),
416
+ Validate.object().pattern(/.+/, internals.semver)
417
+ ],
418
+ once: true,
419
+ requirements: Validate.object({
420
+ hapi: Validate.string(),
421
+ node: Validate.string()
422
+ })
423
+ .default(),
424
+ pkg: Validate.object({
425
+ name: Validate.string(),
426
+ version: Validate.string().default('0.0.0')
427
+ })
428
+ .unknown()
429
+ .default({})
430
+ })
431
+ .unknown()
432
+ })
433
+ .without('once', 'options')
434
+ .unknown();
435
+
436
+
437
+ internals.rules = Validate.object({
438
+ validate: Validate.object({
439
+ schema: Validate.alternatives(Validate.object(), Validate.array()).required(),
440
+ options: Validate.object()
441
+ .default({ allowUnknown: true })
442
+ })
443
+ });