kuzzle 2.56.0 → 2.57.0-beta.2
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/dist/bin/copy-binaries.js +71 -4
- package/dist/bin/start-kuzzle-server +191 -97
- package/dist/index.d.ts +31 -1
- package/dist/index.js +45 -2
- package/dist/lib/api/controllers/adminController.d.ts +4 -3
- package/dist/lib/api/controllers/adminController.js +1 -2
- package/dist/lib/api/controllers/authController.d.ts +37 -16
- package/dist/lib/api/controllers/authController.js +88 -39
- package/dist/lib/api/controllers/baseController.d.ts +10 -5
- package/dist/lib/api/controllers/baseController.js +36 -15
- package/dist/lib/api/controllers/bulkController.d.ts +11 -7
- package/dist/lib/api/controllers/bulkController.js +28 -5
- package/dist/lib/api/controllers/clusterController.d.ts +2 -2
- package/dist/lib/api/controllers/clusterController.js +3 -3
- package/dist/lib/api/controllers/collectionController.d.ts +57 -21
- package/dist/lib/api/controllers/collectionController.js +40 -11
- package/dist/lib/api/controllers/debugController.d.ts +1 -1
- package/dist/lib/api/controllers/documentController.d.ts +137 -28
- package/dist/lib/api/controllers/documentController.js +156 -125
- package/dist/lib/api/controllers/index.d.ts +27 -12
- package/dist/lib/api/controllers/index.js +28 -13
- package/dist/lib/api/controllers/indexController.d.ts +17 -10
- package/dist/lib/api/controllers/indexController.js +13 -11
- package/dist/lib/api/controllers/memoryStorageController.d.ts +2 -5
- package/dist/lib/api/controllers/memoryStorageController.js +199 -127
- package/dist/lib/api/controllers/realtimeController.d.ts +19 -9
- package/dist/lib/api/controllers/realtimeController.js +8 -4
- package/dist/lib/api/controllers/securityController.d.ts +42 -29
- package/dist/lib/api/controllers/securityController.js +35 -19
- package/dist/lib/api/controllers/serverController.d.ts +114 -19
- package/dist/lib/api/controllers/serverController.js +69 -29
- package/dist/lib/api/documentExtractor.d.ts +9 -7
- package/dist/lib/api/documentExtractor.js +105 -41
- package/dist/lib/api/funnel.d.ts +131 -29
- package/dist/lib/api/funnel.js +436 -225
- package/dist/lib/api/httpRoutes.d.ts +16 -11
- package/dist/lib/api/httpRoutes.js +272 -2
- package/dist/lib/api/openapi/OpenApiManager.d.ts +1 -1
- package/dist/lib/api/openapi/openApiGenerator.d.ts +1 -1
- package/dist/lib/api/rateLimiter.d.ts +15 -5
- package/dist/lib/api/rateLimiter.js +42 -14
- package/dist/lib/api/request/kuzzleRequest.d.ts +83 -12
- package/dist/lib/api/request/kuzzleRequest.js +88 -23
- package/dist/lib/api/request/requestContext.d.ts +20 -5
- package/dist/lib/api/request/requestContext.js +14 -4
- package/dist/lib/api/request/requestInput.d.ts +37 -6
- package/dist/lib/api/request/requestInput.js +22 -9
- package/dist/lib/api/request/requestResponse.d.ts +45 -9
- package/dist/lib/api/request/requestResponse.js +34 -3
- package/dist/lib/cluster/command.d.ts +131 -37
- package/dist/lib/cluster/command.js +243 -71
- package/dist/lib/cluster/idCardHandler.d.ts +18 -5
- package/dist/lib/cluster/idCardHandler.js +52 -19
- package/dist/lib/cluster/index.d.ts +8 -2
- package/dist/lib/cluster/index.js +6 -2
- package/dist/lib/cluster/node.d.ts +127 -49
- package/dist/lib/cluster/node.js +412 -179
- package/dist/lib/cluster/protobuf/command.proto +18 -0
- package/dist/lib/cluster/protobuf/commandMessages.d.ts +104 -0
- package/dist/lib/cluster/protobuf/commandMessages.js +30 -0
- package/dist/lib/cluster/protobuf/syncMessages.d.ts +184 -0
- package/dist/lib/cluster/protobuf/syncMessages.js +23 -0
- package/dist/lib/cluster/publisher.d.ts +118 -78
- package/dist/lib/cluster/publisher.js +174 -72
- package/dist/lib/cluster/state.d.ts +15 -9
- package/dist/lib/cluster/state.js +12 -8
- package/dist/lib/cluster/subscriber.d.ts +185 -131
- package/dist/lib/cluster/subscriber.js +357 -95
- package/dist/lib/cluster/workers/IDCardRenewer.d.ts +39 -8
- package/dist/lib/cluster/workers/IDCardRenewer.js +88 -23
- package/dist/lib/config/default.config.d.ts +2 -2
- package/dist/lib/config/default.config.js +10 -3
- package/dist/lib/config/documentEventAliases.d.ts +1 -1
- package/dist/lib/config/index.d.ts +2 -5
- package/dist/lib/config/index.js +30 -17
- package/dist/lib/core/auth/formatProcessing.d.ts +3 -3
- package/dist/lib/core/auth/passportResponse.d.ts +1 -1
- package/dist/lib/core/auth/passportWrapper.d.ts +1 -1
- package/dist/lib/core/auth/passportWrapper.js +14 -13
- package/dist/lib/core/auth/tokenManager.d.ts +24 -3
- package/dist/lib/core/auth/tokenManager.js +47 -19
- package/dist/lib/core/backend/applicationManager.d.ts +2 -2
- package/dist/lib/core/backend/backend.d.ts +16 -5
- package/dist/lib/core/backend/backend.js +14 -6
- package/dist/lib/core/backend/backendCluster.d.ts +1 -1
- package/dist/lib/core/backend/backendConfig.d.ts +17 -5
- package/dist/lib/core/backend/backendConfig.js +1 -0
- package/dist/lib/core/backend/backendController.d.ts +1 -1
- package/dist/lib/core/backend/backendController.js +8 -1
- package/dist/lib/core/backend/backendErrors.d.ts +15 -8
- package/dist/lib/core/backend/backendErrors.js +5 -0
- package/dist/lib/core/backend/backendHook.d.ts +1 -1
- package/dist/lib/core/backend/backendImport.d.ts +1 -1
- package/dist/lib/core/backend/backendOpenApi.d.ts +3 -2
- package/dist/lib/core/backend/backendPipe.d.ts +1 -1
- package/dist/lib/core/backend/backendPipe.js +9 -1
- package/dist/lib/core/backend/backendPlugin.d.ts +2 -2
- package/dist/lib/core/backend/backendSubscription.d.ts +2 -2
- package/dist/lib/core/backend/backendVault.d.ts +1 -1
- package/dist/lib/core/backend/backendVault.js +8 -1
- package/dist/lib/core/cache/cacheEngine.d.ts +7 -4
- package/dist/lib/core/cache/cacheEngine.js +25 -8
- package/dist/lib/core/debug/kuzzleDebugger.d.ts +2 -1
- package/dist/lib/core/debug/kuzzleDebugger.js +31 -17
- package/dist/lib/core/network/accessLogger.d.ts +33 -18
- package/dist/lib/core/network/accessLogger.js +135 -73
- package/dist/lib/core/network/clientConnection.d.ts +13 -11
- package/dist/lib/core/network/clientConnection.js +33 -9
- package/dist/lib/core/network/context.d.ts +17 -22
- package/dist/lib/core/network/context.js +43 -26
- package/dist/lib/core/network/entryPoint.d.ts +38 -16
- package/dist/lib/core/network/entryPoint.js +119 -48
- package/dist/lib/core/network/httpRouter/index.d.ts +20 -50
- package/dist/lib/core/network/httpRouter/index.js +61 -75
- package/dist/lib/core/network/httpRouter/routeHandler.d.ts +17 -32
- package/dist/lib/core/network/httpRouter/routeHandler.js +26 -36
- package/dist/lib/core/network/httpRouter/routePart.d.ts +9 -18
- package/dist/lib/core/network/httpRouter/routePart.js +61 -43
- package/dist/lib/core/network/httpRouter/routeTypes.d.ts +3 -0
- package/dist/lib/core/network/httpRouter/routeTypes.js +23 -0
- package/dist/lib/core/network/networkEntryPoint.d.ts +20 -0
- package/dist/lib/core/network/networkEntryPoint.js +23 -0
- package/dist/lib/core/network/protocolManifest.d.ts +5 -4
- package/dist/lib/core/network/protocolManifest.js +6 -3
- package/dist/lib/core/network/protocols/httpMessage.d.ts +25 -18
- package/dist/lib/core/network/protocols/httpMessage.js +14 -11
- package/dist/lib/core/network/protocols/httpwsProtocol.d.ts +84 -93
- package/dist/lib/core/network/protocols/httpwsProtocol.js +284 -129
- package/dist/lib/core/network/protocols/internalProtocol.d.ts +26 -15
- package/dist/lib/core/network/protocols/internalProtocol.js +17 -16
- package/dist/lib/core/network/protocols/mqttProtocol.d.ts +56 -32
- package/dist/lib/core/network/protocols/mqttProtocol.js +91 -44
- package/dist/lib/core/network/protocols/protocol.d.ts +85 -21
- package/dist/lib/core/network/protocols/protocol.js +83 -27
- package/dist/lib/core/network/router.d.ts +13 -22
- package/dist/lib/core/network/router.js +59 -46
- package/dist/lib/core/plugin/plugin.d.ts +57 -51
- package/dist/lib/core/plugin/plugin.js +218 -103
- package/dist/lib/core/plugin/pluginContext.d.ts +54 -11
- package/dist/lib/core/plugin/pluginContext.js +99 -58
- package/dist/lib/core/plugin/pluginManifest.d.ts +6 -2
- package/dist/lib/core/plugin/pluginManifest.js +18 -11
- package/dist/lib/core/plugin/pluginRepository.d.ts +35 -44
- package/dist/lib/core/plugin/pluginRepository.js +35 -50
- package/dist/lib/core/plugin/pluginsManager.d.ts +128 -46
- package/dist/lib/core/plugin/pluginsManager.js +468 -231
- package/dist/lib/core/plugin/privilegedContext.d.ts +4 -9
- package/dist/lib/core/plugin/privilegedContext.js +5 -10
- package/dist/lib/core/realtime/actionEnum.d.ts +12 -21
- package/dist/lib/core/realtime/actionEnum.js +6 -7
- package/dist/lib/core/realtime/channel.d.ts +11 -5
- package/dist/lib/core/realtime/channel.js +17 -2
- package/dist/lib/core/realtime/connectionRooms.d.ts +2 -2
- package/dist/lib/core/realtime/hotelClerk.d.ts +12 -6
- package/dist/lib/core/realtime/hotelClerk.js +29 -11
- package/dist/lib/core/realtime/index.d.ts +8 -3
- package/dist/lib/core/realtime/index.js +12 -5
- package/dist/lib/core/realtime/notification/document.d.ts +54 -25
- package/dist/lib/core/realtime/notification/document.js +10 -13
- package/dist/lib/core/realtime/notification/index.d.ts +9 -3
- package/dist/lib/core/realtime/notification/index.js +10 -4
- package/dist/lib/core/realtime/notification/server.d.ts +7 -10
- package/dist/lib/core/realtime/notification/server.js +4 -7
- package/dist/lib/core/realtime/notification/user.d.ts +45 -21
- package/dist/lib/core/realtime/notification/user.js +8 -9
- package/dist/lib/core/realtime/notifier.d.ts +52 -40
- package/dist/lib/core/realtime/notifier.js +60 -25
- package/dist/lib/core/realtime/room.d.ts +1 -1
- package/dist/lib/core/realtime/subscription.d.ts +11 -6
- package/dist/lib/core/realtime/subscription.js +5 -1
- package/dist/lib/core/security/index.d.ts +14 -6
- package/dist/lib/core/security/index.js +27 -13
- package/dist/lib/core/security/profileRepository.d.ts +24 -19
- package/dist/lib/core/security/profileRepository.js +23 -10
- package/dist/lib/core/security/roleRepository.d.ts +60 -23
- package/dist/lib/core/security/roleRepository.js +122 -53
- package/dist/lib/core/security/securityLoader.d.ts +33 -18
- package/dist/lib/core/security/securityLoader.js +43 -16
- package/dist/lib/core/security/tokenRepository.d.ts +21 -7
- package/dist/lib/core/security/tokenRepository.js +50 -23
- package/dist/lib/core/security/userRepository.d.ts +44 -21
- package/dist/lib/core/security/userRepository.js +59 -19
- package/dist/lib/core/shared/KoncordeWrapper.d.ts +1 -1
- package/dist/lib/core/shared/ObjectRepository.d.ts +80 -18
- package/dist/lib/core/shared/ObjectRepository.js +57 -29
- package/dist/lib/core/shared/abstractManifest.d.ts +21 -8
- package/dist/lib/core/shared/abstractManifest.js +57 -17
- package/dist/lib/core/shared/sdk/embeddedSdk.d.ts +3 -1
- package/dist/lib/core/shared/sdk/embeddedSdk.js +8 -7
- package/dist/lib/core/shared/sdk/funnelProtocol.d.ts +2 -1
- package/dist/lib/core/shared/sdk/funnelProtocol.js +12 -3
- package/dist/lib/core/shared/sdk/impersonatedSdk.d.ts +11 -5
- package/dist/lib/core/shared/sdk/impersonatedSdk.js +22 -9
- package/dist/lib/core/shared/store.d.ts +45 -29
- package/dist/lib/core/shared/store.js +48 -27
- package/dist/lib/core/statistics/statistics.d.ts +1 -1
- package/dist/lib/core/storage/clientAdapter.d.ts +39 -21
- package/dist/lib/core/storage/clientAdapter.js +88 -48
- package/dist/lib/core/storage/indexCache.d.ts +8 -0
- package/dist/lib/core/storage/indexCache.js +16 -7
- package/dist/lib/core/storage/storageEngine.d.ts +7 -6
- package/dist/lib/core/storage/storageEngine.js +11 -8
- package/dist/lib/core/validation/baseType.d.ts +22 -22
- package/dist/lib/core/validation/baseType.js +11 -26
- package/dist/lib/core/validation/specification.d.ts +148 -0
- package/dist/lib/core/validation/specification.js +34 -0
- package/dist/lib/core/validation/typeOptions.d.ts +62 -0
- package/dist/lib/core/validation/typeOptions.js +23 -0
- package/dist/lib/core/validation/types/anything.d.ts +3 -6
- package/dist/lib/core/validation/types/anything.js +7 -7
- package/dist/lib/core/validation/types/boolean.d.ts +5 -12
- package/dist/lib/core/validation/types/boolean.js +7 -12
- package/dist/lib/core/validation/types/date.d.ts +19 -11
- package/dist/lib/core/validation/types/date.js +212 -161
- package/dist/lib/core/validation/types/email.d.ts +7 -11
- package/dist/lib/core/validation/types/email.js +13 -17
- package/dist/lib/core/validation/types/enum.d.ts +7 -11
- package/dist/lib/core/validation/types/enum.js +39 -20
- package/dist/lib/core/validation/types/geoPoint.d.ts +5 -13
- package/dist/lib/core/validation/types/geoPoint.js +10 -15
- package/dist/lib/core/validation/types/geoShape.d.ts +22 -21
- package/dist/lib/core/validation/types/geoShape.js +113 -129
- package/dist/lib/core/validation/types/geoShapeUtils.d.ts +15 -0
- package/dist/lib/core/validation/types/geoShapeUtils.js +75 -0
- package/dist/lib/core/validation/types/integer.d.ts +7 -5
- package/dist/lib/core/validation/types/integer.js +7 -13
- package/dist/lib/core/validation/types/ipAddress.d.ts +7 -11
- package/dist/lib/core/validation/types/ipAddress.js +13 -17
- package/dist/lib/core/validation/types/numeric.d.ts +7 -11
- package/dist/lib/core/validation/types/numeric.js +22 -29
- package/dist/lib/core/validation/types/object.d.ts +8 -15
- package/dist/lib/core/validation/types/object.js +12 -21
- package/dist/lib/core/validation/types/string.d.ts +7 -11
- package/dist/lib/core/validation/types/string.js +22 -29
- package/dist/lib/core/validation/types/url.d.ts +7 -11
- package/dist/lib/core/validation/types/url.js +14 -18
- package/dist/lib/core/validation/validation.d.ts +119 -80
- package/dist/lib/core/validation/validation.js +470 -412
- package/dist/lib/core/validation/validationUtils.d.ts +31 -0
- package/dist/lib/core/validation/validationUtils.js +190 -0
- package/dist/lib/kerror/codes/4-plugin.json +0 -12
- package/dist/lib/kerror/codes/index.d.ts +12 -2
- package/dist/lib/kerror/codes/index.js +5 -4
- package/dist/lib/kerror/errors/badRequestError.d.ts +1 -1
- package/dist/lib/kerror/errors/badRequestError.js +1 -1
- package/dist/lib/kerror/errors/externalServiceError.d.ts +1 -1
- package/dist/lib/kerror/errors/externalServiceError.js +1 -1
- package/dist/lib/kerror/errors/forbiddenError.d.ts +1 -1
- package/dist/lib/kerror/errors/forbiddenError.js +1 -1
- package/dist/lib/kerror/errors/gatewayTimeoutError.d.ts +1 -1
- package/dist/lib/kerror/errors/gatewayTimeoutError.js +1 -1
- package/dist/lib/kerror/errors/internalError.d.ts +1 -1
- package/dist/lib/kerror/errors/internalError.js +1 -1
- package/dist/lib/kerror/errors/kuzzleError.d.ts +32 -3
- package/dist/lib/kerror/errors/kuzzleError.js +21 -7
- package/dist/lib/kerror/errors/multipleErrorsError.d.ts +2 -2
- package/dist/lib/kerror/errors/multipleErrorsError.js +2 -2
- package/dist/lib/kerror/errors/notFoundError.d.ts +1 -1
- package/dist/lib/kerror/errors/notFoundError.js +1 -1
- package/dist/lib/kerror/errors/partialError.d.ts +8 -2
- package/dist/lib/kerror/errors/partialError.js +22 -9
- package/dist/lib/kerror/errors/pluginImplementationError.d.ts +9 -1
- package/dist/lib/kerror/errors/pluginImplementationError.js +9 -3
- package/dist/lib/kerror/errors/preconditionError.d.ts +1 -1
- package/dist/lib/kerror/errors/preconditionError.js +1 -1
- package/dist/lib/kerror/errors/serviceUnavailableError.d.ts +1 -1
- package/dist/lib/kerror/errors/serviceUnavailableError.js +1 -1
- package/dist/lib/kerror/errors/sizeLimitError.d.ts +1 -1
- package/dist/lib/kerror/errors/sizeLimitError.js +1 -1
- package/dist/lib/kerror/errors/tooManyRequestsError.d.ts +1 -1
- package/dist/lib/kerror/errors/tooManyRequestsError.js +1 -1
- package/dist/lib/kerror/errors/unauthorizedError.d.ts +1 -1
- package/dist/lib/kerror/errors/unauthorizedError.js +1 -1
- package/dist/lib/kerror/index.d.ts +19 -13
- package/dist/lib/kerror/index.js +60 -19
- package/dist/lib/kuzzle/Logger.d.ts +2 -2
- package/dist/lib/kuzzle/dumpGenerator.d.ts +12 -8
- package/dist/lib/kuzzle/dumpGenerator.js +130 -62
- package/dist/lib/kuzzle/event/KuzzleEventEmitter.d.ts +18 -9
- package/dist/lib/kuzzle/event/KuzzleEventEmitter.js +45 -18
- package/dist/lib/kuzzle/event/pipeRunner.d.ts +37 -16
- package/dist/lib/kuzzle/event/pipeRunner.js +73 -26
- package/dist/lib/kuzzle/event/waterfall.d.ts +11 -1
- package/dist/lib/kuzzle/event/waterfall.js +38 -13
- package/dist/lib/kuzzle/internalIndexHandler.d.ts +11 -174
- package/dist/lib/kuzzle/internalIndexHandler.js +58 -29
- package/dist/lib/kuzzle/kuzzle.d.ts +25 -10
- package/dist/lib/kuzzle/kuzzle.js +74 -17
- package/dist/lib/kuzzle/kuzzleStateEnum.d.ts +16 -12
- package/dist/lib/kuzzle/kuzzleStateEnum.js +5 -7
- package/dist/lib/kuzzle/vault.d.ts +5 -1
- package/dist/lib/kuzzle/vault.js +29 -17
- package/dist/lib/model/security/profile.d.ts +34 -5
- package/dist/lib/model/security/profile.js +6 -5
- package/dist/lib/model/security/rights.d.ts +12 -4
- package/dist/lib/model/security/rights.js +7 -6
- package/dist/lib/model/security/role.d.ts +8 -4
- package/dist/lib/model/security/role.js +12 -6
- package/dist/lib/model/security/token.d.ts +8 -0
- package/dist/lib/model/security/user.d.ts +8 -2
- package/dist/lib/model/security/user.js +7 -4
- package/dist/lib/model/storage/apiKey.d.ts +55 -26
- package/dist/lib/model/storage/apiKey.js +97 -24
- package/dist/lib/model/storage/baseModel.d.ts +77 -66
- package/dist/lib/model/storage/baseModel.js +21 -34
- package/dist/lib/service/cache/redis.d.ts +53 -36
- package/dist/lib/service/cache/redis.js +148 -71
- package/dist/lib/service/service.d.ts +14 -19
- package/dist/lib/service/service.js +41 -22
- package/dist/lib/service/storage/7/elasticsearch.d.ts +136 -93
- package/dist/lib/service/storage/7/elasticsearch.js +218 -165
- package/dist/lib/service/storage/7/esWrapper.d.ts +30 -13
- package/dist/lib/service/storage/7/esWrapper.js +58 -37
- package/dist/lib/service/storage/8/elasticsearch.d.ts +153 -119
- package/dist/lib/service/storage/8/elasticsearch.js +286 -213
- package/dist/lib/service/storage/8/esWrapper.d.ts +30 -13
- package/dist/lib/service/storage/8/esWrapper.js +59 -38
- package/dist/lib/service/storage/commons/queryTranslator.d.ts +3 -3
- package/dist/lib/service/storage/commons/queryTranslator.js +71 -35
- package/dist/lib/types/ApiRoute.d.ts +12 -0
- package/dist/lib/types/ApiRoute.js +23 -0
- package/dist/lib/types/ClientConnection.d.ts +1 -1
- package/dist/lib/types/EventHandler.d.ts +10 -0
- package/dist/lib/types/Global.d.ts +8 -3
- package/dist/lib/types/HttpMessage.d.ts +2 -2
- package/dist/lib/types/HttpStream.d.ts +1 -1
- package/dist/lib/types/HttpStream.js +3 -1
- package/dist/lib/types/JSONObject.d.ts +9 -0
- package/dist/lib/types/JSONObject.js +23 -0
- package/dist/lib/types/Kuzzle.d.ts +5 -3
- package/dist/lib/types/KuzzleDocument.d.ts +1 -1
- package/dist/lib/types/KuzzleWebSocket.d.ts +24 -0
- package/dist/lib/types/KuzzleWebSocket.js +23 -0
- package/dist/lib/types/OpenApiDefinition.d.ts +1 -1
- package/dist/lib/types/Plugin.d.ts +33 -8
- package/dist/lib/types/PluginInstance.d.ts +67 -0
- package/dist/lib/types/PluginInstance.js +23 -0
- package/dist/lib/types/Policy.d.ts +1 -1
- package/dist/lib/types/Target.d.ts +8 -0
- package/dist/lib/types/Token.d.ts +14 -2
- package/dist/lib/types/config/HttpConfiguration.d.ts +5 -0
- package/dist/lib/types/config/KuzzleConfiguration.d.ts +102 -1
- package/dist/lib/types/config/PluginsConfiguration.d.ts +3 -2
- package/dist/lib/types/config/SecurityConfiguration.d.ts +6 -2
- package/dist/lib/types/config/ServerConfiguration.d.ts +2 -2
- package/dist/lib/types/config/ServicesConfiguration.d.ts +1 -1
- package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.d.ts +131 -0
- package/dist/lib/types/config/cache/BaseCacheRedisConfiguration.js +3 -0
- package/dist/lib/types/config/internalCache/InternalCacheRedisConfiguration.d.ts +2 -106
- package/dist/lib/types/config/publicCache/PublicCacheRedisConfiguration.d.ts +2 -26
- package/dist/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +3 -0
- package/dist/lib/types/controllers/Controller.d.ts +12 -3
- package/dist/lib/types/controllers/ControllerDefinition.d.ts +2 -2
- package/dist/lib/types/controllers/{adminControlller.type.js → adminController.type.js} +1 -1
- package/dist/lib/types/controllers/authController.type.d.ts +2 -2
- package/dist/lib/types/core/auth/formatProcessing.type.d.ts +7 -1
- package/dist/lib/types/errors/ErrorDomains.d.ts +1 -1
- package/dist/lib/types/events/EventGenericDocument.d.ts +10 -9
- package/dist/lib/types/events/EventProtocol.d.ts +4 -4
- package/dist/lib/types/index.d.ts +7 -0
- package/dist/lib/types/index.js +7 -0
- package/dist/lib/types/shared/StoreCollectionsDefinition.d.ts +1 -1
- package/dist/lib/types/storage/7/Elasticsearch.d.ts +62 -13
- package/dist/lib/types/storage/8/Elasticsearch.d.ts +62 -13
- package/dist/lib/util/Inflector.d.ts +4 -1
- package/dist/lib/util/Inflector.js +0 -3
- package/dist/lib/util/assertType.d.ts +24 -27
- package/dist/lib/util/assertType.js +28 -39
- package/dist/lib/util/async.js +19 -6
- package/dist/lib/util/asyncStore.js +1 -1
- package/dist/lib/util/bufferedPassThrough.d.ts +9 -0
- package/dist/lib/util/bufferedPassThrough.js +27 -13
- package/dist/lib/util/bytes.d.ts +1 -1
- package/dist/lib/util/bytes.js +6 -2
- package/dist/lib/util/debug.d.ts +3 -1
- package/dist/lib/util/debug.js +42 -10
- package/dist/lib/util/deprecate.d.ts +9 -1
- package/dist/lib/util/deprecate.js +10 -6
- package/dist/lib/util/didYouMean.d.ts +2 -1
- package/dist/lib/util/didYouMean.js +8 -4
- package/dist/lib/util/distributedLock.d.ts +56 -0
- package/dist/lib/util/distributedLock.js +166 -0
- package/dist/lib/util/dump-collection.d.ts +1 -1
- package/dist/lib/util/dump-collection.js +4 -5
- package/dist/lib/util/extractFields.d.ts +15 -11
- package/dist/lib/util/extractFields.js +8 -9
- package/dist/lib/util/koncordeCompat.d.ts +2 -2
- package/dist/lib/util/koncordeCompat.js +33 -0
- package/dist/lib/util/memoize.d.ts +7 -6
- package/dist/lib/util/memoize.js +3 -3
- package/dist/lib/util/mutex.d.ts +22 -2
- package/dist/lib/util/mutex.js +39 -1
- package/dist/lib/util/name-generator.js +14 -2
- package/dist/lib/util/promback.d.ts +20 -11
- package/dist/lib/util/promback.js +14 -7
- package/dist/lib/util/requestAssertions.d.ts +30 -10
- package/dist/lib/util/requestAssertions.js +125 -121
- package/dist/lib/util/safeObject.d.ts +3 -3
- package/dist/lib/util/safeObject.js +7 -3
- package/dist/lib/util/stackTrace.d.ts +13 -5
- package/dist/lib/util/stackTrace.js +17 -12
- package/dist/lib/util/thrown.d.ts +13 -0
- package/dist/lib/util/thrown.js +46 -0
- package/dist/package.json +26 -19
- package/package.json +26 -19
- package/dist/lib/util/wildcard.d.ts +0 -1
- package/dist/lib/util/wildcard.js +0 -46
- /package/dist/lib/types/controllers/{adminControlller.type.d.ts → adminController.type.d.ts} +0 -0
|
@@ -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,20 +19,47 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
const node_querystring_1 = __importDefault(require("node:querystring"));
|
|
49
|
+
const node_url_1 = __importDefault(require("node:url"));
|
|
50
|
+
const node_zlib_1 = __importDefault(require("node:zlib"));
|
|
51
|
+
const uWebSockets_js_1 = __importDefault(require("uWebSockets.js"));
|
|
52
|
+
const request_1 = require("../../../api/request");
|
|
53
|
+
const kerror = __importStar(require("../../../kerror"));
|
|
54
|
+
const errors_1 = require("../../../kerror/errors");
|
|
55
|
+
const types_1 = require("../../../types");
|
|
56
|
+
const debug_1 = __importDefault(require("../../../util/debug"));
|
|
57
|
+
const stackTrace_1 = require("../../../util/stackTrace");
|
|
58
|
+
const thrown_1 = require("../../../util/thrown");
|
|
59
|
+
const clientConnection_1 = __importDefault(require("../clientConnection"));
|
|
60
|
+
const httpMessage_1 = __importDefault(require("./httpMessage"));
|
|
61
|
+
const protocol_1 = __importDefault(require("./protocol"));
|
|
62
|
+
const debug = debug_1.default;
|
|
35
63
|
const kerrorWS = kerror.wrap("network", "websocket");
|
|
36
64
|
const kerrorHTTP = kerror.wrap("network", "http");
|
|
37
65
|
const debugWS = debug("kuzzle:network:protocols:websocket");
|
|
@@ -65,7 +93,7 @@ const HTTP_ALLOWED_CONTENT_TYPES = [
|
|
|
65
93
|
"application/x-www-form-urlencoded",
|
|
66
94
|
"multipart/form-data",
|
|
67
95
|
];
|
|
68
|
-
const HTTP_SKIPPED_HEADERS = ["content-length", "set-cookie"];
|
|
96
|
+
const HTTP_SKIPPED_HEADERS = new Set(["content-length", "set-cookie"]);
|
|
69
97
|
const HTTP_HEADER_CONNECTION = Buffer.from("Connection");
|
|
70
98
|
const HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN = Buffer.from("Access-Control-Allow-Origin");
|
|
71
99
|
const HTTP_HEADER_SET_COOKIE = Buffer.from("Set-Cookie");
|
|
@@ -76,15 +104,33 @@ const X_KUZZLE_REQUEST_ID = Buffer.from("X-Kuzzle-Request-Id");
|
|
|
76
104
|
const CLOSE = Buffer.from("close");
|
|
77
105
|
const CHARSET_REGEX = /charset=([\w-]+)/i;
|
|
78
106
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
107
|
+
* Whatever failed parsing a WebSocket payload, as the error sent back.
|
|
108
|
+
*
|
|
109
|
+
* Always `network.websocket.unexpected_error`, even for a `KuzzleError`: that
|
|
110
|
+
* is what the `protocol:websocket:afterParsingPayload` pipe and `JSON.parse`
|
|
111
|
+
* have always answered, and the pipe hands over what a plugin threw already
|
|
112
|
+
* wrapped as `plugin.runtime.unexpected_error`.
|
|
113
|
+
*/
|
|
114
|
+
function parsingError(thrown) {
|
|
115
|
+
const error = (0, thrown_1.causeOf)(thrown);
|
|
116
|
+
return kerrorWS.getFrom(error, "unexpected_error", error.message);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* What `new Request()` threw, as the error sent back: a `KuzzleError`
|
|
120
|
+
* (`BadRequestError`) in every in-tree path, forwarded as is.
|
|
81
121
|
*/
|
|
82
|
-
|
|
122
|
+
function asKuzzleError(thrown) {
|
|
123
|
+
if (thrown instanceof errors_1.KuzzleError) {
|
|
124
|
+
return thrown;
|
|
125
|
+
}
|
|
126
|
+
return parsingError(thrown);
|
|
127
|
+
}
|
|
128
|
+
class HttpWsProtocol extends protocol_1.default {
|
|
83
129
|
constructor() {
|
|
84
130
|
super("websocket");
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
87
|
-
this.
|
|
131
|
+
this._server = null;
|
|
132
|
+
this._wsConfig = null;
|
|
133
|
+
this._httpConfig = null;
|
|
88
134
|
// Used to limit the rate of messages on websocket
|
|
89
135
|
this.now = Date.now();
|
|
90
136
|
this.nowInterval = setInterval(() => {
|
|
@@ -98,16 +144,49 @@ class HttpWsProtocol extends Protocol {
|
|
|
98
144
|
this.socketByConnectionId = new Map();
|
|
99
145
|
this.logger = global.kuzzle.log.child("core:network:protocols:httpws");
|
|
100
146
|
}
|
|
101
|
-
|
|
102
|
-
|
|
147
|
+
/**
|
|
148
|
+
* The uWebSockets application and the two parsed configuration blocks.
|
|
149
|
+
* All three are built by `init` — the first from the other two, which are
|
|
150
|
+
* themselves parsed out of a configuration only the entry point has — and
|
|
151
|
+
* every one of the seventeen reads below happens in a handler that the
|
|
152
|
+
* server registered, so none of them can run before `init` returned.
|
|
153
|
+
*
|
|
154
|
+
* Declaring them nullable and dereferencing them anyway is the shape
|
|
155
|
+
* `Protocol.entryPoint` had; these accessors answer the same way, once,
|
|
156
|
+
* instead of at each call site.
|
|
157
|
+
*/
|
|
158
|
+
get server() {
|
|
159
|
+
if (this._server === null) {
|
|
160
|
+
throw new Error("[http/websocket] no server: init() has not been called");
|
|
161
|
+
}
|
|
162
|
+
return this._server;
|
|
163
|
+
}
|
|
164
|
+
get wsConfig() {
|
|
165
|
+
if (this._wsConfig === null) {
|
|
166
|
+
throw new Error("[http/websocket] no websocket configuration: init() has not been called");
|
|
167
|
+
}
|
|
168
|
+
return this._wsConfig;
|
|
169
|
+
}
|
|
170
|
+
get httpConfig() {
|
|
171
|
+
if (this._httpConfig === null) {
|
|
172
|
+
throw new Error("[http/websocket] no http configuration: init() has not been called");
|
|
173
|
+
}
|
|
174
|
+
return this._httpConfig;
|
|
175
|
+
}
|
|
176
|
+
async init(...args) {
|
|
177
|
+
const entrypoint = protocol_1.default.entryPointOf(args);
|
|
178
|
+
// Awaited: the base sets `entryPoint` and `maxRequestSize`, which
|
|
179
|
+
// `parseWebSocketOptions` reads two lines down. It happened to work
|
|
180
|
+
// because that body has no `await` of its own.
|
|
181
|
+
await super.init(entrypoint);
|
|
103
182
|
this.config = entrypoint.config.protocols;
|
|
104
|
-
this.
|
|
105
|
-
this.
|
|
183
|
+
this._wsConfig = this.parseWebSocketOptions();
|
|
184
|
+
this._httpConfig = this.parseHttpOptions();
|
|
106
185
|
if (!this.wsConfig.enabled && !this.httpConfig.enabled) {
|
|
107
186
|
return false;
|
|
108
187
|
}
|
|
109
188
|
// eslint-disable-next-line new-cap
|
|
110
|
-
this.
|
|
189
|
+
this._server = uWebSockets_js_1.default.App();
|
|
111
190
|
if (this.wsConfig.enabled) {
|
|
112
191
|
this.initWebSocket();
|
|
113
192
|
}
|
|
@@ -168,8 +247,8 @@ class HttpWsProtocol extends Protocol {
|
|
|
168
247
|
return;
|
|
169
248
|
}
|
|
170
249
|
const payload = data.payload;
|
|
171
|
-
for (
|
|
172
|
-
payload.room =
|
|
250
|
+
for (const channel of data.channels) {
|
|
251
|
+
payload.room = channel;
|
|
173
252
|
this.wsSend(socket, Buffer.from(JSON.stringify(payload)));
|
|
174
253
|
}
|
|
175
254
|
}
|
|
@@ -204,13 +283,19 @@ class HttpWsProtocol extends Protocol {
|
|
|
204
283
|
headers[header] = value;
|
|
205
284
|
});
|
|
206
285
|
res.upgrade({
|
|
286
|
+
// `last` and `count` are the rate limiter's bookkeeping. Seeding them
|
|
287
|
+
// here is what makes them non-optional on the socket: the limiter
|
|
288
|
+
// incremented `count` on a socket that had never been given one, and
|
|
289
|
+
// only ever read it in the branch that had just written it.
|
|
290
|
+
count: 0,
|
|
207
291
|
headers,
|
|
208
292
|
internal: {},
|
|
293
|
+
last: 0,
|
|
209
294
|
}, req.getHeader("sec-websocket-key"), req.getHeader("sec-websocket-protocol"), req.getHeader("sec-websocket-extensions"), context);
|
|
210
295
|
}
|
|
211
296
|
wsOnOpenHandler(socket) {
|
|
212
297
|
const ip = Buffer.from(socket.getRemoteAddressAsText()).toString();
|
|
213
|
-
const connection = new
|
|
298
|
+
const connection = new clientConnection_1.default(this.name, [ip], socket.headers, socket.internal);
|
|
214
299
|
this.entryPoint.newConnection(connection);
|
|
215
300
|
this.connectionBySocket.set(socket, connection);
|
|
216
301
|
this.socketByConnectionId.set(connection.id, socket);
|
|
@@ -221,7 +306,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
221
306
|
if (!connection) {
|
|
222
307
|
return;
|
|
223
308
|
}
|
|
224
|
-
const reason = Buffer.from(message
|
|
309
|
+
const reason = Buffer.from(message ?? new ArrayBuffer(0)).toString();
|
|
225
310
|
// This hack is only here to indicate that uWebSockets killed the connection early
|
|
226
311
|
// because the received payload exceeded the configured threshold.
|
|
227
312
|
if (code === 1006 && reason.startsWith("Received too big message")) {
|
|
@@ -240,6 +325,12 @@ class HttpWsProtocol extends Protocol {
|
|
|
240
325
|
return;
|
|
241
326
|
}
|
|
242
327
|
const connection = this.connectionBySocket.get(socket);
|
|
328
|
+
// A socket with no connection is one `wsOnCloseHandler` has already torn
|
|
329
|
+
// down: there is nothing left to answer on, not even a rate-limit error.
|
|
330
|
+
// The six reads below took that on trust.
|
|
331
|
+
if (connection === undefined) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
243
334
|
// enforce rate limits
|
|
244
335
|
if (this.wsConfig.rateLimit > 0) {
|
|
245
336
|
if (socket.last === this.now) {
|
|
@@ -269,7 +360,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
269
360
|
So... the error is forwarded to the client, hoping they know
|
|
270
361
|
what to do with it.
|
|
271
362
|
*/
|
|
272
|
-
this.wsSendError(socket, connection,
|
|
363
|
+
this.wsSendError(socket, connection, parsingError(e));
|
|
273
364
|
return;
|
|
274
365
|
}
|
|
275
366
|
if (parsed.p && parsed.p === 1 && Object.keys(parsed).length === 1) {
|
|
@@ -279,10 +370,10 @@ class HttpWsProtocol extends Protocol {
|
|
|
279
370
|
}
|
|
280
371
|
let request;
|
|
281
372
|
try {
|
|
282
|
-
request = new Request(parsed, { connection });
|
|
373
|
+
request = new request_1.Request(parsed, { connection });
|
|
283
374
|
}
|
|
284
375
|
catch (e) {
|
|
285
|
-
this.wsSendError(socket, connection, e, parsed.requestId);
|
|
376
|
+
this.wsSendError(socket, connection, asKuzzleError(e), parsed.requestId);
|
|
286
377
|
return;
|
|
287
378
|
}
|
|
288
379
|
this.entryPoint.execute(connection, request, (result) => {
|
|
@@ -304,9 +395,16 @@ class HttpWsProtocol extends Protocol {
|
|
|
304
395
|
wsOnDrainHandler(socket) {
|
|
305
396
|
socket.cork(() => {
|
|
306
397
|
const buffer = this.backpressureBuffer.get(socket);
|
|
307
|
-
|
|
308
|
-
|
|
398
|
+
if (buffer === undefined) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
// Drain until the socket fills up again, or until there is nothing left
|
|
402
|
+
// to drain — which is what `shift()` answering `undefined` means.
|
|
403
|
+
while (socket.getBufferedAmount() < WS_PER_SOCKET_BACKPRESSURE_BUFFER_SIZE) {
|
|
309
404
|
const payload = buffer.shift();
|
|
405
|
+
if (payload === undefined) {
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
310
408
|
socket.send(payload);
|
|
311
409
|
}
|
|
312
410
|
});
|
|
@@ -320,10 +418,10 @@ class HttpWsProtocol extends Protocol {
|
|
|
320
418
|
* @param {String} requestId @optional
|
|
321
419
|
*/
|
|
322
420
|
wsSendError(socket, connection, error, requestId) {
|
|
323
|
-
const request = new Request({}, { connection, error });
|
|
421
|
+
const request = new request_1.Request({}, { connection, error });
|
|
324
422
|
// If a requestId is provided we use it instead of the generated one
|
|
325
423
|
request.id = requestId || request.id;
|
|
326
|
-
const sanitized = removeStacktrace(request.response.toJSON()).content;
|
|
424
|
+
const sanitized = (0, stackTrace_1.removeStacktrace)(request.response.toJSON()).content;
|
|
327
425
|
this.wsSend(socket, Buffer.from(JSON.stringify(sanitized)));
|
|
328
426
|
}
|
|
329
427
|
/**
|
|
@@ -334,14 +432,19 @@ class HttpWsProtocol extends Protocol {
|
|
|
334
432
|
* @param {Buffer} payload
|
|
335
433
|
*/
|
|
336
434
|
wsSend(socket, payload) {
|
|
337
|
-
|
|
435
|
+
// The three socket maps are written by `wsOnOpenHandler` and cleared by
|
|
436
|
+
// `wsOnCloseHandler`, together: a socket with no backpressure buffer is a
|
|
437
|
+
// socket with no connection. Asking the map that is about to be read
|
|
438
|
+
// answers both questions at once, and replaces a `has()`-then-`get()`
|
|
439
|
+
// pair on two different maps.
|
|
440
|
+
const buffer = this.backpressureBuffer.get(socket);
|
|
441
|
+
if (buffer === undefined) {
|
|
338
442
|
return;
|
|
339
443
|
}
|
|
340
444
|
if (socket.getBufferedAmount() < WS_PER_SOCKET_BACKPRESSURE_BUFFER_SIZE) {
|
|
341
445
|
socket.cork(() => socket.send(payload));
|
|
342
446
|
}
|
|
343
447
|
else {
|
|
344
|
-
const buffer = this.backpressureBuffer.get(socket);
|
|
345
448
|
buffer.push(payload);
|
|
346
449
|
/**
|
|
347
450
|
* Client socket too slow: we need to close it
|
|
@@ -361,10 +464,17 @@ class HttpWsProtocol extends Protocol {
|
|
|
361
464
|
* @param {uWS.HttpRequest} request
|
|
362
465
|
*/
|
|
363
466
|
httpOnMessageHandler(response, request) {
|
|
364
|
-
|
|
365
|
-
|
|
467
|
+
// Collected once, here, and handed to both: a uWS `HttpRequest` has no
|
|
468
|
+
// `headers` property, so the JavaScript's `request.headers` was `undefined`
|
|
469
|
+
// and every HTTP connection carried `{}` — despite `ClientConnection`'s own
|
|
470
|
+
// doc promising the request headers (TD-52).
|
|
471
|
+
const headers = getRequestHeaders(request);
|
|
472
|
+
const connection = new clientConnection_1.default("HTTP/1.1", getHttpIps(response, request), headers);
|
|
473
|
+
const message = new httpMessage_1.default(connection, request, headers);
|
|
366
474
|
debugHTTP("[%s] Received HTTP request: %a", connection.id, message);
|
|
367
|
-
|
|
475
|
+
// `Number(...)`: a header value is a string, and the JavaScript relied on
|
|
476
|
+
// `>` coercing it. Same comparison, spelled.
|
|
477
|
+
if (Number(message.headers["content-length"]) > this.maxRequestSize) {
|
|
368
478
|
this.httpSendError(message, response, HTTP_REQUEST_TOO_LARGE_ERROR);
|
|
369
479
|
return;
|
|
370
480
|
}
|
|
@@ -374,15 +484,19 @@ class HttpWsProtocol extends Protocol {
|
|
|
374
484
|
const contentType = contentTypeParamIndex !== -1
|
|
375
485
|
? contentTypeHeader.slice(0, contentTypeParamIndex).trim()
|
|
376
486
|
: contentTypeHeader.trim();
|
|
377
|
-
if (!this.httpConfig.opts.allowedContentTypes.
|
|
487
|
+
if (!this.httpConfig.opts.allowedContentTypes.includes(contentType)) {
|
|
378
488
|
this.httpSendError(message, response, kerrorHTTP.get("unsupported_content", contentType));
|
|
379
489
|
return;
|
|
380
490
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
491
|
+
// Inside the branch now: a charset is declared by the content-type
|
|
492
|
+
// header, so with no header there is nothing to read one out of. The
|
|
493
|
+
// regex used to be run against `undefined`, which stringifies to
|
|
494
|
+
// "undefined" and matches nothing — the same answer, by accident.
|
|
495
|
+
const charset = CHARSET_REGEX.exec(contentTypeHeader)?.[1];
|
|
496
|
+
if (charset !== undefined && charset.toLowerCase() !== "utf-8") {
|
|
497
|
+
this.httpSendError(message, response, kerrorHTTP.get("unsupported_charset", charset.toLowerCase()));
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
386
500
|
}
|
|
387
501
|
this.httpReadData(message, response, (err) => {
|
|
388
502
|
if (err) {
|
|
@@ -424,7 +538,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
424
538
|
return;
|
|
425
539
|
}
|
|
426
540
|
let resolve;
|
|
427
|
-
|
|
541
|
+
const promise = new Promise((res) => (resolve = res));
|
|
428
542
|
this.httpUncompress(message, payload, async (err, inflated) => {
|
|
429
543
|
if (err) {
|
|
430
544
|
cb(err);
|
|
@@ -446,44 +560,62 @@ class HttpWsProtocol extends Protocol {
|
|
|
446
560
|
async httpParseContent(message, content, cb) {
|
|
447
561
|
const type = message.headers["content-type"] || "";
|
|
448
562
|
if (type.includes("multipart/form-data")) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (!parts) {
|
|
452
|
-
cb();
|
|
563
|
+
if (!this.httpParseMultipart(message, content, type)) {
|
|
564
|
+
cb(HTTP_FILE_TOO_LARGE_ERROR);
|
|
453
565
|
return;
|
|
454
566
|
}
|
|
455
|
-
for (const part of parts) {
|
|
456
|
-
if (part.data.byteLength > this.maxFormFileSize) {
|
|
457
|
-
cb(HTTP_FILE_TOO_LARGE_ERROR);
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
if (part.filename) {
|
|
461
|
-
message.content[part.name] = {
|
|
462
|
-
encoding: part.type,
|
|
463
|
-
file: Buffer.from(part.data).toString("base64"),
|
|
464
|
-
filename: part.filename,
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
message.content[part.name] = Buffer.from(part.data).toString();
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
567
|
}
|
|
472
568
|
else if (type.includes("application/x-www-form-urlencoded")) {
|
|
473
|
-
message.content =
|
|
569
|
+
message.content = node_querystring_1.default.parse(content.toString());
|
|
474
570
|
}
|
|
475
571
|
else {
|
|
476
572
|
try {
|
|
477
573
|
const { payload } = await global.kuzzle.pipe("protocol:http:afterParsingPayload", { message, payload: JSON.parse(content.toString()) });
|
|
478
574
|
message.content = payload;
|
|
479
575
|
}
|
|
480
|
-
catch
|
|
576
|
+
catch {
|
|
577
|
+
// The parser error is deliberately dropped: `body_parse_failed` already
|
|
578
|
+
// carries the offending payload, and the raw message leaks internals of
|
|
579
|
+
// whichever parser ran to the client.
|
|
481
580
|
cb(kerrorHTTP.get("body_parse_failed", content.toString().slice(0, 50)));
|
|
482
581
|
return;
|
|
483
582
|
}
|
|
484
583
|
}
|
|
485
584
|
cb();
|
|
486
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* Fills `message.content` from a multipart/form-data payload, file parts
|
|
588
|
+
* base64-encoded and the rest read as text.
|
|
589
|
+
*
|
|
590
|
+
* Returns false when a part is over the configured `maxFormFileSize`, leaving
|
|
591
|
+
* the caller to raise the error — a boolean rather than a throw so
|
|
592
|
+
* `httpParseContent` keeps answering through its callback, and split out of
|
|
593
|
+
* it to stay under the cognitive complexity ceiling the `.js` → `.ts` rename
|
|
594
|
+
* re-scores as new code.
|
|
595
|
+
*/
|
|
596
|
+
httpParseMultipart(message, content, contentType) {
|
|
597
|
+
// Handed down rather than read off the message again: the caller only
|
|
598
|
+
// reaches here because it read that header and found "multipart/form-data"
|
|
599
|
+
// in it.
|
|
600
|
+
const parts = uWebSockets_js_1.default.getParts(content, contentType);
|
|
601
|
+
message.content = {};
|
|
602
|
+
if (!parts) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
605
|
+
for (const part of parts) {
|
|
606
|
+
if (part.data.byteLength > this.httpConfig.opts.maxFormFileSize) {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
message.content[part.name] = part.filename
|
|
610
|
+
? {
|
|
611
|
+
encoding: part.type,
|
|
612
|
+
file: Buffer.from(part.data).toString("base64"),
|
|
613
|
+
filename: part.filename,
|
|
614
|
+
}
|
|
615
|
+
: Buffer.from(part.data).toString();
|
|
616
|
+
}
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
487
619
|
httpProcessRequest(response, message) {
|
|
488
620
|
debugHTTP("[%s] httpProcessRequest: %a", message.connection.id, message);
|
|
489
621
|
if (response.aborted) {
|
|
@@ -496,7 +628,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
496
628
|
if (response.aborted) {
|
|
497
629
|
return;
|
|
498
630
|
}
|
|
499
|
-
if (request.result instanceof HttpStream) {
|
|
631
|
+
if (request.result instanceof types_1.HttpStream) {
|
|
500
632
|
this.httpSendStream(request, response, request.result, message);
|
|
501
633
|
return;
|
|
502
634
|
}
|
|
@@ -539,8 +671,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
539
671
|
}
|
|
540
672
|
// Access-Control-Allow-Origin Logic
|
|
541
673
|
if (request.response.headers["Access-Control-Allow-Origin"] === undefined &&
|
|
542
|
-
message.headers
|
|
543
|
-
message.headers.origin) {
|
|
674
|
+
message.headers?.origin) {
|
|
544
675
|
response.writeHeader(HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, Buffer.from(message.headers.origin));
|
|
545
676
|
response.writeHeader(HTTP_HEADER_VARY, ORIGIN);
|
|
546
677
|
}
|
|
@@ -551,7 +682,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
551
682
|
}
|
|
552
683
|
for (const [key, value] of Object.entries(request.response.headers)) {
|
|
553
684
|
// Skip some headers that are not allowed to be sent or modified
|
|
554
|
-
if (HTTP_SKIPPED_HEADERS.
|
|
685
|
+
if (HTTP_SKIPPED_HEADERS.has(key.toLowerCase())) {
|
|
555
686
|
continue;
|
|
556
687
|
}
|
|
557
688
|
response.writeHeader(Buffer.from(key), Buffer.from(value.toString()));
|
|
@@ -574,8 +705,12 @@ class HttpWsProtocol extends Protocol {
|
|
|
574
705
|
this.httpSendError(message, response, kerror.get("network", "http", "stream_closed"));
|
|
575
706
|
return;
|
|
576
707
|
}
|
|
577
|
-
// Remove Content-Length header to avoid
|
|
578
|
-
|
|
708
|
+
// Remove Content-Length header to avoid a conflict with the
|
|
709
|
+
// Transfer-Encoding header. `setHeader(name, null)` was the spelling, and
|
|
710
|
+
// it sets the header to the string "null" — `String(value)` — rather than
|
|
711
|
+
// removing anything. It went unnoticed because `httpWriteRequestHeaders`
|
|
712
|
+
// skips content-length on its way to the wire.
|
|
713
|
+
request.response.removeHeader("Content-Length");
|
|
579
714
|
// Send Headers in one go
|
|
580
715
|
response.cork(() => {
|
|
581
716
|
this.httpWriteRequestHeaders(request, response, message);
|
|
@@ -584,7 +719,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
584
719
|
// Make a copy of the array buffer
|
|
585
720
|
const arrayBuffer = chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength);
|
|
586
721
|
const arrayBufferOffset = response.getWriteOffset();
|
|
587
|
-
let backpressure
|
|
722
|
+
let backpressure;
|
|
588
723
|
/**
|
|
589
724
|
* Switch method of writing data to the response
|
|
590
725
|
* based on the size of the stream.
|
|
@@ -616,7 +751,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
616
751
|
httpStream.stream.resume();
|
|
617
752
|
return true;
|
|
618
753
|
}
|
|
619
|
-
let retryBackpressure
|
|
754
|
+
let retryBackpressure;
|
|
620
755
|
const remainingChunkData = response.arrayBuffer.slice(offset - response.arrayBufferOffset);
|
|
621
756
|
if (streamSizeFixed) {
|
|
622
757
|
const [success] = response.tryEnd(remainingChunkData, httpStream.totalBytes);
|
|
@@ -647,7 +782,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
647
782
|
if (httpStream.destroy()) {
|
|
648
783
|
response.end();
|
|
649
784
|
}
|
|
650
|
-
debugHTTP("[%s] httpSendStream: %s",
|
|
785
|
+
debugHTTP("[%s] httpSendStream: %s", message.connection.id, err.message);
|
|
651
786
|
});
|
|
652
787
|
response.onAborted(() => {
|
|
653
788
|
httpStream.destroy();
|
|
@@ -661,12 +796,12 @@ class HttpWsProtocol extends Protocol {
|
|
|
661
796
|
* @param {Error} error
|
|
662
797
|
*/
|
|
663
798
|
httpSendError(message, response, error) {
|
|
664
|
-
const kerr = error instanceof KuzzleError
|
|
799
|
+
const kerr = error instanceof errors_1.KuzzleError
|
|
665
800
|
? error
|
|
666
801
|
: kerrorHTTP.getFrom(error, "unexpected_error", error.message);
|
|
667
|
-
const content = Buffer.from(JSON.stringify(removeStacktrace(kerr)));
|
|
802
|
+
const content = Buffer.from(JSON.stringify((0, stackTrace_1.removeStacktrace)(kerr)));
|
|
668
803
|
debugHTTP("[%s] httpSendError: %a", message.connection.id, kerr);
|
|
669
|
-
this.entryPoint.logAccess(message.connection, new Request(message, {
|
|
804
|
+
this.entryPoint.logAccess(message.connection, new request_1.Request(message, {
|
|
670
805
|
connectionId: message.connection.id,
|
|
671
806
|
error: kerr,
|
|
672
807
|
}), message);
|
|
@@ -680,7 +815,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
680
815
|
response.writeHeader(header[0], header[1]);
|
|
681
816
|
}
|
|
682
817
|
// Access-Control-Allow-Origin Logic
|
|
683
|
-
if (message.headers
|
|
818
|
+
if (message.headers?.origin) {
|
|
684
819
|
if (global.kuzzle.config.internal.allowAllOrigins) {
|
|
685
820
|
response.writeHeader(HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, WILDCARD);
|
|
686
821
|
}
|
|
@@ -701,7 +836,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
701
836
|
* @returns {Buffer}
|
|
702
837
|
*/
|
|
703
838
|
httpRequestToResponse(request, message) {
|
|
704
|
-
|
|
839
|
+
const data = (0, stackTrace_1.removeStacktrace)(request.response.toJSON());
|
|
705
840
|
if (message.requestId !== data.requestId) {
|
|
706
841
|
data.requestId = message.requestId;
|
|
707
842
|
if (!data.raw) {
|
|
@@ -709,39 +844,44 @@ class HttpWsProtocol extends Protocol {
|
|
|
709
844
|
}
|
|
710
845
|
}
|
|
711
846
|
debugHTTP("HTTP request response: %a", data);
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
else if (typeof data.content === "object") {
|
|
717
|
-
/*
|
|
718
|
-
This object can be either a Buffer object, a stringified Buffer object,
|
|
719
|
-
or anything else.
|
|
720
|
-
In the former two cases, we create a new Buffer object, and in the
|
|
721
|
-
latter, we stringify t he content.
|
|
722
|
-
*/
|
|
723
|
-
if (data.content instanceof Buffer ||
|
|
724
|
-
(data.content.type === "Buffer" && Array.isArray(data.content.data))) {
|
|
725
|
-
data = data.content;
|
|
726
|
-
}
|
|
727
|
-
else {
|
|
728
|
-
data = JSON.stringify(data.content);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
else {
|
|
732
|
-
// scalars are sent as strings
|
|
733
|
-
data = data.content.toString();
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
else {
|
|
847
|
+
// Early returns rather than reassigning `data` from the response object to
|
|
848
|
+
// a string or a Buffer: the variable changed type under itself, which is
|
|
849
|
+
// what the conversion could not express. Each branch is the original one.
|
|
850
|
+
if (!data.raw) {
|
|
737
851
|
let indent = 0;
|
|
738
|
-
|
|
739
|
-
|
|
852
|
+
// `url.parse` is legacy, but `message.url` is a path with no origin, so
|
|
853
|
+
// the WHATWG parser needs a base, and it throws where this one tolerates
|
|
854
|
+
// a malformed URL. Swapping them changes what a bad request does, which
|
|
855
|
+
// is not a decision the conversion gets to make.
|
|
856
|
+
const parsedUrl = node_url_1.default.parse(message.url, true); // NOSONAR
|
|
857
|
+
if (parsedUrl.query?.pretty !== undefined) {
|
|
740
858
|
indent = 2;
|
|
741
859
|
}
|
|
742
|
-
|
|
860
|
+
return Buffer.from(JSON.stringify(data.content, undefined, indent));
|
|
861
|
+
}
|
|
862
|
+
const content = data.content;
|
|
863
|
+
if (content === null || content === undefined) {
|
|
864
|
+
return Buffer.from("");
|
|
865
|
+
}
|
|
866
|
+
if (typeof content !== "object") {
|
|
867
|
+
// scalars are sent as strings
|
|
868
|
+
return Buffer.from(content.toString());
|
|
743
869
|
}
|
|
744
|
-
|
|
870
|
+
/*
|
|
871
|
+
This object can be either a Buffer object, a stringified Buffer object,
|
|
872
|
+
or anything else.
|
|
873
|
+
In the former two cases, we create a new Buffer object, and in the
|
|
874
|
+
latter, we stringify the content.
|
|
875
|
+
*/
|
|
876
|
+
if (content instanceof Buffer) {
|
|
877
|
+
return Buffer.from(content);
|
|
878
|
+
}
|
|
879
|
+
if (content.type === "Buffer" && Array.isArray(content.data)) {
|
|
880
|
+
// `Buffer.from(content)` and `Buffer.from(content.data)` build the same
|
|
881
|
+
// bytes for the JSON form of a Buffer; the latter is the one that types.
|
|
882
|
+
return Buffer.from(content.data);
|
|
883
|
+
}
|
|
884
|
+
return Buffer.from(JSON.stringify(content));
|
|
745
885
|
}
|
|
746
886
|
/**
|
|
747
887
|
* Compress an outgoing message according to the
|
|
@@ -756,12 +896,16 @@ class HttpWsProtocol extends Protocol {
|
|
|
756
896
|
const encodings = message.headers["accept-encoding"]
|
|
757
897
|
.split(",")
|
|
758
898
|
.map((e) => e.trim().toLowerCase());
|
|
899
|
+
// Undefined until a gzip or deflate encoding is seen: the list may hold
|
|
900
|
+
// neither, which is the `identity` answer at the bottom of the method.
|
|
759
901
|
let algorithm;
|
|
760
902
|
let priority = -1;
|
|
761
903
|
for (const encoding of encodings) {
|
|
762
904
|
if (encoding.startsWith("gzip") || encoding.startsWith("deflate")) {
|
|
763
|
-
|
|
764
|
-
|
|
905
|
+
const [_algorithm, rawPriority = "q=0"] = encoding.split(";");
|
|
906
|
+
// `|| 0` was a number falling into `parseFloat`, which stringifies it
|
|
907
|
+
// back; `"0"` is the same value without the round trip.
|
|
908
|
+
const _priority = Number.parseFloat(rawPriority.split("=")[1] || "0");
|
|
765
909
|
if (_priority > priority) {
|
|
766
910
|
algorithm = _algorithm;
|
|
767
911
|
priority = _priority;
|
|
@@ -774,14 +918,14 @@ class HttpWsProtocol extends Protocol {
|
|
|
774
918
|
}
|
|
775
919
|
}
|
|
776
920
|
if (algorithm === "gzip") {
|
|
777
|
-
|
|
921
|
+
node_zlib_1.default.gzip(data, (err, compressed) => callback({
|
|
778
922
|
compressed: !err ? compressed : data,
|
|
779
923
|
encoding: !err ? "gzip" : "identity",
|
|
780
924
|
}));
|
|
781
925
|
return;
|
|
782
926
|
}
|
|
783
927
|
else if (algorithm === "deflate") {
|
|
784
|
-
|
|
928
|
+
node_zlib_1.default.deflate(data, (err, compressed) => callback({
|
|
785
929
|
compressed: !err ? compressed : data,
|
|
786
930
|
encoding: !err ? "deflate" : "identity",
|
|
787
931
|
}));
|
|
@@ -794,12 +938,14 @@ class HttpWsProtocol extends Protocol {
|
|
|
794
938
|
});
|
|
795
939
|
}
|
|
796
940
|
httpUncompress(message, payload, cb) {
|
|
797
|
-
|
|
798
|
-
if (!
|
|
941
|
+
const header = message.headers["content-encoding"];
|
|
942
|
+
if (!header) {
|
|
799
943
|
cb(null, payload);
|
|
800
944
|
return;
|
|
801
945
|
}
|
|
802
|
-
|
|
946
|
+
// A separate name for the list: the JavaScript reassigned the header string
|
|
947
|
+
// to the array parsed out of it.
|
|
948
|
+
const encodings = header.split(",").map((e) => e.trim().toLowerCase());
|
|
803
949
|
if (encodings.length > this.httpConfig.opts.maxEncodingLayers) {
|
|
804
950
|
cb(kerrorHTTP.get("too_many_encodings"));
|
|
805
951
|
return;
|
|
@@ -820,7 +966,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
820
966
|
this.httpUncompressStep(encodings, payload, cb, index + 1);
|
|
821
967
|
}
|
|
822
968
|
else if (encoding === "gzip" || encoding === "deflate") {
|
|
823
|
-
const fn = encoding === "gzip" ?
|
|
969
|
+
const fn = encoding === "gzip" ? node_zlib_1.default.gunzip : node_zlib_1.default.inflate;
|
|
824
970
|
fn(payload, (err, inflated) => {
|
|
825
971
|
if (err) {
|
|
826
972
|
cb(err);
|
|
@@ -840,7 +986,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
840
986
|
return { enabled: false };
|
|
841
987
|
}
|
|
842
988
|
let idleTimeout = cfg.idleTimeout;
|
|
843
|
-
const compression = cfg.compression ?
|
|
989
|
+
const compression = cfg.compression ? uWebSockets_js_1.default.SHARED_COMPRESSOR : uWebSockets_js_1.default.DISABLED;
|
|
844
990
|
if (idleTimeout === 0 || idleTimeout < 1000) {
|
|
845
991
|
idleTimeout = DEFAULT_IDLE_TIMEOUT;
|
|
846
992
|
this.logger.warn(`[websocket] The "idleTimeout" parameter can neither be deactivated or be set with a value lower than 1000. Defaulted to ${DEFAULT_IDLE_TIMEOUT}.`);
|
|
@@ -872,16 +1018,17 @@ class HttpWsProtocol extends Protocol {
|
|
|
872
1018
|
}
|
|
873
1019
|
// precomputes default headers
|
|
874
1020
|
const httpCfg = global.kuzzle.config.http;
|
|
875
|
-
|
|
1021
|
+
// uWS writes Buffers, and the raw name is kept in a third slot for the
|
|
1022
|
+
// lookup that follows. Built as that triplet rather than rewritten into
|
|
1023
|
+
// one in place: the loop read back the slots it was overwriting, so every
|
|
1024
|
+
// row was `string | Buffer | undefined` to the compiler and the widened
|
|
1025
|
+
// element type was the only thing holding the shape together.
|
|
1026
|
+
const rawHeaders = [
|
|
876
1027
|
["Access-Control-Allow-Headers", httpCfg.accessControlAllowHeaders],
|
|
877
1028
|
["Access-Control-Allow-Methods", httpCfg.accessControlAllowMethods],
|
|
878
1029
|
["Content-Type", "application/json"],
|
|
879
1030
|
];
|
|
880
|
-
|
|
881
|
-
header[2] = header[0]; // Save the raw header name in the third slot
|
|
882
|
-
header[0] = Buffer.from(header[0]);
|
|
883
|
-
header[1] = Buffer.from(header[1]);
|
|
884
|
-
}
|
|
1031
|
+
const headers = rawHeaders.map(([name, value]) => [Buffer.from(name), Buffer.from(value), name]);
|
|
885
1032
|
return {
|
|
886
1033
|
enabled: cfg.enabled,
|
|
887
1034
|
headers,
|
|
@@ -904,6 +1051,14 @@ class HttpWsProtocol extends Protocol {
|
|
|
904
1051
|
* @param {uWS.HttpRequest} request
|
|
905
1052
|
* @return {Array.<string>}
|
|
906
1053
|
*/
|
|
1054
|
+
/**
|
|
1055
|
+
* Collects a uWS request's headers, which are only reachable through `forEach`.
|
|
1056
|
+
*/
|
|
1057
|
+
function getRequestHeaders(request) {
|
|
1058
|
+
const headers = {};
|
|
1059
|
+
request.forEach((name, value) => (headers[name] = value));
|
|
1060
|
+
return headers;
|
|
1061
|
+
}
|
|
907
1062
|
function getHttpIps(response, request) {
|
|
908
1063
|
const ips = [Buffer.from(response.getRemoteAddressAsText()).toString()];
|
|
909
1064
|
const forwardHeader = request.getHeader("x-forwarded-for");
|