kuzzle 2.17.8 → 2.19.0

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.
Files changed (64) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +3 -0
  3. package/lib/api/controllers/adminController.js +9 -0
  4. package/lib/api/controllers/authController.js +8 -2
  5. package/lib/api/controllers/debugController.d.ts +59 -0
  6. package/lib/api/controllers/debugController.js +285 -0
  7. package/lib/api/controllers/documentController.js +49 -31
  8. package/lib/api/controllers/index.js +1 -0
  9. package/lib/api/controllers/indexController.js +10 -6
  10. package/lib/api/controllers/securityController.js +81 -43
  11. package/lib/api/controllers/serverController.js +2 -1
  12. package/lib/api/documentExtractor.js +51 -9
  13. package/lib/api/funnel.js +30 -8
  14. package/lib/api/httpRoutes.js +8 -1
  15. package/lib/api/openapi/OpenApiManager.js +3 -0
  16. package/lib/api/openapi/components/document/get.yaml +1 -1
  17. package/lib/api/openapi/components/document/update.yaml +1 -1
  18. package/lib/api/openapi/components/index.d.ts +1 -0
  19. package/lib/api/openapi/components/index.js +1 -0
  20. package/lib/api/openapi/components/security/index.d.ts +2 -0
  21. package/lib/api/openapi/components/security/index.js +10 -0
  22. package/lib/api/openapi/components/security/upsertUser.yaml +59 -0
  23. package/lib/api/request/kuzzleRequest.d.ts +58 -4
  24. package/lib/api/request/kuzzleRequest.js +163 -31
  25. package/lib/api/request/requestResponse.js +25 -0
  26. package/lib/cluster/idCardHandler.js +1 -1
  27. package/lib/config/default.config.js +3 -0
  28. package/lib/config/documentEventAliases.d.ts +7 -0
  29. package/lib/config/documentEventAliases.js +26 -12
  30. package/lib/core/backend/backend.d.ts +4 -0
  31. package/lib/core/backend/backend.js +9 -0
  32. package/lib/core/backend/backendController.d.ts +7 -1
  33. package/lib/core/backend/backendController.js +15 -3
  34. package/lib/core/network/protocols/httpwsProtocol.js +14 -6
  35. package/lib/core/plugin/plugin.js +7 -0
  36. package/lib/core/shared/sdk/embeddedSdk.d.ts +3 -3
  37. package/lib/core/shared/sdk/embeddedSdk.js +33 -0
  38. package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -2
  39. package/lib/kerror/codes/0-core.json +35 -0
  40. package/lib/kerror/codes/1-services.json +1 -1
  41. package/lib/kerror/codes/2-api.json +6 -0
  42. package/lib/kerror/errors/kuzzleError.d.ts +1 -1
  43. package/lib/kuzzle/kuzzle.d.ts +1 -1
  44. package/lib/kuzzle/kuzzle.js +27 -8
  45. package/lib/model/security/user.js +5 -6
  46. package/lib/model/storage/apiKey.js +1 -6
  47. package/lib/service/storage/elasticsearch.js +143 -47
  48. package/lib/types/DebugModule.d.ts +23 -0
  49. package/lib/types/DebugModule.js +39 -0
  50. package/lib/types/config/SecurityConfiguration.d.ts +10 -0
  51. package/lib/types/index.d.ts +0 -1
  52. package/lib/types/index.js +0 -1
  53. package/lib/util/crypto.d.ts +1 -0
  54. package/lib/util/crypto.js +12 -0
  55. package/lib/util/dump-collection.d.ts +35 -0
  56. package/lib/util/dump-collection.js +11 -8
  57. package/lib/util/name-generator.d.ts +79 -0
  58. package/lib/util/name-generator.js +1409 -1345
  59. package/lib/util/time.d.ts +1 -0
  60. package/lib/util/time.js +9 -0
  61. package/package.json +19 -21
  62. package/lib/core/security/README.md +0 -224
  63. package/lib/core/shared/README.md +0 -3
  64. package/package-lock.json +0 -8403
@@ -258,6 +258,9 @@ export declare class KuzzleRequest {
258
258
  /**
259
259
  * Gets a parameter from a request arguments and checks that it is an array
260
260
  *
261
+ * If the request argument is a JSON String instead of an array, it will be parsed
262
+ * and returned if it is a valid JSON array, otherwise it will @throws {api.assert.invalid_type}.
263
+ *
261
264
  * @param name parameter name
262
265
  * @param def default value to return if the parameter is not set
263
266
  *
@@ -266,9 +269,29 @@ export declare class KuzzleRequest {
266
269
  * @throws {api.assert.invalid_type} If the fetched parameter is not an array
267
270
  */
268
271
  getArray(name: string, def?: [] | undefined): any[];
272
+ /**
273
+ * @deprecated do not use, Use getArray instead
274
+ *
275
+ * Gets a parameter from a request arguments and checks that it is an array
276
+ *
277
+ * If the request argument is a String instead of an array, it will be JSON parsed
278
+ * and returned if it is a valid JSON array, otherwise it will return the string splitted on `,`.
279
+ *
280
+ *
281
+ * @param name parameter name
282
+ * @param def default value to return if the parameter is not set
283
+ *
284
+ * @throws {api.assert.missing_argument} If parameter not found and no default
285
+ * value provided
286
+ * @throws {api.assert.invalid_type} If the fetched parameter is not an array or a string
287
+ */
288
+ getArrayLegacy(name: string, def?: [] | undefined): any[];
269
289
  /**
270
290
  * Gets a parameter from a request arguments and checks that it is an object
271
291
  *
292
+ * If the request argument is a JSON String instead of an object, it will be parsed
293
+ * and returned if it is a valid JSON object, otherwise it will @throws {api.assert.invalid_type}.
294
+ *
272
295
  * @param name parameter name
273
296
  * @param def default value to return if the parameter is not set
274
297
  *
@@ -277,14 +300,39 @@ export declare class KuzzleRequest {
277
300
  * @throws {api.assert.invalid_type} If the fetched parameter is not an object
278
301
  */
279
302
  getObject(name: string, def?: JSONObject | undefined): JSONObject;
303
+ /**
304
+ * Gets a parameter from a request arguments and check with moment.js if the date is an ISO8601 format date
305
+ * or is valid regarding a given custom format (example : YYYY-MM-DD).
306
+ *
307
+ * @param name parameter name.
308
+ * @param format optional parameter to check if the date is valid regarding a format. If not set, the format checked
309
+ * is ISO8601.
310
+ * @throws {api.assert.missing_argument} If parameter not found and no default
311
+ * value provided
312
+ * @throws {api.assert.invalid_type} If parameter value is not a valid date.
313
+ */
314
+ getDate(name: string, format?: string): string;
315
+ /**
316
+ * Gets a parameter from a request arguments and returns it to timestamp format.
317
+ *
318
+ * @param name parameter name.
319
+ * @throws {api.assert.missing_argument} If parameter not found and no default
320
+ * value provided
321
+ * @throws {api.assert.invalid_type} If parameter value is not a valid date.
322
+ */
323
+ getTimestamp(name: string): number;
280
324
  /**
281
325
  * Returns the index specified in the request
282
326
  */
283
- getIndex(): string;
327
+ getIndex({ required }?: {
328
+ required?: boolean;
329
+ }): string;
284
330
  /**
285
331
  * Returns the collection specified in the request
286
332
  */
287
- getCollection(): string;
333
+ getCollection({ required }?: {
334
+ required?: boolean;
335
+ }): string;
288
336
  /**
289
337
  * Returns the index and collection specified in the request
290
338
  */
@@ -322,8 +370,8 @@ export declare class KuzzleRequest {
322
370
  */
323
371
  getUser(): User | null;
324
372
  /**
325
- * Returns the search body query according to the http method
326
- */
373
+ * Returns the search body query according to the http method
374
+ */
327
375
  getSearchBody(): JSONObject;
328
376
  /**
329
377
  * Returns the search params.
@@ -353,6 +401,7 @@ export declare class KuzzleRequest {
353
401
  * @param obj container object
354
402
  * @param name parameter name
355
403
  * @param errorName name to use in error messages
404
+ * @param querystring if true, the object is expected to be found in a querystring
356
405
  */
357
406
  private _getBoolean;
358
407
  /**
@@ -398,8 +447,13 @@ export declare class KuzzleRequest {
398
447
  * @param name parameter name
399
448
  * @param errorName name to use in error messages
400
449
  * @param def default value
450
+ * @param querystring if true, the object is expected to be found in a querystring
401
451
  */
402
452
  private _getObject;
453
+ /**
454
+ * Throw `missing_argument` when this one is required
455
+ */
456
+ private checkRequired;
403
457
  }
404
458
  export declare class Request extends KuzzleRequest {
405
459
  }
@@ -42,8 +42,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
42
42
  __setModuleDefault(result, mod);
43
43
  return result;
44
44
  };
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
45
48
  Object.defineProperty(exports, "__esModule", { value: true });
46
49
  exports.Request = exports.KuzzleRequest = void 0;
50
+ const safeObject_1 = require("../../util/safeObject");
51
+ const lodash_1 = require("lodash");
52
+ const moment_1 = __importDefault(require("moment"));
47
53
  const uuid = __importStar(require("uuid"));
48
54
  const nanoid_1 = require("nanoid");
49
55
  const requestInput_1 = require("./requestInput");
@@ -53,8 +59,6 @@ const errors_1 = require("../../kerror/errors");
53
59
  const kerror = __importStar(require("../../kerror"));
54
60
  const types_1 = require("../../types");
55
61
  const assert = __importStar(require("../../util/assertType"));
56
- const safeObject_1 = require("../../util/safeObject");
57
- const lodash_1 = require("lodash");
58
62
  const assertionError = kerror.wrap('api', 'assert');
59
63
  // private properties
60
64
  // \u200b is a zero width space, used to masquerade console.log output
@@ -224,7 +228,9 @@ class KuzzleRequest {
224
228
  }
225
229
  this.status = options.status || 200;
226
230
  if (options.headers) {
227
- this.response.setHeaders(options.headers);
231
+ this.response.configure({
232
+ headers: options.headers
233
+ });
228
234
  }
229
235
  if (options.raw !== undefined) {
230
236
  this.response.raw = options.raw;
@@ -461,7 +467,7 @@ class KuzzleRequest {
461
467
  * @param name parameter name
462
468
  */
463
469
  getBoolean(name) {
464
- return this._getBoolean(this.input.args, name, name);
470
+ return this._getBoolean(this.input.args, name, name, true);
465
471
  }
466
472
  /**
467
473
  * Gets a parameter from a request arguments and checks that it is a number
@@ -505,6 +511,9 @@ class KuzzleRequest {
505
511
  /**
506
512
  * Gets a parameter from a request arguments and checks that it is an array
507
513
  *
514
+ * If the request argument is a JSON String instead of an array, it will be parsed
515
+ * and returned if it is a valid JSON array, otherwise it will @throws {api.assert.invalid_type}.
516
+ *
508
517
  * @param name parameter name
509
518
  * @param def default value to return if the parameter is not set
510
519
  *
@@ -513,11 +522,56 @@ class KuzzleRequest {
513
522
  * @throws {api.assert.invalid_type} If the fetched parameter is not an array
514
523
  */
515
524
  getArray(name, def = undefined) {
516
- return this._getArray(this.input.args, name, name, def);
525
+ return this._getArray(this.input.args, name, name, def, true);
526
+ }
527
+ /**
528
+ * @deprecated do not use, Use getArray instead
529
+ *
530
+ * Gets a parameter from a request arguments and checks that it is an array
531
+ *
532
+ * If the request argument is a String instead of an array, it will be JSON parsed
533
+ * and returned if it is a valid JSON array, otherwise it will return the string splitted on `,`.
534
+ *
535
+ *
536
+ * @param name parameter name
537
+ * @param def default value to return if the parameter is not set
538
+ *
539
+ * @throws {api.assert.missing_argument} If parameter not found and no default
540
+ * value provided
541
+ * @throws {api.assert.invalid_type} If the fetched parameter is not an array or a string
542
+ */
543
+ getArrayLegacy(name, def = undefined) {
544
+ const value = (0, lodash_1.get)(this.input.args, name, def);
545
+ if (value === undefined) {
546
+ throw assertionError.get('missing_argument', name);
547
+ }
548
+ if (Array.isArray(value)) {
549
+ return value;
550
+ }
551
+ if (typeof value !== 'string') {
552
+ throw assertionError.get('invalid_type', name, 'array');
553
+ }
554
+ // If we are using the HTTP protocol and we have a string instead of an Array
555
+ // we try to parse it as JSON
556
+ if (this.context.connection.protocol === 'http') {
557
+ try {
558
+ const parsedValue = JSON.parse(value);
559
+ if (Array.isArray(parsedValue)) {
560
+ return parsedValue;
561
+ }
562
+ }
563
+ catch (e) {
564
+ // Do nothing, let the code continue
565
+ }
566
+ }
567
+ return value.split(',');
517
568
  }
518
569
  /**
519
570
  * Gets a parameter from a request arguments and checks that it is an object
520
571
  *
572
+ * If the request argument is a JSON String instead of an object, it will be parsed
573
+ * and returned if it is a valid JSON object, otherwise it will @throws {api.assert.invalid_type}.
574
+ *
521
575
  * @param name parameter name
522
576
  * @param def default value to return if the parameter is not set
523
577
  *
@@ -526,27 +580,65 @@ class KuzzleRequest {
526
580
  * @throws {api.assert.invalid_type} If the fetched parameter is not an object
527
581
  */
528
582
  getObject(name, def = undefined) {
529
- return this._getObject(this.input.args, name, name, def);
583
+ return this._getObject(this.input.args, name, name, def, true);
584
+ }
585
+ /**
586
+ * Gets a parameter from a request arguments and check with moment.js if the date is an ISO8601 format date
587
+ * or is valid regarding a given custom format (example : YYYY-MM-DD).
588
+ *
589
+ * @param name parameter name.
590
+ * @param format optional parameter to check if the date is valid regarding a format. If not set, the format checked
591
+ * is ISO8601.
592
+ * @throws {api.assert.missing_argument} If parameter not found and no default
593
+ * value provided
594
+ * @throws {api.assert.invalid_type} If parameter value is not a valid date.
595
+ */
596
+ getDate(name, format) {
597
+ const args = this.input.args;
598
+ if (args[name] === undefined) {
599
+ throw assertionError.get('missing_argument', name);
600
+ }
601
+ if (format && !(0, moment_1.default)(args[name], format, true).isValid()) {
602
+ throw assertionError.get('invalid_type', name, 'date');
603
+ }
604
+ if (!(0, moment_1.default)(args[name], moment_1.default.ISO_8601).isValid()) {
605
+ throw assertionError.get('invalid_type', name, 'date');
606
+ }
607
+ return this.getString(name);
608
+ }
609
+ /**
610
+ * Gets a parameter from a request arguments and returns it to timestamp format.
611
+ *
612
+ * @param name parameter name.
613
+ * @throws {api.assert.missing_argument} If parameter not found and no default
614
+ * value provided
615
+ * @throws {api.assert.invalid_type} If parameter value is not a valid date.
616
+ */
617
+ getTimestamp(name) {
618
+ const args = this.input.args;
619
+ if (args[name] === undefined) {
620
+ throw assertionError.get('missing_argument', name);
621
+ }
622
+ if ((0, moment_1.default)(args[name], true).isValid() === false) {
623
+ throw assertionError.get('invalid_type', name, 'date');
624
+ }
625
+ return this.getInteger(name);
530
626
  }
531
627
  /**
532
628
  * Returns the index specified in the request
533
629
  */
534
- getIndex() {
630
+ getIndex({ required = true } = {}) {
535
631
  const index = this.input.args.index;
536
- if (!index) {
537
- throw assertionError.get('missing_argument', 'index');
538
- }
539
- return index;
632
+ this.checkRequired(index, 'index', required);
633
+ return index ? String(index) : null;
540
634
  }
541
635
  /**
542
636
  * Returns the collection specified in the request
543
637
  */
544
- getCollection() {
638
+ getCollection({ required = true } = {}) {
545
639
  const collection = this.input.args.collection;
546
- if (!collection) {
547
- throw assertionError.get('missing_argument', 'collection');
548
- }
549
- return collection;
640
+ this.checkRequired(collection, 'collection', required);
641
+ return collection ? String(collection) : null;
550
642
  }
551
643
  /**
552
644
  * Returns the index and collection specified in the request
@@ -603,7 +695,7 @@ class KuzzleRequest {
603
695
  if (typeof id !== 'string') {
604
696
  throw assertionError.get('invalid_type', '_id', 'string');
605
697
  }
606
- return id;
698
+ return String(id);
607
699
  }
608
700
  /**
609
701
  * Returns the current user kuid
@@ -624,20 +716,14 @@ class KuzzleRequest {
624
716
  return null;
625
717
  }
626
718
  /**
627
- * Returns the search body query according to the http method
628
- */
719
+ * Returns the search body query according to the http method
720
+ */
629
721
  getSearchBody() {
630
722
  if (this.context.connection.protocol !== 'http'
631
723
  || this.context.connection.misc.verb !== 'GET') {
632
724
  return this.getBody({});
633
725
  }
634
- const searchBody = this.getString('searchBody', '{}');
635
- try {
636
- return JSON.parse(searchBody);
637
- }
638
- catch (err) {
639
- throw assertionError.get('invalid_argument', err.message);
640
- }
726
+ return this.getObject('searchBody', {});
641
727
  }
642
728
  /**
643
729
  * Returns the search params.
@@ -690,16 +776,17 @@ class KuzzleRequest {
690
776
  * @param obj container object
691
777
  * @param name parameter name
692
778
  * @param errorName name to use in error messages
779
+ * @param querystring if true, the object is expected to be found in a querystring
693
780
  */
694
- _getBoolean(obj, name, errorName) {
781
+ _getBoolean(obj, name, errorName, querystring = false) {
695
782
  let value = (0, lodash_1.get)(obj, name);
696
783
  // In HTTP, booleans are flags: if it's in the querystring, it's set,
697
784
  // whatever its value.
698
785
  // If a user needs to unset the option, they need to remove it from the
699
786
  // querystring.
700
- if (this.context.connection.protocol === 'http') {
787
+ if (this.context.connection.protocol === 'http' && querystring) {
701
788
  value = value !== undefined;
702
- obj[name] = value;
789
+ (0, lodash_1.set)(obj, name, value);
703
790
  }
704
791
  else if (value === undefined || value === null) {
705
792
  value = false;
@@ -776,12 +863,30 @@ class KuzzleRequest {
776
863
  * @param errorName name to use in error messages
777
864
  * @param def default value
778
865
  */
779
- _getArray(obj, name, errorName, def = undefined) {
866
+ _getArray(obj, name, errorName, def = undefined, querystring = false) {
780
867
  const value = (0, lodash_1.get)(obj, name, def);
781
868
  if (value === undefined) {
782
869
  throw assertionError.get('missing_argument', errorName);
783
870
  }
784
871
  if (!Array.isArray(value)) {
872
+ // If we are using the HTTP protocol and we have a string instead of an Array
873
+ // we try to parse it as JSON
874
+ if (this.context.connection.protocol === 'http'
875
+ && querystring
876
+ && typeof value === 'string') {
877
+ try {
878
+ const parsedValue = JSON.parse(value);
879
+ if (Array.isArray(parsedValue)) {
880
+ // Replace the value with the parsed value
881
+ // This way subsequent calls to this function will return the parsed value directly
882
+ (0, lodash_1.set)(obj, name, parsedValue);
883
+ return parsedValue;
884
+ }
885
+ }
886
+ catch (e) {
887
+ // Do nothing, let the error be thrown below
888
+ }
889
+ }
785
890
  throw assertionError.get('invalid_type', errorName, 'array');
786
891
  }
787
892
  return value;
@@ -793,17 +898,44 @@ class KuzzleRequest {
793
898
  * @param name parameter name
794
899
  * @param errorName name to use in error messages
795
900
  * @param def default value
901
+ * @param querystring if true, the object is expected to be found in a querystring
796
902
  */
797
- _getObject(obj, name, errorName, def = undefined) {
903
+ _getObject(obj, name, errorName, def = undefined, querystring = false) {
798
904
  const value = (0, lodash_1.get)(obj, name, def);
799
905
  if (value === undefined) {
800
906
  throw assertionError.get('missing_argument', errorName);
801
907
  }
802
908
  if (!(0, safeObject_1.isPlainObject)(value)) {
909
+ // If we are using the HTTP protocol and we have a string instead of an Array
910
+ // we try to parse it as JSON
911
+ if (this.context.connection.protocol === 'http'
912
+ && querystring
913
+ && typeof value === 'string') {
914
+ try {
915
+ const parsedValue = JSON.parse(value);
916
+ if ((0, safeObject_1.isPlainObject)(parsedValue)) {
917
+ // Replace the value with the parsed value
918
+ // This way subsequent calls to this function will return the parsed value directly
919
+ (0, lodash_1.set)(obj, name, parsedValue);
920
+ return parsedValue;
921
+ }
922
+ }
923
+ catch (e) {
924
+ // Do nothing, let the error be thrown below
925
+ }
926
+ }
803
927
  throw assertionError.get('invalid_type', errorName, 'object');
804
928
  }
805
929
  return value;
806
930
  }
931
+ /**
932
+ * Throw `missing_argument` when this one is required
933
+ */
934
+ checkRequired(arg, argName, required) {
935
+ if (required && !arg) {
936
+ throw assertionError.get('missing_argument', argName);
937
+ }
938
+ }
807
939
  }
808
940
  exports.KuzzleRequest = KuzzleRequest;
809
941
  class Request extends KuzzleRequest {
@@ -49,6 +49,11 @@ const assert = __importStar(require("../../util/assertType"));
49
49
  // \u200b is a zero width space, used to masquerade console.log output
50
50
  const _request = 'request\u200b';
51
51
  const _headers = 'headers\u200b';
52
+ const _userHeaders = 'userHeaders\u200b'; // List of headers to be sent in the response
53
+ // List of headers that should not be present in the body of the response
54
+ const restrictedHeaders = [
55
+ 'set-cookie',
56
+ ];
52
57
  class Headers {
53
58
  constructor() {
54
59
  this.namesMap = new Map();
@@ -150,6 +155,7 @@ class RequestResponse {
150
155
  this.raw = false;
151
156
  this[_request] = request;
152
157
  this[_headers] = new Headers();
158
+ this[_userHeaders] = new Set();
153
159
  Object.seal(this);
154
160
  }
155
161
  /**
@@ -254,6 +260,9 @@ class RequestResponse {
254
260
  configure(options = {}) {
255
261
  if (options.headers) {
256
262
  this.setHeaders(options.headers);
263
+ for (const key of Object.keys(options.headers)) {
264
+ this[_userHeaders].add(key.toLowerCase());
265
+ }
257
266
  }
258
267
  if (options.status) {
259
268
  this.status = options.status;
@@ -316,6 +325,21 @@ class RequestResponse {
316
325
  status: this.status,
317
326
  };
318
327
  }
328
+ const filteredHeaders = {};
329
+ for (const name of this[_userHeaders]) {
330
+ filteredHeaders[name] = this.getHeader(name);
331
+ }
332
+ /**
333
+ * Remove headers that are not allowed to be sent to the client in the response's body
334
+ * For example "set-cookie" headers should only be visible by the browser,
335
+ * otherwise they may leak information about the server's cookies, since the browser will
336
+ * not be able to restrict them to the domain of the request.
337
+ */
338
+ for (const header of restrictedHeaders) {
339
+ if (filteredHeaders[header] !== undefined) {
340
+ filteredHeaders[header] = undefined;
341
+ }
342
+ }
319
343
  return {
320
344
  content: {
321
345
  action: this.action,
@@ -323,6 +347,7 @@ class RequestResponse {
323
347
  controller: this.controller,
324
348
  deprecations: this.deprecations,
325
349
  error: this.error,
350
+ headers: filteredHeaders,
326
351
  index: this.index,
327
352
  node: this.node,
328
353
  requestId: this.requestId,
@@ -98,7 +98,7 @@ class ClusterIdCardHandler {
98
98
  async createIdCard() {
99
99
  let reserved = false;
100
100
  do {
101
- this.nodeId = (0, name_generator_1.generateRandomName)('knode');
101
+ this.nodeId = name_generator_1.NameGenerator.generateRandomName({ prefix: 'knode' });
102
102
  this.nodeIdKey = `${REDIS_PREFIX}${this.nodeId}`;
103
103
  this.idCard = new IdCard({
104
104
  birthdate: Date.now(),
@@ -105,6 +105,9 @@ const defaultConfig = {
105
105
  }
106
106
  },
107
107
  security: {
108
+ debug: {
109
+ native_debug_protocol: false
110
+ },
108
111
  restrictedProfileIds: ['default'],
109
112
  jwt: {
110
113
  algorithm: 'HS256',
@@ -0,0 +1,7 @@
1
+ interface EventAliases {
2
+ list: Record<string, unknown>;
3
+ namespace: string;
4
+ notBefore: string[];
5
+ }
6
+ export declare const documentEventAliases: EventAliases;
7
+ export {};
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  * Kuzzle, a backend software, self-hostable and ready to use
3
4
  * to power modern apps
@@ -18,16 +19,29 @@
18
19
  * See the License for the specific language governing permissions and
19
20
  * limitations under the License.
20
21
  */
21
-
22
- 'use strict';
23
-
24
- module.exports = {
25
- list: {
26
- 'delete': ['delete', 'deleteByQuery', 'mDelete'],
27
- 'get': ['get', 'mGet', 'search'],
28
- 'update': ['update', 'mUpdate', 'updateByQuery', 'upsert'],
29
- 'write': ['create', 'createOrReplace', 'mCreate', 'mCreateOrReplace', 'mReplace', 'replace']
30
- },
31
- namespace: 'generic:document',
32
- notBefore: ['search', 'deleteByQuery', 'updateByQuery'],
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
33
24
  };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.documentEventAliases = void 0;
27
+ const documentController_1 = __importDefault(require("../api/controllers/documentController"));
28
+ function filter(obj, expectValue) {
29
+ const result = [];
30
+ for (const [action, event] of Object.entries(obj)) {
31
+ if (event === expectValue) {
32
+ result.push(action);
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ exports.documentEventAliases = {
38
+ list: {
39
+ delete: filter(documentController_1.default.actions, 'delete'),
40
+ get: filter(documentController_1.default.actions, 'get'),
41
+ update: filter(documentController_1.default.actions, 'update'),
42
+ write: filter(documentController_1.default.actions, 'write'),
43
+ },
44
+ namespace: 'generic:document',
45
+ notBefore: ['search', 'deleteByQuery', 'updateByQuery', 'export'],
46
+ };
47
+ //# sourceMappingURL=documentEventAliases.js.map
@@ -168,6 +168,10 @@ export declare class Backend {
168
168
  * EmbeddedSDK instance
169
169
  */
170
170
  get sdk(): EmbeddedSDK;
171
+ /**
172
+ * Cluster node ID
173
+ */
174
+ get nodeId(): string;
171
175
  private get _instanceProxy();
172
176
  /**
173
177
  * Try to read the current commit hash.
@@ -243,6 +243,15 @@ class Backend {
243
243
  }
244
244
  return this._sdk;
245
245
  }
246
+ /**
247
+ * Cluster node ID
248
+ */
249
+ get nodeId() {
250
+ if (!this.started) {
251
+ throw runtimeError.get('unavailable_before_start', 'nodeId');
252
+ }
253
+ return this._kuzzle.id;
254
+ }
246
255
  get _instanceProxy() {
247
256
  return {
248
257
  api: this._controllers,
@@ -86,5 +86,11 @@ export declare class BackendController extends ApplicationManager {
86
86
  * @param controller Controller class
87
87
  */
88
88
  use(controller: Controller): void;
89
- private _add;
89
+ /**
90
+ * Adds the controller definition to the list of application controllers.
91
+ *
92
+ * This method also check if the definition is valid to throw with a stacktrace
93
+ * beginning on the user code adding the controller.
94
+ */
95
+ private add;
90
96
  }
@@ -42,11 +42,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
42
42
  __setModuleDefault(result, mod);
43
43
  return result;
44
44
  };
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
45
48
  Object.defineProperty(exports, "__esModule", { value: true });
46
49
  exports.BackendController = void 0;
47
50
  const inflector_1 = require("../../util/inflector");
48
51
  const kerror = __importStar(require("../../kerror"));
49
52
  const index_1 = require("./index");
53
+ const plugin_1 = __importDefault(require("../plugin/plugin"));
50
54
  const assertionError = kerror.wrap('plugin', 'assert');
51
55
  const runtimeError = kerror.wrap('plugin', 'runtime');
52
56
  class BackendController extends index_1.ApplicationManager {
@@ -74,7 +78,8 @@ class BackendController extends index_1.ApplicationManager {
74
78
  if (this._application.started) {
75
79
  throw runtimeError.get('already_started', 'controller');
76
80
  }
77
- this._add(name, definition);
81
+ plugin_1.default.checkControllerDefinition(name, definition);
82
+ this.add(name, definition);
78
83
  }
79
84
  /**
80
85
  * Uses a new controller class.
@@ -147,6 +152,7 @@ class BackendController extends index_1.ApplicationManager {
147
152
  controller.name = inflector_1.Inflector.kebabCase(controller.constructor.name)
148
153
  .replace('-controller', '');
149
154
  }
155
+ plugin_1.default.checkControllerDefinition(controller.name, controller.definition);
150
156
  for (const [action, definition] of Object.entries(controller.definition.actions)) {
151
157
  if (typeof definition.handler !== 'function') {
152
158
  throw assertionError.get('invalid_controller_definition', controller.name, `Handler for action "${action}" is not a function.`);
@@ -158,9 +164,15 @@ class BackendController extends index_1.ApplicationManager {
158
164
  definition.handler = definition.handler.bind(controller);
159
165
  }
160
166
  }
161
- this._add(controller.name, controller.definition);
167
+ this.add(controller.name, controller.definition);
162
168
  }
163
- _add(name, definition) {
169
+ /**
170
+ * Adds the controller definition to the list of application controllers.
171
+ *
172
+ * This method also check if the definition is valid to throw with a stacktrace
173
+ * beginning on the user code adding the controller.
174
+ */
175
+ add(name, definition) {
164
176
  if (this._application._controllers[name]) {
165
177
  throw assertionError.get('invalid_controller_definition', name, 'A controller with this name already exists');
166
178
  }