kuzzle 2.27.1 → 2.27.3
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.
- package/README.md +12 -6
- package/lib/api/controllers/adminController.js +9 -9
- package/lib/api/controllers/bulkController.js +9 -9
- package/lib/api/controllers/collectionController.js +17 -17
- package/lib/api/controllers/documentController.js +51 -51
- package/lib/api/controllers/indexController.js +4 -4
- package/lib/api/controllers/memoryStorageController.js +11 -11
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +67 -70
- package/lib/api/controllers/serverController.js +5 -5
- package/lib/api/documentExtractor.js +3 -3
- package/lib/api/funnel.js +43 -43
- package/lib/api/rateLimiter.js +1 -1
- package/lib/cluster/command.js +4 -4
- package/lib/cluster/idCardHandler.js +1 -1
- package/lib/cluster/node.js +55 -55
- package/lib/cluster/subscriber.js +33 -33
- package/lib/cluster/workers/IDCardRenewer.js +4 -4
- package/lib/config/index.js +24 -24
- package/lib/core/auth/passportWrapper.js +6 -6
- package/lib/core/cache/cacheEngine.js +20 -20
- package/lib/core/network/accessLogger.js +15 -15
- package/lib/core/network/entryPoint.js +12 -12
- package/lib/core/network/httpRouter/index.js +4 -4
- package/lib/core/network/httpRouter/routePart.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +41 -41
- package/lib/core/network/protocols/internalProtocol.js +2 -2
- package/lib/core/network/protocols/mqttProtocol.js +9 -9
- package/lib/core/network/protocols/protocol.js +3 -3
- package/lib/core/network/router.js +7 -7
- package/lib/core/plugin/plugin.js +23 -23
- package/lib/core/plugin/pluginManifest.js +1 -1
- package/lib/core/plugin/pluginsManager.js +62 -62
- package/lib/core/realtime/notifier.js +14 -14
- package/lib/core/security/README.md +223 -0
- package/lib/core/security/roleRepository.js +18 -18
- package/lib/core/security/securityLoader.js +7 -7
- package/lib/core/security/userRepository.js +16 -16
- package/lib/core/shared/README.md +3 -0
- package/lib/core/shared/abstractManifest.js +1 -1
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +11 -11
- package/lib/core/statistics/statistics.js +15 -15
- package/lib/core/storage/clientAdapter.js +61 -61
- package/lib/core/validation/baseType.js +1 -1
- package/lib/core/validation/types/date.js +1 -1
- package/lib/core/validation/types/enum.js +5 -5
- package/lib/core/validation/types/geoShape.js +13 -13
- package/lib/core/validation/types/numeric.js +2 -2
- package/lib/core/validation/types/string.js +2 -2
- package/lib/core/validation/validation.js +71 -71
- package/lib/kerror/codes/index.js +23 -23
- package/lib/kuzzle/dumpGenerator.js +17 -17
- package/lib/kuzzle/event/kuzzleEventEmitter.js +9 -9
- package/lib/kuzzle/event/pipeRunner.js +2 -2
- package/lib/kuzzle/internalIndexHandler.js +8 -8
- package/lib/kuzzle/log.js +2 -2
- package/lib/kuzzle/vault.js +4 -4
- package/lib/model/security/role.js +3 -1
- package/lib/model/security/user.js +3 -1
- package/lib/model/storage/apiKey.js +3 -3
- package/lib/model/storage/baseModel.js +7 -7
- package/lib/service/cache/redis.js +3 -3
- package/lib/service/storage/elasticsearch.js +52 -52
- package/lib/service/storage/esWrapper.js +3 -3
- package/lib/service/storage/queryTranslator.js +2 -2
- package/lib/util/assertType.js +1 -1
- package/lib/util/deprecate.js +3 -3
- package/lib/util/extractFields.js +2 -2
- package/lib/util/wildcard.js +1 -1
- package/package.json +69 -81
package/lib/api/funnel.js
CHANGED
|
@@ -101,7 +101,7 @@ class Funnel {
|
|
|
101
101
|
* @returns {Boolean}
|
|
102
102
|
*/
|
|
103
103
|
global.kuzzle.onAsk("kuzzle:api:funnel:controller:isNative", (name) =>
|
|
104
|
-
this.isNativeController(name)
|
|
104
|
+
this.isNativeController(name),
|
|
105
105
|
);
|
|
106
106
|
|
|
107
107
|
/**
|
|
@@ -129,7 +129,7 @@ class Funnel {
|
|
|
129
129
|
this.controllers.set("ms", msController);
|
|
130
130
|
|
|
131
131
|
const initPromises = Array.from(this.controllers.keys()).map((ctrl) =>
|
|
132
|
-
this.controllers.get(ctrl).init()
|
|
132
|
+
this.controllers.get(ctrl).init(),
|
|
133
133
|
);
|
|
134
134
|
|
|
135
135
|
return Bluebird.all(initPromises);
|
|
@@ -183,7 +183,7 @@ class Funnel {
|
|
|
183
183
|
const isRequestFromDebugSession = get(
|
|
184
184
|
request,
|
|
185
185
|
"context.connection.misc.internal.debugSession",
|
|
186
|
-
false
|
|
186
|
+
false,
|
|
187
187
|
);
|
|
188
188
|
|
|
189
189
|
if (this.overloaded) {
|
|
@@ -197,11 +197,11 @@ class Funnel {
|
|
|
197
197
|
const overloadPercentage =
|
|
198
198
|
Math.round(
|
|
199
199
|
(10000 * this.pendingRequestsQueue.length) /
|
|
200
|
-
global.kuzzle.config.limits.requestsBufferSize
|
|
200
|
+
global.kuzzle.config.limits.requestsBufferSize,
|
|
201
201
|
) / 100;
|
|
202
202
|
global.kuzzle.emit("core:overload", overloadPercentage);
|
|
203
203
|
global.kuzzle.log.warn(
|
|
204
|
-
`[!WARNING!] Kuzzle overloaded: ${overloadPercentage}%. Delaying requests
|
|
204
|
+
`[!WARNING!] Kuzzle overloaded: ${overloadPercentage}%. Delaying requests...`,
|
|
205
205
|
);
|
|
206
206
|
|
|
207
207
|
this.overloadWarned = true;
|
|
@@ -245,7 +245,7 @@ class Funnel {
|
|
|
245
245
|
if (!this.pendingRequestsById.has(request.internalId)) {
|
|
246
246
|
this.pendingRequestsById.set(
|
|
247
247
|
request.internalId,
|
|
248
|
-
new PendingRequest(request, fn, context)
|
|
248
|
+
new PendingRequest(request, fn, context),
|
|
249
249
|
);
|
|
250
250
|
|
|
251
251
|
if (isRequestFromDebugSession) {
|
|
@@ -291,7 +291,7 @@ class Funnel {
|
|
|
291
291
|
if (!request.input.controller || !request.input.controller.length) {
|
|
292
292
|
callback(
|
|
293
293
|
kerror.get("api", "assert", "missing_argument", "controller"),
|
|
294
|
-
request
|
|
294
|
+
request,
|
|
295
295
|
);
|
|
296
296
|
return 1;
|
|
297
297
|
}
|
|
@@ -299,7 +299,7 @@ class Funnel {
|
|
|
299
299
|
if (!request.input.action || !request.input.action.length) {
|
|
300
300
|
callback(
|
|
301
301
|
kerror.get("api", "assert", "missing_argument", "action"),
|
|
302
|
-
request
|
|
302
|
+
request,
|
|
303
303
|
);
|
|
304
304
|
return 1;
|
|
305
305
|
}
|
|
@@ -320,9 +320,9 @@ class Funnel {
|
|
|
320
320
|
"assert",
|
|
321
321
|
"mutually_exclusive",
|
|
322
322
|
"index, collection",
|
|
323
|
-
"targets"
|
|
323
|
+
"targets",
|
|
324
324
|
),
|
|
325
|
-
request
|
|
325
|
+
request,
|
|
326
326
|
);
|
|
327
327
|
return 1;
|
|
328
328
|
}
|
|
@@ -334,18 +334,18 @@ class Funnel {
|
|
|
334
334
|
) {
|
|
335
335
|
debug(
|
|
336
336
|
"Reject request, unauthorized origin %s",
|
|
337
|
-
request.input.headers.origin
|
|
337
|
+
request.input.headers.origin,
|
|
338
338
|
);
|
|
339
339
|
return this._executeError(
|
|
340
340
|
kerror.get(
|
|
341
341
|
"api",
|
|
342
342
|
"process",
|
|
343
343
|
"unauthorized_origin",
|
|
344
|
-
request.input.headers.origin
|
|
344
|
+
request.input.headers.origin,
|
|
345
345
|
),
|
|
346
346
|
request,
|
|
347
347
|
true,
|
|
348
|
-
callback
|
|
348
|
+
callback,
|
|
349
349
|
);
|
|
350
350
|
}
|
|
351
351
|
|
|
@@ -365,7 +365,7 @@ class Funnel {
|
|
|
365
365
|
req.input.controller,
|
|
366
366
|
req.input.action,
|
|
367
367
|
req.id,
|
|
368
|
-
req.input
|
|
368
|
+
req.input,
|
|
369
369
|
);
|
|
370
370
|
|
|
371
371
|
global.kuzzle.asyncStore.run(() => {
|
|
@@ -397,7 +397,7 @@ class Funnel {
|
|
|
397
397
|
debug(
|
|
398
398
|
"Request %s successfully executed. Result: %a",
|
|
399
399
|
modifiedRequest.id,
|
|
400
|
-
processResult
|
|
400
|
+
processResult,
|
|
401
401
|
);
|
|
402
402
|
|
|
403
403
|
return global.kuzzle
|
|
@@ -418,7 +418,7 @@ class Funnel {
|
|
|
418
418
|
debug(
|
|
419
419
|
"Error processing request %s: %a",
|
|
420
420
|
modifiedRequest.id,
|
|
421
|
-
err
|
|
421
|
+
err,
|
|
422
422
|
);
|
|
423
423
|
return global.kuzzle
|
|
424
424
|
.pipe("request:afterExecution", {
|
|
@@ -431,8 +431,8 @@ class Funnel {
|
|
|
431
431
|
pipeEvent.error,
|
|
432
432
|
pipeEvent.request,
|
|
433
433
|
true,
|
|
434
|
-
callback
|
|
435
|
-
)
|
|
434
|
+
callback,
|
|
435
|
+
),
|
|
436
436
|
);
|
|
437
437
|
});
|
|
438
438
|
})
|
|
@@ -449,14 +449,14 @@ class Funnel {
|
|
|
449
449
|
pipeEvent.error,
|
|
450
450
|
pipeEvent.request,
|
|
451
451
|
true,
|
|
452
|
-
callback
|
|
453
|
-
)
|
|
452
|
+
callback,
|
|
453
|
+
),
|
|
454
454
|
);
|
|
455
455
|
});
|
|
456
456
|
});
|
|
457
457
|
},
|
|
458
458
|
this,
|
|
459
|
-
request
|
|
459
|
+
request,
|
|
460
460
|
);
|
|
461
461
|
|
|
462
462
|
return executing ? 0 : -1;
|
|
@@ -489,7 +489,7 @@ class Funnel {
|
|
|
489
489
|
global.kuzzle.log.error(
|
|
490
490
|
err instanceof Error && !(err instanceof KuzzleError)
|
|
491
491
|
? `${err.message}\n${err.stack}`
|
|
492
|
-
: err
|
|
492
|
+
: err,
|
|
493
493
|
);
|
|
494
494
|
|
|
495
495
|
if (
|
|
@@ -511,7 +511,7 @@ class Funnel {
|
|
|
511
511
|
.join("-");
|
|
512
512
|
|
|
513
513
|
global.kuzzle.dump(
|
|
514
|
-
`handled-${errorType.toLocaleLowerCase()}-${errorMessage}
|
|
514
|
+
`handled-${errorType.toLocaleLowerCase()}-${errorMessage}`,
|
|
515
515
|
);
|
|
516
516
|
}
|
|
517
517
|
|
|
@@ -559,7 +559,7 @@ class Funnel {
|
|
|
559
559
|
"security",
|
|
560
560
|
"token",
|
|
561
561
|
"verification_error",
|
|
562
|
-
"Both token and cookie are present, could not decide which one to use"
|
|
562
|
+
"Both token and cookie are present, could not decide which one to use",
|
|
563
563
|
);
|
|
564
564
|
}
|
|
565
565
|
|
|
@@ -579,7 +579,7 @@ class Funnel {
|
|
|
579
579
|
|
|
580
580
|
request.context.token = await global.kuzzle.ask(
|
|
581
581
|
"core:security:token:verify",
|
|
582
|
-
token
|
|
582
|
+
token,
|
|
583
583
|
);
|
|
584
584
|
} catch (error) {
|
|
585
585
|
await global.kuzzle.pipe("request:onUnauthorized", request);
|
|
@@ -590,19 +590,19 @@ class Funnel {
|
|
|
590
590
|
|
|
591
591
|
request.context.user = await global.kuzzle.ask(
|
|
592
592
|
"core:security:user:get",
|
|
593
|
-
userId
|
|
593
|
+
userId,
|
|
594
594
|
);
|
|
595
595
|
|
|
596
596
|
// If we have a token, link the connection with the token,
|
|
597
597
|
// this way the connection can be notified when the token has expired.
|
|
598
598
|
if (
|
|
599
599
|
global.kuzzle.config.internal.notifiableProtocols.includes(
|
|
600
|
-
request.context.connection.protocol
|
|
600
|
+
request.context.connection.protocol,
|
|
601
601
|
)
|
|
602
602
|
) {
|
|
603
603
|
global.kuzzle.tokenManager.link(
|
|
604
604
|
request.context.token,
|
|
605
|
-
request.context.connection.id
|
|
605
|
+
request.context.connection.id,
|
|
606
606
|
);
|
|
607
607
|
}
|
|
608
608
|
|
|
@@ -615,7 +615,7 @@ class Funnel {
|
|
|
615
615
|
userId === "-1" ? "unauthorized" : "forbidden",
|
|
616
616
|
request.input.controller,
|
|
617
617
|
request.input.action,
|
|
618
|
-
request.context.user._id
|
|
618
|
+
request.context.user._id,
|
|
619
619
|
);
|
|
620
620
|
|
|
621
621
|
request.setError(error);
|
|
@@ -662,7 +662,7 @@ class Funnel {
|
|
|
662
662
|
_request = await this.performDocumentAlias(_request, "before");
|
|
663
663
|
_request = await global.kuzzle.pipe(
|
|
664
664
|
this.getEventName(_request, "before"),
|
|
665
|
-
_request
|
|
665
|
+
_request,
|
|
666
666
|
);
|
|
667
667
|
|
|
668
668
|
const responseData = await doAction(controller, _request);
|
|
@@ -688,7 +688,7 @@ class Funnel {
|
|
|
688
688
|
|
|
689
689
|
_request = await global.kuzzle.pipe(
|
|
690
690
|
this.getEventName(_request, "after"),
|
|
691
|
-
_request
|
|
691
|
+
_request,
|
|
692
692
|
);
|
|
693
693
|
|
|
694
694
|
_request = await this.performDocumentAlias(_request, "after");
|
|
@@ -727,14 +727,14 @@ class Funnel {
|
|
|
727
727
|
|
|
728
728
|
const alias = this.documentEventAliases.mirrorList[action];
|
|
729
729
|
const event = `${this.documentEventAliases.namespace}:${prefix}${capitalize(
|
|
730
|
-
alias
|
|
730
|
+
alias,
|
|
731
731
|
)}`;
|
|
732
732
|
const extractor = new DocumentExtractor(request);
|
|
733
733
|
|
|
734
734
|
const documents = await global.kuzzle.pipe(
|
|
735
735
|
event,
|
|
736
736
|
extractor.extract(),
|
|
737
|
-
request
|
|
737
|
+
request,
|
|
738
738
|
);
|
|
739
739
|
|
|
740
740
|
return extractor.insert(documents);
|
|
@@ -767,7 +767,7 @@ class Funnel {
|
|
|
767
767
|
try {
|
|
768
768
|
const updated = await global.kuzzle.pipe(
|
|
769
769
|
this.getEventName(modifiedRequest, "error"),
|
|
770
|
-
modifiedRequest
|
|
770
|
+
modifiedRequest,
|
|
771
771
|
);
|
|
772
772
|
|
|
773
773
|
// If there is no pipe attached on this event, the same request is
|
|
@@ -788,7 +788,7 @@ class Funnel {
|
|
|
788
788
|
try {
|
|
789
789
|
const updated = await global.kuzzle.pipe(
|
|
790
790
|
"request:onError",
|
|
791
|
-
modifiedRequest
|
|
791
|
+
modifiedRequest,
|
|
792
792
|
);
|
|
793
793
|
|
|
794
794
|
if (updated === modifiedRequest) {
|
|
@@ -849,7 +849,7 @@ class Funnel {
|
|
|
849
849
|
throw processError.get(
|
|
850
850
|
"action_not_found",
|
|
851
851
|
request.input.controller,
|
|
852
|
-
request.input.action
|
|
852
|
+
request.input.action,
|
|
853
853
|
);
|
|
854
854
|
}
|
|
855
855
|
}
|
|
@@ -899,7 +899,7 @@ class Funnel {
|
|
|
899
899
|
throw processError.get(
|
|
900
900
|
"incompatible_sdk_version",
|
|
901
901
|
sdkVersion,
|
|
902
|
-
"Kuzzle v2"
|
|
902
|
+
"Kuzzle v2",
|
|
903
903
|
);
|
|
904
904
|
}
|
|
905
905
|
|
|
@@ -960,13 +960,13 @@ class Funnel {
|
|
|
960
960
|
// If there is room to play bufferized requests, do it now. If not, retry later
|
|
961
961
|
const quantityToInject = Math.min(
|
|
962
962
|
this.pendingRequestsQueue.length,
|
|
963
|
-
global.kuzzle.config.limits.concurrentRequests - this.concurrentRequests
|
|
963
|
+
global.kuzzle.config.limits.concurrentRequests - this.concurrentRequests,
|
|
964
964
|
);
|
|
965
965
|
|
|
966
966
|
if (quantityToInject > 0) {
|
|
967
967
|
for (let i = 0; i < quantityToInject; i++) {
|
|
968
968
|
const pendingItem = this.pendingRequestsById.get(
|
|
969
|
-
this.pendingRequestsQueue.peekFront()
|
|
969
|
+
this.pendingRequestsQueue.peekFront(),
|
|
970
970
|
);
|
|
971
971
|
|
|
972
972
|
try {
|
|
@@ -974,7 +974,7 @@ class Funnel {
|
|
|
974
974
|
this.throttle(
|
|
975
975
|
pendingItem.fn,
|
|
976
976
|
pendingItem.context,
|
|
977
|
-
pendingItem.request
|
|
977
|
+
pendingItem.request,
|
|
978
978
|
)
|
|
979
979
|
) {
|
|
980
980
|
this.pendingRequestsQueue.shift();
|
|
@@ -1000,7 +1000,7 @@ class Funnel {
|
|
|
1000
1000
|
) {
|
|
1001
1001
|
this.overloadWarned = false;
|
|
1002
1002
|
global.kuzzle.log.info(
|
|
1003
|
-
"End of overloaded state. Resuming normal activity."
|
|
1003
|
+
"End of overloaded state. Resuming normal activity.",
|
|
1004
1004
|
);
|
|
1005
1005
|
this.lastOverloadTime = now;
|
|
1006
1006
|
}
|
|
@@ -1020,7 +1020,7 @@ class Funnel {
|
|
|
1020
1020
|
"plugin",
|
|
1021
1021
|
"runtime",
|
|
1022
1022
|
"unexpected_error",
|
|
1023
|
-
error.message
|
|
1023
|
+
error.message,
|
|
1024
1024
|
);
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
@@ -1084,7 +1084,7 @@ function doAction(controller, request) {
|
|
|
1084
1084
|
"controller",
|
|
1085
1085
|
"invalid_action_response",
|
|
1086
1086
|
request.input.controller,
|
|
1087
|
-
request.input.action
|
|
1087
|
+
request.input.action,
|
|
1088
1088
|
);
|
|
1089
1089
|
}
|
|
1090
1090
|
|
package/lib/api/rateLimiter.js
CHANGED
package/lib/cluster/command.js
CHANGED
|
@@ -140,7 +140,7 @@ class ClusterCommand {
|
|
|
140
140
|
async handleHandshake(data) {
|
|
141
141
|
const decoder = this.protoroot.lookupType("HandshakeRequest");
|
|
142
142
|
const { nodeId, ip, lastMessageId } = decoder.toObject(
|
|
143
|
-
decoder.decode(data)
|
|
143
|
+
decoder.decode(data),
|
|
144
144
|
);
|
|
145
145
|
|
|
146
146
|
const added = await this.node.addNode(nodeId, ip, lastMessageId);
|
|
@@ -189,7 +189,7 @@ class ClusterCommand {
|
|
|
189
189
|
// no response from the remote node in a timely fashion... retrying
|
|
190
190
|
// with another one
|
|
191
191
|
global.kuzzle.log.warn(
|
|
192
|
-
`Unable to fetch a full state from node ${id} (no response received)
|
|
192
|
+
`Unable to fetch a full state from node ${id} (no response received)`,
|
|
193
193
|
);
|
|
194
194
|
idx = (idx + 1) % nodes.length;
|
|
195
195
|
} finally {
|
|
@@ -229,7 +229,7 @@ class ClusterCommand {
|
|
|
229
229
|
const encoded = encoder.encode(encoder.create(payload)).finish();
|
|
230
230
|
|
|
231
231
|
const responses = await Bluebird.map(nodes, ({ id, ip }) =>
|
|
232
|
-
this._sendSingleHandshake(id, ip, encoded)
|
|
232
|
+
this._sendSingleHandshake(id, ip, encoded),
|
|
233
233
|
);
|
|
234
234
|
|
|
235
235
|
const decoder = this.protoroot.lookupType("HandshakeResponse");
|
|
@@ -270,7 +270,7 @@ class ClusterCommand {
|
|
|
270
270
|
[, response] = await req.receive();
|
|
271
271
|
} catch (e) {
|
|
272
272
|
global.kuzzle.log.warn(
|
|
273
|
-
`Couldn't complete handshake with node ${id}: no response received
|
|
273
|
+
`Couldn't complete handshake with node ${id}: no response received`,
|
|
274
274
|
);
|
|
275
275
|
} finally {
|
|
276
276
|
req.close();
|
|
@@ -276,7 +276,7 @@ class ClusterIdCardHandler {
|
|
|
276
276
|
if (!this.idCard) {
|
|
277
277
|
return false;
|
|
278
278
|
}
|
|
279
|
-
return
|
|
279
|
+
return global.kuzzle.ask("core:cache:internal:store", this.nodeIdKey, JSON.stringify(this.idCard.serialize()), { onlyIfNew: creation, ttl: this.refreshDelay * this.refreshMultiplier });
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
exports.ClusterIdCardHandler = ClusterIdCardHandler;
|