kuzzle 2.16.11 → 2.17.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 (164) hide show
  1. package/lib/api/controllers/adminController.js +3 -3
  2. package/lib/api/controllers/authController.js +11 -11
  3. package/lib/api/controllers/baseController.js +60 -3
  4. package/lib/api/controllers/clusterController.js +1 -1
  5. package/lib/api/controllers/collectionController.js +7 -5
  6. package/lib/api/controllers/documentController.js +130 -17
  7. package/lib/api/controllers/indexController.js +1 -1
  8. package/lib/api/controllers/memoryStorageController.js +39 -38
  9. package/lib/api/controllers/realtimeController.js +1 -1
  10. package/lib/api/controllers/securityController.js +49 -49
  11. package/lib/api/controllers/serverController.js +73 -27
  12. package/lib/api/documentExtractor.js +3 -3
  13. package/lib/api/funnel.js +40 -21
  14. package/lib/api/httpRoutes.js +9 -4
  15. package/lib/api/openapi/OpenApiManager.d.ts +11 -0
  16. package/lib/api/openapi/OpenApiManager.js +96 -0
  17. package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
  18. package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
  19. package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
  20. package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
  21. package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
  22. package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
  23. package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
  24. package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
  25. package/lib/api/openapi/{document → components/document}/index.js +7 -2
  26. package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
  27. package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
  28. package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
  29. package/lib/api/openapi/components/document/validate.yaml +42 -0
  30. package/lib/api/openapi/components/index.d.ts +2 -0
  31. package/lib/api/openapi/components/index.js +18 -0
  32. package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
  33. package/lib/api/openapi/index.d.ts +1 -2
  34. package/lib/api/openapi/index.js +1 -5
  35. package/lib/api/openapi/openApiGenerator.d.ts +7 -0
  36. package/lib/api/openapi/openApiGenerator.js +133 -0
  37. package/lib/api/request/kuzzleRequest.js +4 -0
  38. package/lib/cluster/node.js +9 -9
  39. package/lib/cluster/publisher.js +1 -1
  40. package/lib/cluster/subscriber.js +1 -1
  41. package/lib/cluster/workers/IDCardRenewer.js +2 -2
  42. package/lib/config/default.config.js +1 -0
  43. package/lib/config/index.js +6 -6
  44. package/lib/core/auth/passportResponse.js +6 -6
  45. package/lib/core/auth/passportWrapper.js +5 -5
  46. package/lib/core/backend/backend.d.ts +5 -1
  47. package/lib/core/backend/backend.js +12 -8
  48. package/lib/core/backend/backendConfig.d.ts +5 -1
  49. package/lib/core/backend/backendConfig.js +4 -0
  50. package/lib/core/backend/backendOpenApi.d.ts +9 -0
  51. package/lib/core/backend/backendOpenApi.js +69 -0
  52. package/lib/core/backend/index.d.ts +1 -0
  53. package/lib/core/backend/index.js +1 -0
  54. package/lib/core/network/accessLogger.js +6 -6
  55. package/lib/core/network/clientConnection.js +1 -1
  56. package/lib/core/network/entryPoint.js +5 -5
  57. package/lib/core/network/httpRouter/index.js +5 -5
  58. package/lib/core/network/httpRouter/routeHandler.js +3 -3
  59. package/lib/core/network/httpRouter/routePart.js +5 -5
  60. package/lib/core/network/protocolManifest.js +1 -1
  61. package/lib/core/network/protocols/httpMessage.js +2 -2
  62. package/lib/core/network/protocols/httpwsProtocol.js +205 -48
  63. package/lib/core/network/protocols/mqttProtocol.js +3 -3
  64. package/lib/core/network/protocols/protocol.js +3 -3
  65. package/lib/core/network/router.js +7 -6
  66. package/lib/core/plugin/plugin.js +38 -64
  67. package/lib/core/plugin/pluginManifest.js +3 -3
  68. package/lib/core/plugin/pluginRepository.js +5 -5
  69. package/lib/core/plugin/pluginsManager.js +29 -28
  70. package/lib/core/realtime/notification/server.js +1 -1
  71. package/lib/core/realtime/notification/user.js +1 -1
  72. package/lib/core/realtime/notifier.js +5 -5
  73. package/lib/core/security/index.js +1 -1
  74. package/lib/core/security/profileRepository.d.ts +176 -0
  75. package/lib/core/security/profileRepository.js +426 -443
  76. package/lib/core/security/roleRepository.js +16 -16
  77. package/lib/core/security/securityLoader.js +2 -2
  78. package/lib/core/security/tokenRepository.js +11 -11
  79. package/lib/core/security/userRepository.js +8 -8
  80. package/lib/core/shared/abstractManifest.js +4 -4
  81. package/lib/core/shared/repository.js +5 -5
  82. package/lib/core/shared/sdk/funnelProtocol.js +1 -1
  83. package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
  84. package/lib/core/shared/store.js +30 -23
  85. package/lib/core/statistics/statistics.js +17 -17
  86. package/lib/core/storage/clientAdapter.js +45 -10
  87. package/lib/core/validation/baseType.js +5 -5
  88. package/lib/core/validation/types/anything.js +1 -1
  89. package/lib/core/validation/types/boolean.js +2 -2
  90. package/lib/core/validation/types/date.js +9 -9
  91. package/lib/core/validation/types/email.js +5 -5
  92. package/lib/core/validation/types/enum.js +6 -6
  93. package/lib/core/validation/types/geoPoint.js +2 -2
  94. package/lib/core/validation/types/geoShape.js +28 -25
  95. package/lib/core/validation/types/integer.js +4 -4
  96. package/lib/core/validation/types/ipAddress.js +7 -6
  97. package/lib/core/validation/types/numeric.js +4 -4
  98. package/lib/core/validation/types/object.js +5 -5
  99. package/lib/core/validation/types/string.js +5 -5
  100. package/lib/core/validation/types/url.js +7 -6
  101. package/lib/core/validation/validation.js +95 -84
  102. package/lib/kerror/codes/1-services.json +12 -0
  103. package/lib/kerror/codes/2-api.json +12 -0
  104. package/lib/kerror/codes/3-network.json +12 -0
  105. package/lib/kerror/codes/4-plugin.json +6 -0
  106. package/lib/kerror/codes/index.js +11 -11
  107. package/lib/kerror/index.js +1 -1
  108. package/lib/kuzzle/dumpGenerator.js +3 -3
  109. package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
  110. package/lib/kuzzle/event/pipeRunner.js +1 -1
  111. package/lib/kuzzle/event/waterfall.js +6 -6
  112. package/lib/kuzzle/kuzzle.js +36 -5
  113. package/lib/kuzzle/log.js +3 -3
  114. package/lib/kuzzle/vault.js +3 -3
  115. package/lib/model/security/profile.d.ts +54 -0
  116. package/lib/model/security/profile.js +174 -233
  117. package/lib/model/security/rights.js +1 -1
  118. package/lib/model/security/role.d.ts +40 -0
  119. package/lib/model/security/role.js +159 -191
  120. package/lib/model/security/user.d.ts +29 -0
  121. package/lib/model/security/user.js +84 -52
  122. package/lib/model/storage/apiKey.js +2 -2
  123. package/lib/model/storage/baseModel.js +3 -3
  124. package/lib/service/cache/redis.js +7 -7
  125. package/lib/service/storage/elasticsearch.js +152 -90
  126. package/lib/service/storage/esWrapper.js +2 -3
  127. package/lib/types/ControllerDefinition.d.ts +3 -3
  128. package/lib/types/ControllerRights.d.ts +22 -0
  129. package/lib/types/ControllerRights.js +23 -0
  130. package/lib/types/HttpStream.d.ts +32 -0
  131. package/lib/types/HttpStream.js +70 -0
  132. package/lib/types/OpenApiDefinition.d.ts +43 -0
  133. package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
  134. package/lib/types/Policy.d.ts +25 -0
  135. package/lib/types/{InternalLogger.js → Policy.js} +2 -2
  136. package/lib/types/PolicyRestrictions.d.ts +21 -0
  137. package/lib/types/PolicyRestrictions.js +23 -0
  138. package/lib/types/Target.d.ts +15 -0
  139. package/lib/types/Target.js +23 -0
  140. package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
  141. package/lib/types/config/ServicesConfiguration.d.ts +2 -2
  142. package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
  143. package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
  144. package/lib/types/index.d.ts +7 -1
  145. package/lib/types/index.js +7 -1
  146. package/lib/util/array.d.ts +11 -0
  147. package/lib/util/array.js +57 -0
  148. package/lib/util/assertType.js +6 -6
  149. package/lib/util/bufferedPassThrough.d.ts +76 -0
  150. package/lib/util/bufferedPassThrough.js +161 -0
  151. package/lib/util/deprecate.js +7 -5
  152. package/lib/util/didYouMean.js +1 -1
  153. package/lib/util/dump-collection.d.ts +3 -0
  154. package/lib/util/dump-collection.js +265 -0
  155. package/lib/util/extractFields.js +2 -2
  156. package/lib/util/inflector.d.ts +8 -0
  157. package/lib/util/inflector.js +16 -0
  158. package/lib/util/requestAssertions.js +7 -7
  159. package/lib/util/wildcard.js +55 -0
  160. package/package-lock.json +538 -78
  161. package/package.json +5 -3
  162. package/lib/api/openApiGenerator.d.ts +0 -7
  163. package/lib/api/openApiGenerator.js +0 -197
  164. package/lib/types/InternalLogger.d.ts +0 -25
@@ -27,6 +27,7 @@ const zlib = require('zlib');
27
27
 
28
28
  const uWS = require('uWebSockets.js');
29
29
 
30
+ const { HttpStream } = require('../../../types');
30
31
  const { Request } = require('../../../api/request');
31
32
  const { KuzzleError } = require('../../../kerror/errors');
32
33
  const Protocol = require('./protocol');
@@ -80,6 +81,8 @@ const HTTP_HEADER_CONNECTION = Buffer.from('Connection');
80
81
  const HTTP_HEADER_CONTENT_LENGTH = Buffer.from('Content-Length');
81
82
  const HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN = Buffer.from('Access-Control-Allow-Origin');
82
83
  const HTTP_HEADER_VARY = Buffer.from('Vary');
84
+ const HTTP_HEADER_TRANSFER_ENCODING = Buffer.from('Transfer-Encoding');
85
+ const CHUNKED = Buffer.from('chunked');
83
86
  const WILDCARD = Buffer.from('*');
84
87
  const ORIGIN = Buffer.from('Origin');
85
88
  const CLOSE = Buffer.from('close');
@@ -121,7 +124,7 @@ class HttpWsProtocol extends Protocol {
121
124
  this.wsConfig = this.parseWebSocketOptions();
122
125
  this.httpConfig = this.parseHttpOptions();
123
126
 
124
- if (!this.wsConfig.enabled && !this.httpConfig.enabled) {
127
+ if (! this.wsConfig.enabled && ! this.httpConfig.enabled) {
125
128
  return false;
126
129
  }
127
130
 
@@ -137,7 +140,7 @@ class HttpWsProtocol extends Protocol {
137
140
  }
138
141
 
139
142
  this.server.listen(entrypoint.config.port, socket => {
140
- if (!socket) {
143
+ if (! socket) {
141
144
  throw new Error(`[http/websocket] fatal: unable to listen to port ${entrypoint.config.port}`);
142
145
  }
143
146
  });
@@ -199,7 +202,7 @@ class HttpWsProtocol extends Protocol {
199
202
  const socket = this.socketByConnectionId.get(data.connectionId);
200
203
  debugWS('notify: %a', data);
201
204
 
202
- if (!socket) {
205
+ if (! socket) {
203
206
  return;
204
207
  }
205
208
 
@@ -214,7 +217,7 @@ class HttpWsProtocol extends Protocol {
214
217
  joinChannel (channel, connectionId) {
215
218
  const socket = this.socketByConnectionId.get(connectionId);
216
219
 
217
- if (!socket) {
220
+ if (! socket) {
218
221
  return;
219
222
  }
220
223
 
@@ -225,7 +228,7 @@ class HttpWsProtocol extends Protocol {
225
228
  leaveChannel (channel, connectionId) {
226
229
  const socket = this.socketByConnectionId.get(connectionId);
227
230
 
228
- if (!socket) {
231
+ if (! socket) {
229
232
  return;
230
233
  }
231
234
 
@@ -239,7 +242,7 @@ class HttpWsProtocol extends Protocol {
239
242
 
240
243
  const socket = this.socketByConnectionId.get(connectionId);
241
244
 
242
- if (!socket) {
245
+ if (! socket) {
243
246
  return;
244
247
  }
245
248
 
@@ -262,7 +265,7 @@ class HttpWsProtocol extends Protocol {
262
265
 
263
266
  wsOnOpenHandler (socket) {
264
267
  const ip = Buffer.from(socket.getRemoteAddressAsText()).toString();
265
- const connection = new ClientConnection(this.name, [ip], {cookie: socket.cookie});
268
+ const connection = new ClientConnection(this.name, [ip], { cookie: socket.cookie });
266
269
 
267
270
  this.entryPoint.newConnection(connection);
268
271
  this.connectionBySocket.set(socket, connection);
@@ -273,7 +276,7 @@ class HttpWsProtocol extends Protocol {
273
276
  wsOnCloseHandler (socket, code, message) {
274
277
  const connection = this.connectionBySocket.get(socket);
275
278
 
276
- if (!connection) {
279
+ if (! connection) {
277
280
  return;
278
281
  }
279
282
 
@@ -291,7 +294,7 @@ class HttpWsProtocol extends Protocol {
291
294
  }
292
295
 
293
296
  wsOnMessageHandler (socket, data) {
294
- if (!data || data.byteLength === 0) {
297
+ if (! data || data.byteLength === 0) {
295
298
  return;
296
299
  }
297
300
 
@@ -405,7 +408,7 @@ class HttpWsProtocol extends Protocol {
405
408
  * @param {Buffer} payload
406
409
  */
407
410
  wsSend (socket, payload) {
408
- if (!this.connectionBySocket.has(socket)) {
411
+ if (! this.connectionBySocket.has(socket)) {
409
412
  return;
410
413
  }
411
414
 
@@ -444,7 +447,7 @@ class HttpWsProtocol extends Protocol {
444
447
  const contentType = message.headers['content-type'];
445
448
 
446
449
  if ( contentType
447
- && !HTTP_ALLOWED_CONTENT_TYPES.some(allowed => contentType.includes(allowed))
450
+ && ! HTTP_ALLOWED_CONTENT_TYPES.some(allowed => contentType.includes(allowed))
448
451
  ) {
449
452
  this.httpSendError(
450
453
  message,
@@ -501,7 +504,7 @@ class HttpWsProtocol extends Protocol {
501
504
  return;
502
505
  }
503
506
 
504
- if (!isLast) {
507
+ if (! isLast) {
505
508
  return;
506
509
  }
507
510
 
@@ -584,6 +587,13 @@ class HttpWsProtocol extends Protocol {
584
587
  return;
585
588
  }
586
589
 
590
+ if (request.result instanceof HttpStream) {
591
+ this.httpSendStream(request, response, request.result, message);
592
+ return;
593
+ }
594
+
595
+ // Send the response in one go
596
+
587
597
  const data = this.httpRequestToResponse(request, message);
588
598
 
589
599
  this.httpCompress(message, data, result => {
@@ -594,38 +604,13 @@ class HttpWsProtocol extends Protocol {
594
604
  request.response.setHeader('Content-Encoding', result.encoding);
595
605
 
596
606
  response.cork(() => {
597
- response.writeStatus(Buffer.from(request.response.status.toString()));
598
-
599
- response.writeHeader(HTTP_HEADER_CONNECTION, CLOSE);
600
-
601
- for (const header of this.httpConfig.headers) {
602
- // If header is missing, add the default one
603
- if (request.response.headers[header[2]] === undefined) {
604
- response.writeHeader(header[0], header[1]);
605
- }
606
- }
607
-
608
- // Access-Control-Allow-Origin Logic
609
- if ( request.response.headers['Access-Control-Allow-Origin'] === undefined
610
- && message.headers
611
- && message.headers.origin
612
- ) {
613
- response.writeHeader(
614
- HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
615
- Buffer.from(message.headers.origin));
616
-
617
- response.writeHeader(HTTP_HEADER_VARY, ORIGIN);
618
- }
619
-
620
- for (const [key, value] of Object.entries(request.response.headers)) {
621
- response.writeHeader(Buffer.from(key), Buffer.from(value.toString()));
622
- }
607
+ this.httpWriteRequestHeaders(request, response, message);
623
608
 
624
609
  const [ success ] = response.tryEnd(
625
610
  result.compressed,
626
611
  result.compressed.length);
627
612
 
628
- if (!success) {
613
+ if (! success) {
629
614
  response.onWritable(offset => {
630
615
  const retryData = result.compressed.subarray(offset);
631
616
  const [ retrySuccess ] = response.tryEnd(
@@ -640,6 +625,177 @@ class HttpWsProtocol extends Protocol {
640
625
  });
641
626
  }
642
627
 
628
+ /**
629
+ *
630
+ * @param {uWS.HttpRequest} request
631
+ * @param {uWS.HttpResponse} response
632
+ * @param {HttpMessage} message
633
+ */
634
+ httpWriteRequestHeaders (request, response, message) {
635
+ response.writeStatus(Buffer.from(request.response.status.toString()));
636
+
637
+ response.writeHeader(HTTP_HEADER_CONNECTION, CLOSE);
638
+
639
+ for (const header of this.httpConfig.headers) {
640
+ // If header is missing, add the default one
641
+ if (request.response.headers[header[2]] === undefined) {
642
+ response.writeHeader(header[0], header[1]);
643
+ }
644
+ }
645
+
646
+ // Access-Control-Allow-Origin Logic
647
+ if ( request.response.headers['Access-Control-Allow-Origin'] === undefined
648
+ && message.headers
649
+ && message.headers.origin
650
+ ) {
651
+ response.writeHeader(
652
+ HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
653
+ Buffer.from(message.headers.origin));
654
+
655
+ response.writeHeader(HTTP_HEADER_VARY, ORIGIN);
656
+ }
657
+
658
+ for (const [key, value] of Object.entries(request.response.headers)) {
659
+ response.writeHeader(Buffer.from(key), Buffer.from(value.toString()));
660
+ }
661
+ }
662
+
663
+ /**
664
+ * Send stream data thorugh the HTTP response
665
+ * @param {HttpRequest} request
666
+ * @param {HttpStream} httpStream - The data stream to send
667
+ * @param {uWS.HttpResponse} response
668
+ * @param {HttpMessage} message
669
+ */
670
+ httpSendStream (request, response, httpStream, message) {
671
+ const streamSizeFixed = typeof httpStream.totalBytes === 'number' && httpStream.totalBytes > 0;
672
+
673
+ if (httpStream.errored) {
674
+ this.httpSendError(
675
+ message,
676
+ response,
677
+ kerror.get('network', 'http', 'stream_errored', httpStream.error.message)
678
+ );
679
+ return;
680
+ }
681
+
682
+ if (httpStream.destroyed) {
683
+ this.httpSendError(
684
+ message,
685
+ response,
686
+ kerror.get('network', 'http', 'stream_closed')
687
+ );
688
+ return;
689
+ }
690
+
691
+ // Remove Content-Length header to avoid conflic with Transfer-Encoding header
692
+ request.response.setHeader('Content-Length', null);
693
+
694
+ // Send Headers in one go
695
+ response.cork(() => {
696
+ this.httpWriteRequestHeaders(request, response, message);
697
+
698
+ if (streamSizeFixed) {
699
+ response.writeHeader(HTTP_HEADER_CONTENT_LENGTH, Buffer.from(httpStream.totalBytes.toString()));
700
+ }
701
+ else {
702
+ response.writeHeader(HTTP_HEADER_TRANSFER_ENCODING, CHUNKED);
703
+ }
704
+ });
705
+
706
+ httpStream.stream.on('data', chunk => {
707
+ // Make a copy of the array buffer
708
+ const arrayBuffer = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength);
709
+
710
+ const arrayBufferOffset = response.getWriteOffset();
711
+
712
+ let backpressure = false;
713
+
714
+ /**
715
+ * Switch method of writing data to the response
716
+ * based on the size of the stream.
717
+ * If the stream has a fixed size we can use the tryEnd method
718
+ */
719
+ if (streamSizeFixed) {
720
+ const [ success, done ] = response.tryEnd(arrayBuffer, httpStream.totalBytes);
721
+ backpressure = ! success;
722
+
723
+ if (done) {
724
+ httpStream.destroy();
725
+ return;
726
+ }
727
+ }
728
+ else {
729
+ const success = response.write(arrayBuffer);
730
+
731
+ backpressure = ! success;
732
+ }
733
+
734
+ // In case of backpressure we need to wait for drainage before sending more data
735
+ if (backpressure) {
736
+ response.arrayBufferOffset = arrayBufferOffset;
737
+ response.arrayBuffer = arrayBuffer;
738
+ httpStream.stream.pause();
739
+
740
+ /**
741
+ * When the stream is drained we can resume sending data,
742
+ * only if the is no backpressure after we wrote the missing chunk data.
743
+ */
744
+ response.onWritable(offset => {
745
+ if (! streamSizeFixed && offset - response.arrayBufferOffset === 0) {
746
+ httpStream.stream.resume();
747
+ return true;
748
+ }
749
+
750
+ let retryBackpressure = false;
751
+ const remainingChunkData = response.arrayBuffer.slice(offset - response.arrayBufferOffset);
752
+
753
+ if (streamSizeFixed) {
754
+ const [ success ] = response.tryEnd(remainingChunkData, httpStream.totalBytes);
755
+
756
+ retryBackpressure = ! success;
757
+ }
758
+ else {
759
+ const success = response.write(remainingChunkData);
760
+
761
+ retryBackpressure = ! success;
762
+ }
763
+
764
+ if (! retryBackpressure) {
765
+ httpStream.stream.resume();
766
+ }
767
+
768
+ return ! retryBackpressure;
769
+ });
770
+ }
771
+ });
772
+
773
+ httpStream.stream.on('end', () => {
774
+ if (httpStream.destroy()) {
775
+ response.end();
776
+ }
777
+ });
778
+
779
+ httpStream.stream.on('close', () => {
780
+ if (httpStream.destroy()) {
781
+ response.end();
782
+ }
783
+ });
784
+
785
+ httpStream.stream.on('error', err => {
786
+ if (httpStream.destroy()) {
787
+ response.end();
788
+ }
789
+
790
+ debugHTTP('[%s] httpSendStream: %s', httpStream.connection.id, err.message);
791
+ });
792
+
793
+ response.onAborted(() => {
794
+ httpStream.destroy();
795
+ });
796
+
797
+ }
798
+
643
799
  /**
644
800
  * Forward an error response to the client
645
801
  *
@@ -680,7 +836,8 @@ class HttpWsProtocol extends Protocol {
680
836
  if (message.headers && message.headers.origin) {
681
837
  if (global.kuzzle.config.internal.allowAllOrigins) {
682
838
  response.writeHeader(HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, WILDCARD);
683
- } else {
839
+ }
840
+ else {
684
841
  response.writeHeader(HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, Buffer.from(message.headers.origin));
685
842
  response.writeHeader(HTTP_HEADER_VARY, ORIGIN);
686
843
  }
@@ -703,13 +860,13 @@ class HttpWsProtocol extends Protocol {
703
860
  * @param {HttpMessage} message
704
861
  * @returns {Buffer}
705
862
  */
706
- httpRequestToResponse(request, message) {
863
+ httpRequestToResponse (request, message) {
707
864
  let data = removeErrorStack(request.response.toJSON());
708
865
 
709
866
  if (message.requestId !== data.requestId) {
710
867
  data.requestId = message.requestId;
711
868
 
712
- if (!data.raw) {
869
+ if (! data.raw) {
713
870
  data.content.requestId = message.requestId;
714
871
  }
715
872
  }
@@ -763,7 +920,7 @@ class HttpWsProtocol extends Protocol {
763
920
  * @param {Buffer} data
764
921
  * @param {Function} callback
765
922
  */
766
- httpCompress(message, data, callback) {
923
+ httpCompress (message, data, callback) {
767
924
  if (message.headers['accept-encoding']) {
768
925
  const encodings = message.headers['accept-encoding']
769
926
  .split(',')
@@ -792,15 +949,15 @@ class HttpWsProtocol extends Protocol {
792
949
 
793
950
  if (algorithm === 'gzip') {
794
951
  zlib.gzip(data, (err, compressed) => callback({
795
- compressed: !err ? compressed : data,
796
- encoding: !err ? 'gzip' : 'identity',
952
+ compressed: ! err ? compressed : data,
953
+ encoding: ! err ? 'gzip' : 'identity',
797
954
  }));
798
955
  return;
799
956
  }
800
957
  else if (algorithm === 'deflate') {
801
958
  zlib.deflate(data, (err, compressed) => callback({
802
- compressed: !err ? compressed : data,
803
- encoding: !err ? 'deflate' : 'identity',
959
+ compressed: ! err ? compressed : data,
960
+ encoding: ! err ? 'deflate' : 'identity',
804
961
  }));
805
962
  return;
806
963
  }
@@ -814,7 +971,7 @@ class HttpWsProtocol extends Protocol {
814
971
 
815
972
  httpUncompress (message, payload, cb) {
816
973
  let encodings = message.headers['content-encoding'];
817
- if (!encodings) {
974
+ if (! encodings) {
818
975
  cb(null, payload);
819
976
  return;
820
977
  }
@@ -99,7 +99,7 @@ class MqttProtocol extends Protocol {
99
99
  const payload = JSON.stringify(data.payload);
100
100
 
101
101
  for (const channel of data.channels) {
102
- this.aedes.publish({payload, topic: channel}, this.publishCallback);
102
+ this.aedes.publish({ payload, topic: channel }, this.publishCallback);
103
103
  }
104
104
  }
105
105
 
@@ -126,14 +126,14 @@ class MqttProtocol extends Protocol {
126
126
 
127
127
  const client = this.connectionsById.get(data.connectionId);
128
128
 
129
- if (!client) {
129
+ if (! client) {
130
130
  return;
131
131
  }
132
132
 
133
133
  const payload = Buffer.from(JSON.stringify(data.payload));
134
134
 
135
135
  data.channels.forEach(topic => {
136
- client.publish({payload, topic}, this.publishCallback);
136
+ client.publish({ payload, topic }, this.publishCallback);
137
137
  });
138
138
  }
139
139
 
@@ -46,7 +46,7 @@ class Protocol {
46
46
  *
47
47
  * @returns {Promise<boolean>}
48
48
  */
49
- async init(name, entryPoint) {
49
+ async init (name, entryPoint) {
50
50
  this.entryPoint = entryPoint;
51
51
 
52
52
  // name should be passed in the constructor
@@ -83,12 +83,12 @@ class Protocol {
83
83
 
84
84
  joinChannel (channel, connectionId) {
85
85
  // do nothing by default
86
- return {channel, connectionId};
86
+ return { channel, connectionId };
87
87
  }
88
88
 
89
89
  leaveChannel (channel, connectionId) {
90
90
  // do nothing by default
91
- return {channel, connectionId};
91
+ return { channel, connectionId };
92
92
  }
93
93
 
94
94
  notify () {
@@ -31,7 +31,7 @@ const HttpRouter = require('./httpRouter');
31
31
  * @param {Kuzzle} kuzzle
32
32
  */
33
33
  class Router {
34
- constructor() {
34
+ constructor () {
35
35
  this.connections = new Map();
36
36
  this.http = new HttpRouter();
37
37
  }
@@ -42,13 +42,14 @@ class Router {
42
42
  * @param {RequestContext} requestContext
43
43
  */
44
44
  newConnection (requestContext) {
45
- if (!requestContext.connection.id || !requestContext.connection.protocol) {
45
+ if (! requestContext.connection.id || ! requestContext.connection.protocol) {
46
46
  global.kuzzle.log.error(kerror.get(
47
47
  'protocol',
48
48
  'runtime',
49
49
  'invalid_connection',
50
50
  JSON.stringify(requestContext)));
51
- } else {
51
+ }
52
+ else {
52
53
  this.connections.set(requestContext.connection.id, requestContext);
53
54
  global.kuzzle.statistics.newConnection(requestContext);
54
55
  }
@@ -62,7 +63,7 @@ class Router {
62
63
  removeConnection (requestContext) {
63
64
  const connId = requestContext.connection.id;
64
65
 
65
- if (!connId || !requestContext.connection.protocol) {
66
+ if (! connId || ! requestContext.connection.protocol) {
66
67
  global.kuzzle.log.error(kerror.get(
67
68
  'protocol',
68
69
  'runtime',
@@ -71,7 +72,7 @@ class Router {
71
72
  return;
72
73
  }
73
74
 
74
- if (!this.connections.has(connId)) {
75
+ if (! this.connections.has(connId)) {
75
76
  global.kuzzle.log.error(kerror.get(
76
77
  'protocol',
77
78
  'runtime',
@@ -131,7 +132,7 @@ class Router {
131
132
  request.input.action = route.action;
132
133
 
133
134
  if (route.deprecated) {
134
- const { deprecated : { since, message } } = route;
135
+ const { deprecated: { since, message } } = route;
135
136
  request.addDeprecation(since, message);
136
137
  }
137
138
 
@@ -24,7 +24,6 @@
24
24
  const path = require('path');
25
25
  const fs = require('fs');
26
26
  const semver = require('semver');
27
- const enforcer = require('openapi-enforcer');
28
27
 
29
28
  const { PluginContext } = require('./pluginContext');
30
29
  const PrivilegedPluginContext = require('./privilegedContext');
@@ -34,7 +33,6 @@ const Manifest = require('./pluginManifest');
34
33
  const { has, isPlainObject } = require('../../util/safeObject');
35
34
 
36
35
  const assertionError = kerror.wrap('plugin', 'assert');
37
- const controllerError = kerror.wrap('plugin', 'controller');
38
36
  const runtimeError = kerror.wrap('plugin', 'runtime');
39
37
 
40
38
  const PLUGIN_NAME_REGEX = /^[a-z-\d]+$/;
@@ -43,7 +41,7 @@ const HTTP_VERBS = ['get', 'head', 'post', 'put', 'delete', 'patch', 'options'];
43
41
  class Plugin {
44
42
  constructor (
45
43
  instance,
46
- { name, application=false, deprecationWarning=true } = {}
44
+ { name, application = false, deprecationWarning = true } = {}
47
45
  ) {
48
46
  this._instance = instance;
49
47
 
@@ -154,24 +152,46 @@ class Plugin {
154
152
 
155
153
  // getters/setters ===========================================================
156
154
 
157
- get instance () { return this._instance; }
155
+ get instance () {
156
+ return this._instance;
157
+ }
158
158
 
159
- get context () { return this._context; }
159
+ get context () {
160
+ return this._context;
161
+ }
160
162
 
161
- get application () { return this._application; }
163
+ get application () {
164
+ return this._application;
165
+ }
162
166
 
163
- get logPrefix () { return `[${this.name}]`; }
167
+ get logPrefix () {
168
+ return `[${this.name}]`;
169
+ }
164
170
 
165
- get config () { return this._config; }
166
- set config (config) { this._config = config; }
171
+ get config () {
172
+ return this._config;
173
+ }
174
+ set config (config) {
175
+ this._config = config;
176
+ }
167
177
 
168
- get version () { return this._version; }
169
- set version (version) { this._version = version; }
178
+ get version () {
179
+ return this._version;
180
+ }
181
+ set version (version) {
182
+ this._version = version;
183
+ }
170
184
 
171
- get deprecationWarning () { return this._deprecationWarning; }
172
- set deprecationWarning (value) { this._deprecationWarning = value; }
185
+ get deprecationWarning () {
186
+ return this._deprecationWarning;
187
+ }
188
+ set deprecationWarning (value) {
189
+ this._deprecationWarning = value;
190
+ }
173
191
 
174
- get name () { return this._name; }
192
+ get name () {
193
+ return this._name;
194
+ }
175
195
  set name (name) {
176
196
  if (! this.constructor.checkName(name)) {
177
197
  this.printDeprecation('Plugin names should be in kebab-case. This behavior will be enforced in futur versions of Kuzzle.');
@@ -180,7 +200,9 @@ class Plugin {
180
200
  this._name = name;
181
201
  }
182
202
 
183
- get manifest () { return this._manifest; }
203
+ get manifest () {
204
+ return this._manifest;
205
+ }
184
206
  set manifest (manifest) {
185
207
  this._manifest = manifest;
186
208
  }
@@ -264,7 +286,7 @@ class Plugin {
264
286
  return PLUGIN_NAME_REGEX.test(name);
265
287
  }
266
288
 
267
- static async checkControllerDefinition (name, definition, { application=false } = {}) {
289
+ static checkControllerDefinition (name, definition, { application = false } = {}) {
268
290
  if (typeof name !== 'string') {
269
291
  throw assertionError.get(
270
292
  'invalid_controller_definition',
@@ -342,10 +364,6 @@ class Plugin {
342
364
  name,
343
365
  `action "${action}" has invalid http properties: ${routeProperties.join(', ')}`);
344
366
  }
345
-
346
- if (route.openapi) {
347
- await checkOpenAPISpecification(name, action, route);
348
- }
349
367
  }
350
368
  }
351
369
  }
@@ -365,48 +383,4 @@ function checkHttpRouteProperties (route, action, name, application) {
365
383
  }
366
384
  }
367
385
 
368
- async function checkOpenAPISpecification (controller, action, route) {
369
- if (! isPlainObject(route.openapi)) {
370
- throw assertionError.get(
371
- 'invalid_controller_definition',
372
- controller,
373
- 'The "openapi" property of the route definition must be an object');
374
- }
375
-
376
- const routePath = route.path.charAt(0) === '/'
377
- ? route.path
378
- : `/_/${route.path}`;
379
-
380
- // Set :param notation to {param}
381
- const formattedPath = routePath.replace(/\/:([^/]*)/g,'/{$1}');
382
-
383
- const { error, warning } = await enforcer({
384
- /* eslint-disable sort-keys */
385
- openapi: '3.0.0',
386
- info: {
387
- title: 'Kuzzle API',
388
- version: require('../../../package').version
389
- },
390
- paths: {
391
- [formattedPath]: {
392
- [route.verb]: route.openapi
393
- }
394
- },
395
- /* eslint-enable sort-keys */
396
- });
397
-
398
- if (warning) {
399
- global.kuzzle.log.warn(`Warning for OpenAPI specification in "${controller}:${action}", ${route.openapi} : ${warning}`);
400
- }
401
-
402
- if (error) {
403
- throw controllerError.get(
404
- 'invalid_openapi_schema',
405
- controller,
406
- action,
407
- route.openapi,
408
- error);
409
- }
410
- }
411
-
412
386
  module.exports = Plugin;
@@ -27,7 +27,7 @@ const kerror = require('../../kerror').wrap('plugin', 'manifest');
27
27
  const AbstractManifest = require('../shared/abstractManifest');
28
28
 
29
29
  class PluginManifest extends AbstractManifest {
30
- constructor(pluginPath) {
30
+ constructor (pluginPath) {
31
31
  super(pluginPath);
32
32
  this.privileged = false;
33
33
  }
@@ -36,11 +36,11 @@ class PluginManifest extends AbstractManifest {
36
36
  super.load();
37
37
 
38
38
  // Ensure ES will accept the plugin name as index
39
- if (!/^[\w-]+$/.test(this.name)) {
39
+ if (! /^[\w-]+$/.test(this.name)) {
40
40
  throw kerror.get('invalid_name', this.path);
41
41
  }
42
42
 
43
- if (!_.isNil(this.raw) && !_.isNil(this.raw.privileged)) {
43
+ if (! _.isNil(this.raw) && ! _.isNil(this.raw.privileged)) {
44
44
  if (typeof this.raw.privileged !== 'boolean') {
45
45
  throw kerror.get(
46
46
  'invalid_privileged',