kuzzle 2.18.0 → 2.19.1

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 (47) 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 +2 -1
  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/securityController.js +28 -22
  10. package/lib/api/controllers/serverController.js +2 -1
  11. package/lib/api/documentExtractor.js +51 -9
  12. package/lib/api/funnel.js +30 -8
  13. package/lib/api/httpRoutes.js +6 -0
  14. package/lib/api/request/kuzzleRequest.d.ts +37 -4
  15. package/lib/api/request/kuzzleRequest.js +115 -29
  16. package/lib/api/request/requestResponse.js +25 -0
  17. package/lib/cluster/idCardHandler.js +1 -1
  18. package/lib/config/default.config.js +3 -0
  19. package/lib/config/documentEventAliases.d.ts +7 -0
  20. package/lib/config/documentEventAliases.js +26 -12
  21. package/lib/core/backend/backend.d.ts +4 -0
  22. package/lib/core/backend/backend.js +9 -0
  23. package/lib/core/backend/backendController.d.ts +7 -1
  24. package/lib/core/backend/backendController.js +15 -3
  25. package/lib/core/network/protocols/httpwsProtocol.js +14 -6
  26. package/lib/core/plugin/plugin.js +7 -0
  27. package/lib/core/shared/sdk/embeddedSdk.d.ts +1 -1
  28. package/lib/core/shared/sdk/embeddedSdk.js +33 -0
  29. package/lib/kerror/codes/0-core.json +35 -0
  30. package/lib/kerror/codes/2-api.json +6 -0
  31. package/lib/kuzzle/kuzzle.d.ts +1 -1
  32. package/lib/kuzzle/kuzzle.js +27 -8
  33. package/lib/model/storage/apiKey.js +1 -6
  34. package/lib/service/storage/elasticsearch.js +40 -13
  35. package/lib/types/DebugModule.d.ts +23 -0
  36. package/lib/types/DebugModule.js +39 -0
  37. package/lib/types/config/SecurityConfiguration.d.ts +10 -0
  38. package/lib/util/crypto.d.ts +1 -0
  39. package/lib/util/crypto.js +12 -0
  40. package/lib/util/name-generator.d.ts +79 -0
  41. package/lib/util/name-generator.js +1409 -1345
  42. package/lib/util/time.d.ts +1 -0
  43. package/lib/util/time.js +9 -0
  44. package/package.json +4 -6
  45. package/lib/core/security/README.md +0 -224
  46. package/lib/core/shared/README.md +0 -3
  47. package/package-lock.json +0 -8422
@@ -228,7 +228,9 @@ class KuzzleRequest {
228
228
  }
229
229
  this.status = options.status || 200;
230
230
  if (options.headers) {
231
- this.response.setHeaders(options.headers);
231
+ this.response.configure({
232
+ headers: options.headers
233
+ });
232
234
  }
233
235
  if (options.raw !== undefined) {
234
236
  this.response.raw = options.raw;
@@ -465,7 +467,7 @@ class KuzzleRequest {
465
467
  * @param name parameter name
466
468
  */
467
469
  getBoolean(name) {
468
- return this._getBoolean(this.input.args, name, name);
470
+ return this._getBoolean(this.input.args, name, name, true);
469
471
  }
470
472
  /**
471
473
  * Gets a parameter from a request arguments and checks that it is a number
@@ -509,6 +511,9 @@ class KuzzleRequest {
509
511
  /**
510
512
  * Gets a parameter from a request arguments and checks that it is an array
511
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
+ *
512
517
  * @param name parameter name
513
518
  * @param def default value to return if the parameter is not set
514
519
  *
@@ -517,11 +522,56 @@ class KuzzleRequest {
517
522
  * @throws {api.assert.invalid_type} If the fetched parameter is not an array
518
523
  */
519
524
  getArray(name, def = undefined) {
520
- 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(',');
521
568
  }
522
569
  /**
523
570
  * Gets a parameter from a request arguments and checks that it is an object
524
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
+ *
525
575
  * @param name parameter name
526
576
  * @param def default value to return if the parameter is not set
527
577
  *
@@ -530,7 +580,7 @@ class KuzzleRequest {
530
580
  * @throws {api.assert.invalid_type} If the fetched parameter is not an object
531
581
  */
532
582
  getObject(name, def = undefined) {
533
- return this._getObject(this.input.args, name, name, def);
583
+ return this._getObject(this.input.args, name, name, def, true);
534
584
  }
535
585
  /**
536
586
  * Gets a parameter from a request arguments and check with moment.js if the date is an ISO8601 format date
@@ -577,22 +627,18 @@ class KuzzleRequest {
577
627
  /**
578
628
  * Returns the index specified in the request
579
629
  */
580
- getIndex() {
630
+ getIndex({ required = true } = {}) {
581
631
  const index = this.input.args.index;
582
- if (!index) {
583
- throw assertionError.get('missing_argument', 'index');
584
- }
585
- return index;
632
+ this.checkRequired(index, 'index', required);
633
+ return index ? String(index) : null;
586
634
  }
587
635
  /**
588
636
  * Returns the collection specified in the request
589
637
  */
590
- getCollection() {
638
+ getCollection({ required = true } = {}) {
591
639
  const collection = this.input.args.collection;
592
- if (!collection) {
593
- throw assertionError.get('missing_argument', 'collection');
594
- }
595
- return collection;
640
+ this.checkRequired(collection, 'collection', required);
641
+ return collection ? String(collection) : null;
596
642
  }
597
643
  /**
598
644
  * Returns the index and collection specified in the request
@@ -649,7 +695,7 @@ class KuzzleRequest {
649
695
  if (typeof id !== 'string') {
650
696
  throw assertionError.get('invalid_type', '_id', 'string');
651
697
  }
652
- return id;
698
+ return String(id);
653
699
  }
654
700
  /**
655
701
  * Returns the current user kuid
@@ -670,20 +716,14 @@ class KuzzleRequest {
670
716
  return null;
671
717
  }
672
718
  /**
673
- * Returns the search body query according to the http method
674
- */
719
+ * Returns the search body query according to the http method
720
+ */
675
721
  getSearchBody() {
676
722
  if (this.context.connection.protocol !== 'http'
677
723
  || this.context.connection.misc.verb !== 'GET') {
678
724
  return this.getBody({});
679
725
  }
680
- const searchBody = this.getString('searchBody', '{}');
681
- try {
682
- return JSON.parse(searchBody);
683
- }
684
- catch (err) {
685
- throw assertionError.get('invalid_argument', err.message);
686
- }
726
+ return this.getObject('searchBody', {});
687
727
  }
688
728
  /**
689
729
  * Returns the search params.
@@ -736,16 +776,17 @@ class KuzzleRequest {
736
776
  * @param obj container object
737
777
  * @param name parameter name
738
778
  * @param errorName name to use in error messages
779
+ * @param querystring if true, the object is expected to be found in a querystring
739
780
  */
740
- _getBoolean(obj, name, errorName) {
781
+ _getBoolean(obj, name, errorName, querystring = false) {
741
782
  let value = (0, lodash_1.get)(obj, name);
742
783
  // In HTTP, booleans are flags: if it's in the querystring, it's set,
743
784
  // whatever its value.
744
785
  // If a user needs to unset the option, they need to remove it from the
745
786
  // querystring.
746
- if (this.context.connection.protocol === 'http') {
787
+ if (this.context.connection.protocol === 'http' && querystring) {
747
788
  value = value !== undefined;
748
- obj[name] = value;
789
+ (0, lodash_1.set)(obj, name, value);
749
790
  }
750
791
  else if (value === undefined || value === null) {
751
792
  value = false;
@@ -822,12 +863,30 @@ class KuzzleRequest {
822
863
  * @param errorName name to use in error messages
823
864
  * @param def default value
824
865
  */
825
- _getArray(obj, name, errorName, def = undefined) {
866
+ _getArray(obj, name, errorName, def = undefined, querystring = false) {
826
867
  const value = (0, lodash_1.get)(obj, name, def);
827
868
  if (value === undefined) {
828
869
  throw assertionError.get('missing_argument', errorName);
829
870
  }
830
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
+ }
831
890
  throw assertionError.get('invalid_type', errorName, 'array');
832
891
  }
833
892
  return value;
@@ -839,17 +898,44 @@ class KuzzleRequest {
839
898
  * @param name parameter name
840
899
  * @param errorName name to use in error messages
841
900
  * @param def default value
901
+ * @param querystring if true, the object is expected to be found in a querystring
842
902
  */
843
- _getObject(obj, name, errorName, def = undefined) {
903
+ _getObject(obj, name, errorName, def = undefined, querystring = false) {
844
904
  const value = (0, lodash_1.get)(obj, name, def);
845
905
  if (value === undefined) {
846
906
  throw assertionError.get('missing_argument', errorName);
847
907
  }
848
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
+ }
849
927
  throw assertionError.get('invalid_type', errorName, 'object');
850
928
  }
851
929
  return value;
852
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
+ }
853
939
  }
854
940
  exports.KuzzleRequest = KuzzleRequest;
855
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
  }
@@ -256,10 +256,15 @@ class HttpWsProtocol extends Protocol {
256
256
  }
257
257
 
258
258
  wsOnUpgradeHandler (res, req, context) {
259
+ const headers = {};
260
+ // Extract headers from uWS request
261
+ req.forEach((header, value) => {
262
+ headers[header] = value;
263
+ });
264
+
259
265
  res.upgrade(
260
266
  {
261
- cookie: req.getHeader('cookie'),
262
- origin: req.getHeader('origin'),
267
+ headers,
263
268
  },
264
269
  req.getHeader('sec-websocket-key'),
265
270
  req.getHeader('sec-websocket-protocol'),
@@ -273,10 +278,7 @@ class HttpWsProtocol extends Protocol {
273
278
  const connection = new ClientConnection(
274
279
  this.name,
275
280
  [ip],
276
- {
277
- cookie: socket.cookie,
278
- origin: socket.origin
279
- }
281
+ socket.headers
280
282
  );
281
283
 
282
284
  this.entryPoint.newConnection(connection);
@@ -553,10 +555,16 @@ class HttpWsProtocol extends Protocol {
553
555
  if (type.includes('multipart/form-data')) {
554
556
  const parts = uWS.getParts(content, message.headers['content-type']);
555
557
  message.content = {};
558
+
559
+ if (! parts) {
560
+ cb();
561
+ return;
562
+ }
556
563
 
557
564
  for (const part of parts) {
558
565
  if (part.data.byteLength > this.maxFormFileSize) {
559
566
  cb(HTTP_FILE_TOO_LARGE_ERROR);
567
+ return;
560
568
  }
561
569
 
562
570
  if (part.filename) {
@@ -300,6 +300,13 @@ class Plugin {
300
300
  'Controller definition must be an object');
301
301
  }
302
302
 
303
+ if (! isPlainObject(definition.actions)) {
304
+ throw assertionError.get(
305
+ 'invalid_controller_definition',
306
+ name,
307
+ 'Controller definition "actions" property must be an object');
308
+ }
309
+
303
310
  for (const [action, actionDefinition] of Object.entries(definition.actions)) {
304
311
  const actionProperties = Object.keys(actionDefinition);
305
312
 
@@ -6,7 +6,7 @@ interface EmbeddedRealtime extends RealtimeController {
6
6
  * and, optionally, user events matching the provided filters will generate
7
7
  * real-time notifications.
8
8
  *
9
- * @see https://docs.kuzzle.io/core/2/guides/main-concepts/6-realtime-engine/
9
+ * @see https://docs.kuzzle.io/core/2/guides/main-concepts/realtime-engine/
10
10
  *
11
11
  * @param index Index name
12
12
  * @param collection Collection name
@@ -48,11 +48,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
48
48
  Object.defineProperty(exports, "__esModule", { value: true });
49
49
  exports.EmbeddedSDK = void 0;
50
50
  const kuzzle_sdk_1 = require("kuzzle-sdk");
51
+ const lodash_1 = __importDefault(require("lodash"));
51
52
  const funnelProtocol_1 = require("./funnelProtocol");
52
53
  const safeObject_1 = require("../../../util/safeObject");
53
54
  const kerror = __importStar(require("../../../kerror"));
54
55
  const impersonatedSdk_1 = __importDefault(require("./impersonatedSdk"));
55
56
  const contextError = kerror.wrap('plugin', 'context');
57
+ const forbiddenEmbeddedActions = {
58
+ 'auth': new Set([
59
+ 'checkRights',
60
+ 'createApiKey',
61
+ 'createMyCredentials',
62
+ 'credentialsExist',
63
+ 'deleteApiKey',
64
+ 'getCurrentUser',
65
+ 'getMyCredentials',
66
+ 'getMyRights',
67
+ 'getStrategies',
68
+ 'logout',
69
+ 'refreshToken',
70
+ 'searchApiKeys',
71
+ 'updateMyCredentials',
72
+ 'updateSelf',
73
+ 'validateMyCredentials',
74
+ ]),
75
+ };
76
+ const warnEmbeddedActions = {
77
+ 'auth': {
78
+ 'login': 'EmbeddedSDK.login is deprecated, use user impersonation instead',
79
+ }
80
+ };
56
81
  /**
57
82
  * Kuzzle embedded SDK to make API calls inside applications or plugins.
58
83
  */
@@ -91,6 +116,14 @@ class EmbeddedSDK extends kuzzle_sdk_1.Kuzzle {
91
116
  ? false
92
117
  : options.propagate;
93
118
  }
119
+ if (forbiddenEmbeddedActions[request.controller] !== undefined
120
+ && forbiddenEmbeddedActions[request.controller].has(request.action)) {
121
+ throw kerror.get('api', 'process', 'forbidden_embedded_sdk_action', request.controller, request.action, ', use user impersonation or security controller instead');
122
+ }
123
+ const warning = lodash_1.default.get(warnEmbeddedActions, [request.controller, request.action]);
124
+ if (warning) {
125
+ global.kuzzle.log.warn(warning);
126
+ }
94
127
  return super.query(request, options);
95
128
  }
96
129
  }
@@ -154,6 +154,41 @@
154
154
  "class": "GatewayTimeoutError"
155
155
  }
156
156
  }
157
+ },
158
+ "debugger": {
159
+ "code": 5,
160
+ "errors": {
161
+ "not_enabled": {
162
+ "description": "The debugger is not enabled",
163
+ "code": 1,
164
+ "message": "Debugger is not enabled",
165
+ "class": "PreconditionError"
166
+ },
167
+ "monitor_already_running": {
168
+ "description": "The monitor is already running",
169
+ "code": 2,
170
+ "message": "The monitoring of \"%s\" is already running",
171
+ "class": "PreconditionError"
172
+ },
173
+ "monitor_not_running": {
174
+ "description": "The monitor is not running",
175
+ "code": 3,
176
+ "message": "The monitoring of \"%s\" is not running",
177
+ "class": "PreconditionError"
178
+ },
179
+ "native_debug_protocol_usage_denied": {
180
+ "description": "Usage of the native debug protocol is not allowed",
181
+ "code": 4,
182
+ "message": "Usage of the native debug protocol is not allowed",
183
+ "class": "PreconditionError"
184
+ },
185
+ "method_not_found": {
186
+ "description": "Debugger method not found",
187
+ "code": 5,
188
+ "message": "Debugger method \"%s\" not found.",
189
+ "class": "PreconditionError"
190
+ }
191
+ }
157
192
  }
158
193
  }
159
194
  }
@@ -182,6 +182,12 @@
182
182
  "code": 13,
183
183
  "message": "Rejected: Too many login attempts per second",
184
184
  "class": "TooManyRequestsError"
185
+ },
186
+ "forbidden_embedded_sdk_action": {
187
+ "description": "A forbidden EmbdeddedSDK action has been called",
188
+ "code": 14,
189
+ "message": "The action %s:%s has been called while it is forbidden in the EmbeddedSDK%s.",
190
+ "class": "PluginImplementationError"
185
191
  }
186
192
  }
187
193
  }
@@ -1 +1 @@
1
- export {};
1
+ export declare const BACKEND_IMPORT_KEY = "backend:init:import";