kuzzle 2.17.7 → 2.17.8
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/bin/start-kuzzle-server +1 -1
- package/lib/api/controllers/adminController.js +1 -1
- package/lib/api/controllers/authController.js +1 -1
- package/lib/api/controllers/baseController.js +1 -1
- package/lib/api/controllers/bulkController.js +1 -1
- package/lib/api/controllers/clusterController.js +1 -1
- package/lib/api/controllers/collectionController.js +1 -1
- package/lib/api/controllers/documentController.js +7 -2
- package/lib/api/controllers/index.js +1 -1
- package/lib/api/controllers/indexController.js +1 -1
- package/lib/api/controllers/memoryStorageController.js +1 -1
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +1 -1
- package/lib/api/controllers/serverController.js +1 -1
- package/lib/api/documentExtractor.js +1 -1
- package/lib/api/funnel.js +1 -1
- package/lib/api/httpRoutes.js +5 -4
- package/lib/api/openapi/OpenApiManager.js +2 -1
- package/lib/api/openapi/components/document/index.d.ts +2 -0
- package/lib/api/openapi/components/document/index.js +6 -1
- package/lib/api/openapi/components/document/mCreateOrReplace.yaml +93 -0
- package/lib/api/openapi/openApiGenerator.js +1 -1
- package/lib/api/rateLimiter.js +1 -1
- package/lib/api/request/kuzzleRequest.js +1 -1
- package/lib/api/request/requestContext.js +1 -1
- package/lib/api/request/requestInput.js +1 -1
- package/lib/api/request/requestResponse.js +1 -1
- package/lib/cluster/command.js +1 -1
- package/lib/cluster/idCardHandler.js +1 -1
- package/lib/cluster/index.js +1 -1
- package/lib/cluster/node.js +8 -8
- package/lib/cluster/publisher.js +1 -1
- package/lib/cluster/state.js +1 -1
- package/lib/cluster/subscriber.js +4 -1
- package/lib/config/documentEventAliases.js +1 -1
- package/lib/config/index.js +1 -1
- package/lib/core/auth/formatProcessing.js +1 -1
- package/lib/core/auth/passportResponse.js +1 -1
- package/lib/core/auth/passportWrapper.js +1 -1
- package/lib/core/auth/tokenManager.js +1 -1
- package/lib/core/backend/applicationManager.js +1 -1
- package/lib/core/backend/backend.js +1 -1
- package/lib/core/backend/backendCluster.js +1 -1
- package/lib/core/backend/backendConfig.js +1 -1
- package/lib/core/backend/backendController.js +1 -1
- package/lib/core/backend/backendErrors.js +1 -1
- package/lib/core/backend/backendHook.js +1 -1
- package/lib/core/backend/backendImport.js +1 -1
- package/lib/core/backend/backendOpenApi.js +1 -1
- package/lib/core/backend/backendPipe.js +1 -1
- package/lib/core/backend/backendPlugin.js +1 -1
- package/lib/core/backend/backendStorage.js +1 -1
- package/lib/core/backend/backendVault.js +1 -1
- package/lib/core/backend/internalLogger.js +1 -1
- package/lib/core/cache/cacheDbEnum.js +1 -1
- package/lib/core/cache/cacheEngine.js +1 -1
- package/lib/core/network/accessLogger.js +1 -1
- package/lib/core/network/clientConnection.js +1 -1
- package/lib/core/network/context.js +1 -1
- package/lib/core/network/entryPoint.js +6 -6
- package/lib/core/network/httpRouter/index.js +1 -1
- package/lib/core/network/httpRouter/routeHandler.js +1 -1
- package/lib/core/network/httpRouter/routePart.js +1 -1
- package/lib/core/network/protocolManifest.js +1 -1
- package/lib/core/network/protocols/httpMessage.js +1 -1
- package/lib/core/network/protocols/httpwsProtocol.js +5 -10
- package/lib/core/network/protocols/internalProtocol.js +1 -1
- package/lib/core/network/protocols/mqttProtocol.js +4 -3
- package/lib/core/network/protocols/protocol.js +1 -1
- package/lib/core/network/router.js +11 -2
- package/lib/core/plugin/plugin.js +1 -1
- package/lib/core/plugin/pluginContext.js +1 -1
- package/lib/core/plugin/pluginManifest.js +1 -1
- package/lib/core/plugin/pluginRepository.js +1 -1
- package/lib/core/plugin/pluginsManager.js +1 -1
- package/lib/core/plugin/privilegedContext.js +1 -1
- package/lib/core/realtime/actionEnum.js +1 -1
- package/lib/core/realtime/channel.js +1 -1
- package/lib/core/realtime/connectionRooms.js +1 -1
- package/lib/core/realtime/hotelClerk.js +66 -24
- package/lib/core/realtime/index.js +1 -1
- package/lib/core/realtime/notification/document.js +1 -1
- package/lib/core/realtime/notification/index.js +1 -1
- package/lib/core/realtime/notification/server.js +1 -1
- package/lib/core/realtime/notification/user.js +1 -1
- package/lib/core/realtime/notifier.js +1 -1
- package/lib/core/realtime/room.js +1 -1
- package/lib/core/realtime/subscription.js +1 -1
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.js +1 -1
- package/lib/core/security/roleRepository.js +1 -1
- package/lib/core/security/securityLoader.js +1 -1
- package/lib/core/security/tokenRepository.js +1 -1
- package/lib/core/security/userRepository.js +1 -1
- package/lib/core/shared/KoncordeWrapper.js +1 -1
- package/lib/core/shared/abstractManifest.js +1 -1
- package/lib/core/shared/repository.js +1 -1
- package/lib/core/shared/sdk/embeddedSdk.js +4 -3
- package/lib/core/shared/sdk/funnelProtocol.d.ts +14 -0
- package/lib/core/shared/sdk/funnelProtocol.js +76 -81
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +1 -1
- package/lib/core/statistics/index.js +1 -1
- package/lib/core/statistics/statistics.js +1 -1
- package/lib/core/storage/clientAdapter.js +1 -1
- package/lib/core/storage/indexCache.js +1 -1
- package/lib/core/storage/storageEngine.js +1 -1
- package/lib/core/storage/storeScopeEnum.js +1 -1
- package/lib/core/validation/baseType.js +1 -1
- package/lib/core/validation/index.js +1 -1
- package/lib/core/validation/types/anything.js +1 -1
- package/lib/core/validation/types/boolean.js +1 -1
- package/lib/core/validation/types/date.js +1 -1
- package/lib/core/validation/types/email.js +1 -1
- package/lib/core/validation/types/enum.js +1 -1
- package/lib/core/validation/types/geoPoint.js +1 -1
- package/lib/core/validation/types/geoShape.js +1 -1
- package/lib/core/validation/types/integer.js +1 -1
- package/lib/core/validation/types/ipAddress.js +1 -1
- package/lib/core/validation/types/numeric.js +1 -1
- package/lib/core/validation/types/object.js +1 -1
- package/lib/core/validation/types/string.js +1 -1
- package/lib/core/validation/types/url.js +1 -1
- package/lib/core/validation/validation.js +1 -1
- package/lib/kerror/codes/index.js +1 -1
- package/lib/kerror/errors/badRequestError.js +1 -1
- package/lib/kerror/errors/externalServiceError.js +1 -1
- package/lib/kerror/errors/forbiddenError.js +1 -1
- package/lib/kerror/errors/gatewayTimeoutError.js +1 -1
- package/lib/kerror/errors/index.js +1 -1
- package/lib/kerror/errors/internalError.js +1 -1
- package/lib/kerror/errors/kuzzleError.js +1 -1
- package/lib/kerror/errors/multipleErrorsError.js +1 -1
- package/lib/kerror/errors/notFoundError.js +1 -1
- package/lib/kerror/errors/partialError.js +1 -1
- package/lib/kerror/errors/pluginImplementationError.js +1 -1
- package/lib/kerror/errors/preconditionError.js +1 -1
- package/lib/kerror/errors/serviceUnavailableError.js +1 -1
- package/lib/kerror/errors/sizeLimitError.js +1 -1
- package/lib/kerror/errors/tooManyRequestsError.js +1 -1
- package/lib/kerror/errors/unauthorizedError.js +1 -1
- package/lib/kerror/index.js +2 -4
- package/lib/kuzzle/dumpGenerator.js +1 -1
- package/lib/kuzzle/event/kuzzleEventEmitter.js +39 -1
- package/lib/kuzzle/event/pipeRunner.js +1 -1
- package/lib/kuzzle/event/waterfall.js +1 -1
- package/lib/kuzzle/index.js +1 -1
- package/lib/kuzzle/internalIndexHandler.js +1 -1
- package/lib/kuzzle/kuzzle.js +1 -1
- package/lib/kuzzle/kuzzleStateEnum.js +1 -1
- package/lib/kuzzle/log.js +1 -1
- package/lib/kuzzle/vault.js +1 -1
- package/lib/model/security/profile.js +1 -1
- package/lib/model/security/rights.js +1 -1
- package/lib/model/security/role.js +1 -1
- package/lib/model/security/token.js +1 -1
- package/lib/model/security/user.js +1 -1
- package/lib/model/storage/apiKey.js +1 -1
- package/lib/model/storage/baseModel.js +1 -1
- package/lib/service/cache/redis.js +1 -1
- package/lib/service/service.js +1 -1
- package/lib/service/storage/elasticsearch.js +5 -5
- package/lib/service/storage/esWrapper.js +1 -1
- package/lib/service/storage/queryTranslator.js +1 -1
- package/lib/types/Controller.js +1 -1
- package/lib/types/ControllerDefinition.js +1 -1
- package/lib/types/Deprecation.js +1 -1
- package/lib/types/EventHandler.js +1 -1
- package/lib/types/KuzzleDocument.d.ts +3 -0
- package/lib/types/Plugin.js +1 -1
- package/lib/types/PluginManifest.js +1 -1
- package/lib/types/RequestPayload.js +1 -1
- package/lib/types/ResponsePayload.js +1 -1
- package/lib/types/StrategyDefinition.js +1 -1
- package/lib/types/Token.js +1 -1
- package/lib/types/User.js +1 -1
- package/lib/types/index.js +1 -1
- package/lib/util/array.js +1 -1
- package/lib/util/assertType.js +1 -1
- package/lib/util/asyncStore.js +1 -1
- package/lib/util/debug.js +1 -1
- package/lib/util/deprecate.js +1 -1
- package/lib/util/didYouMean.js +1 -1
- package/lib/util/extractFields.js +1 -1
- package/lib/util/inflector.js +1 -1
- package/lib/util/koncordeCompat.js +1 -1
- package/lib/util/memoize.js +1 -1
- package/lib/util/mutex.js +1 -1
- package/lib/util/name-generator.js +1 -1
- package/lib/util/promback.js +1 -1
- package/lib/util/requestAssertions.js +1 -1
- package/lib/util/safeObject.js +1 -1
- package/lib/util/stackTrace.js +56 -17
- package/lib/util/wildcard.js +1 -1
- package/package-lock.json +1 -1
- package/package.json +4 -3
- package/lib/core/network/removeErrorStack.js +0 -56
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
3
|
* to power modern apps
|
|
4
4
|
*
|
|
5
|
-
* Copyright 2015-
|
|
5
|
+
* Copyright 2015-2022 Kuzzle
|
|
6
6
|
* mailto: support AT kuzzle.io
|
|
7
7
|
* website: http://kuzzle.io
|
|
8
8
|
*
|
|
@@ -33,7 +33,7 @@ const MqttProtocol = require('./protocols/mqttProtocol');
|
|
|
33
33
|
const InternalProtocol = require('./protocols/internalProtocol');
|
|
34
34
|
const HttpWsProtocol = require('./protocols/httpwsProtocol');
|
|
35
35
|
const Manifest = require('./protocolManifest');
|
|
36
|
-
const
|
|
36
|
+
const { removeStacktrace } = require('../../util/stackTrace');
|
|
37
37
|
const kerror = require('../../kerror');
|
|
38
38
|
const { AccessLogger } = require('./accessLogger');
|
|
39
39
|
|
|
@@ -256,7 +256,7 @@ class EntryPoint {
|
|
|
256
256
|
|
|
257
257
|
const response = _res.response.toJSON();
|
|
258
258
|
|
|
259
|
-
cb(
|
|
259
|
+
cb(removeStacktrace(response));
|
|
260
260
|
});
|
|
261
261
|
}
|
|
262
262
|
|
|
@@ -298,7 +298,7 @@ class EntryPoint {
|
|
|
298
298
|
// --------------------------------------------------------------------
|
|
299
299
|
|
|
300
300
|
_broadcast (data) {
|
|
301
|
-
const sanitized =
|
|
301
|
+
const sanitized = removeStacktrace(data);
|
|
302
302
|
|
|
303
303
|
debug('[server] broadcasting data through all protocols: %a', sanitized);
|
|
304
304
|
|
|
@@ -316,7 +316,7 @@ class EntryPoint {
|
|
|
316
316
|
request.setError(networkError.get('shutting_down'));
|
|
317
317
|
this.logAccess(connection, request);
|
|
318
318
|
|
|
319
|
-
cb(
|
|
319
|
+
cb(removeStacktrace(request.response.toJSON()));
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
_notify (data) {
|
|
@@ -332,7 +332,7 @@ class EntryPoint {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
try {
|
|
335
|
-
this.protocols.get(client.protocol).notify(
|
|
335
|
+
this.protocols.get(client.protocol).notify(removeStacktrace(data));
|
|
336
336
|
}
|
|
337
337
|
catch (e) {
|
|
338
338
|
global.kuzzle.log.error(`[notify] protocol ${client.protocol} failed: ${e.message}`);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
3
|
* to power modern apps
|
|
4
4
|
*
|
|
5
|
-
* Copyright 2015-
|
|
5
|
+
* Copyright 2015-2022 Kuzzle
|
|
6
6
|
* mailto: support AT kuzzle.io
|
|
7
7
|
* website: http://kuzzle.io
|
|
8
8
|
*
|
|
@@ -32,7 +32,7 @@ const { Request } = require('../../../api/request');
|
|
|
32
32
|
const { KuzzleError } = require('../../../kerror/errors');
|
|
33
33
|
const Protocol = require('./protocol');
|
|
34
34
|
const ClientConnection = require('../clientConnection');
|
|
35
|
-
const
|
|
35
|
+
const { removeStacktrace } = require('../../../util/stackTrace');
|
|
36
36
|
const debug = require('../../../util/debug');
|
|
37
37
|
const kerror = require('../../../kerror');
|
|
38
38
|
const HttpMessage = require('./httpMessage');
|
|
@@ -412,7 +412,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
412
412
|
// If a requestId is provided we use it instead of the generated one
|
|
413
413
|
request.id = requestId || request.id;
|
|
414
414
|
|
|
415
|
-
const sanitized =
|
|
415
|
+
const sanitized = removeStacktrace(request.response.toJSON()).content;
|
|
416
416
|
|
|
417
417
|
this.wsSend(socket, Buffer.from(JSON.stringify(sanitized)));
|
|
418
418
|
}
|
|
@@ -831,7 +831,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
831
831
|
? error
|
|
832
832
|
: kerrorHTTP.getFrom(error, 'unexpected_error', error.message);
|
|
833
833
|
|
|
834
|
-
const content = Buffer.from(JSON.stringify(
|
|
834
|
+
const content = Buffer.from(JSON.stringify(removeStacktrace(kerr)));
|
|
835
835
|
|
|
836
836
|
debugHTTP('[%s] httpSendError: %a', message.connection.id, kerr);
|
|
837
837
|
|
|
@@ -866,11 +866,6 @@ class HttpWsProtocol extends Protocol {
|
|
|
866
866
|
}
|
|
867
867
|
}
|
|
868
868
|
|
|
869
|
-
|
|
870
|
-
response.writeHeader(
|
|
871
|
-
HTTP_HEADER_CONTENT_LENGTH,
|
|
872
|
-
Buffer.from(content.length.toString()));
|
|
873
|
-
|
|
874
869
|
response.end(content);
|
|
875
870
|
});
|
|
876
871
|
}
|
|
@@ -884,7 +879,7 @@ class HttpWsProtocol extends Protocol {
|
|
|
884
879
|
* @returns {Buffer}
|
|
885
880
|
*/
|
|
886
881
|
httpRequestToResponse (request, message) {
|
|
887
|
-
let data =
|
|
882
|
+
let data = removeStacktrace(request.response.toJSON());
|
|
888
883
|
|
|
889
884
|
if (message.requestId !== data.requestId) {
|
|
890
885
|
data.requestId = message.requestId;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
3
|
* to power modern apps
|
|
4
4
|
*
|
|
5
|
-
* Copyright 2015-
|
|
5
|
+
* Copyright 2015-2022 Kuzzle
|
|
6
6
|
* mailto: support AT kuzzle.io
|
|
7
7
|
* website: http://kuzzle.io
|
|
8
8
|
*
|
|
@@ -22,12 +22,13 @@
|
|
|
22
22
|
'use strict';
|
|
23
23
|
|
|
24
24
|
const net = require('net');
|
|
25
|
+
|
|
25
26
|
const aedes = require('aedes');
|
|
26
27
|
|
|
27
28
|
const ClientConnection = require('../clientConnection');
|
|
28
29
|
const Protocol = require('./protocol');
|
|
29
30
|
const { Request } = require('../../../api/request');
|
|
30
|
-
const
|
|
31
|
+
const { removeStacktrace } = require('../../../util/stackTrace');
|
|
31
32
|
const kerror = require('../../../kerror').wrap('network', 'mqtt');
|
|
32
33
|
const debug = require('../../../util/debug')('kuzzle:network:protocols:mqtt');
|
|
33
34
|
|
|
@@ -238,7 +239,7 @@ class MqttProtocol extends Protocol {
|
|
|
238
239
|
connection,
|
|
239
240
|
error: kerror.getFrom(error, 'unexpected_error', error.message)
|
|
240
241
|
});
|
|
241
|
-
this._respond(client,
|
|
242
|
+
this._respond(client, removeStacktrace(errReq.response.toJSON()));
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
_authorizePublish (client, packet, callback) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
3
|
* to power modern apps
|
|
4
4
|
*
|
|
5
|
-
* Copyright 2015-
|
|
5
|
+
* Copyright 2015-2022 Kuzzle
|
|
6
6
|
* mailto: support AT kuzzle.io
|
|
7
7
|
* website: http://kuzzle.io
|
|
8
8
|
*
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
const { Request } = require('../../api/request');
|
|
25
25
|
const kerror = require('../../kerror');
|
|
26
26
|
const HttpRouter = require('./httpRouter');
|
|
27
|
+
const { removeStacktrace } = require('../../util/stackTrace');
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* @class Router
|
|
@@ -189,7 +190,15 @@ class Router {
|
|
|
189
190
|
cb(request);
|
|
190
191
|
}
|
|
191
192
|
else {
|
|
192
|
-
global.kuzzle.funnel.execute(mutatedRequest, (err, result) =>
|
|
193
|
+
global.kuzzle.funnel.execute(mutatedRequest, (err, result) => {
|
|
194
|
+
const _res = result || request;
|
|
195
|
+
|
|
196
|
+
if (err && ! _res.error) {
|
|
197
|
+
_res.setError(err);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
cb(removeStacktrace(_res));
|
|
201
|
+
});
|
|
193
202
|
}
|
|
194
203
|
});
|
|
195
204
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
4
4
|
* to power modern apps
|
|
5
5
|
*
|
|
6
|
-
* Copyright 2015-
|
|
6
|
+
* Copyright 2015-2022 Kuzzle
|
|
7
7
|
* mailto: support AT kuzzle.io
|
|
8
8
|
* website: http://kuzzle.io
|
|
9
9
|
*
|
|
@@ -218,20 +218,37 @@ class HotelClerk {
|
|
|
218
218
|
throw kerror.get('api', 'assert', 'koncorde_dsl_error', e.message);
|
|
219
219
|
}
|
|
220
220
|
this.createRoom(normalized);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
221
|
+
/**
|
|
222
|
+
* You might wonder why in the world is there a callback here.
|
|
223
|
+
* The fact is that to prevent the event loop from switching to another function
|
|
224
|
+
* we need to keep descending the execution stack without returning in a function that has been awaited
|
|
225
|
+
* otherwise once we return to the await keyword the event loop will switch to another function.
|
|
226
|
+
*
|
|
227
|
+
* Everything needs to be atomic (multiple operation done without interruption) otherwise we might
|
|
228
|
+
* run into some issues where the room is created but another request has deleted it before we can
|
|
229
|
+
* subscribe to it.
|
|
230
|
+
* All because the subscription was not atomic.
|
|
231
|
+
*
|
|
232
|
+
* So to keep the context of execution we use a lambda that we give to the subscribeToRoom function
|
|
233
|
+
* and we execute it right after the subscription this way we keep descending the execution stack without returning and
|
|
234
|
+
* without switching context.
|
|
235
|
+
*/
|
|
236
|
+
const afterSubscribeCallback = async (subscribed) => {
|
|
237
|
+
if (subscribed) {
|
|
238
|
+
global.kuzzle.call('core:realtime:subscribe:after', normalized.id);
|
|
239
|
+
// @deprecated -- to be removed in next major version
|
|
240
|
+
// we have to recreate the old "diff" object
|
|
241
|
+
await global.kuzzle.pipe('core:hotelClerk:addSubscription', {
|
|
242
|
+
changed: subscribed,
|
|
243
|
+
collection,
|
|
244
|
+
connectionId: request.context.connection.id,
|
|
245
|
+
filters: normalized.filter,
|
|
246
|
+
index,
|
|
247
|
+
roomId: normalized.id,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
const { channel } = await this.subscribeToRoom(normalized.id, request, afterSubscribeCallback);
|
|
235
252
|
const subscription = new subscription_1.Subscription(index, collection, request.input.body, normalized.id, request.context.connection.id, request.context.user);
|
|
236
253
|
global.kuzzle.emit('core:realtime:user:subscribe:after', subscription);
|
|
237
254
|
return {
|
|
@@ -260,10 +277,27 @@ class HotelClerk {
|
|
|
260
277
|
}
|
|
261
278
|
this.createRoom(normalized);
|
|
262
279
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
280
|
+
/**
|
|
281
|
+
* You might wonder why in the world is there a callback here.
|
|
282
|
+
* The fact is that to prevent the event loop from switching to another function
|
|
283
|
+
* we need to keep descending the execution stack without returning in a function that has been awaited
|
|
284
|
+
* otherwise once we return to the await keyword the event loop will switch to another function.
|
|
285
|
+
*
|
|
286
|
+
* Everything needs to be atomic (multiple operation done without interruption) otherwise we might
|
|
287
|
+
* run into some issues where the room is created but another request has deleted it before we can
|
|
288
|
+
* subscribe to it.
|
|
289
|
+
* All because the subscription was not atomic.
|
|
290
|
+
*
|
|
291
|
+
* So to keep the context of execution we use a lambda that we give to the subscribeToRoom function
|
|
292
|
+
* and we execute it right after the subscription this way we keep descending the execution stack without returning and
|
|
293
|
+
* without switching context.
|
|
294
|
+
*/
|
|
295
|
+
const afterSubscribeCallback = async (subscribed, cluster) => {
|
|
296
|
+
if (cluster && subscribed) {
|
|
297
|
+
global.kuzzle.call('core:realtime:subscribe:after', roomId);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const { channel } = await this.subscribeToRoom(roomId, request, afterSubscribeCallback);
|
|
267
301
|
return {
|
|
268
302
|
channel,
|
|
269
303
|
roomId,
|
|
@@ -347,7 +381,7 @@ class HotelClerk {
|
|
|
347
381
|
throw realtimeError.get('too_many_rooms');
|
|
348
382
|
}
|
|
349
383
|
this.koncorde.store(normalized);
|
|
350
|
-
global.kuzzle.
|
|
384
|
+
global.kuzzle.call('core:realtime:room:create:after', normalized);
|
|
351
385
|
// @deprecated -- to be removed in the next major version of kuzzle
|
|
352
386
|
global.kuzzle.emit('room:new', { collection, index, roomId });
|
|
353
387
|
/*
|
|
@@ -395,8 +429,14 @@ class HotelClerk {
|
|
|
395
429
|
global.kuzzle.entryPoint.leaveChannel(channel, connectionId);
|
|
396
430
|
}
|
|
397
431
|
room.removeConnection(connectionId);
|
|
432
|
+
// Used to know whether the room has been deleted or not during the unsubscription
|
|
433
|
+
// We need to store this information for later since we cannot checks if the room exists or has more than 0 subscriber
|
|
434
|
+
// later because the room might have been recreated by the time we need to send the notification
|
|
435
|
+
// all because of the `await this.removeRoom(roomId)`.
|
|
436
|
+
let roomDeleted = false;
|
|
398
437
|
if (room.size === 0) {
|
|
399
438
|
await this.removeRoom(roomId);
|
|
439
|
+
roomDeleted = true;
|
|
400
440
|
}
|
|
401
441
|
// even if the room is deleted for this node, another one may need the
|
|
402
442
|
// notification
|
|
@@ -407,13 +447,13 @@ class HotelClerk {
|
|
|
407
447
|
index: room.index,
|
|
408
448
|
volatile,
|
|
409
449
|
}, requestContext);
|
|
410
|
-
await this.module.notifier.notifyUser(roomId, request, 'out', { count: room.size });
|
|
411
450
|
// Do not send an unsubscription notification if the room has been destroyed
|
|
412
451
|
// because the other nodes already had destroyed it in the full state
|
|
413
452
|
if (notify
|
|
414
453
|
&& this.rooms.has(roomId)
|
|
415
|
-
&& room.channels.size > 0
|
|
416
|
-
|
|
454
|
+
&& room.channels.size > 0
|
|
455
|
+
&& !roomDeleted) {
|
|
456
|
+
global.kuzzle.call('core:realtime:unsubscribe:after', roomId);
|
|
417
457
|
// @deprecated -- to be removed in next major version
|
|
418
458
|
await global.kuzzle.pipe('core:hotelClerk:removeRoomForCustomer', {
|
|
419
459
|
requestContext,
|
|
@@ -424,6 +464,7 @@ class HotelClerk {
|
|
|
424
464
|
},
|
|
425
465
|
});
|
|
426
466
|
}
|
|
467
|
+
await this.module.notifier.notifyUser(roomId, request, 'out', { count: room.size });
|
|
427
468
|
const kuid = global.kuzzle.tokenManager.getKuidFromConnection(connectionId);
|
|
428
469
|
const subscription = new subscription_1.Subscription(room.index, room.collection, undefined, roomId, connectionId, { _id: kuid });
|
|
429
470
|
global.kuzzle.emit('core:realtime:user:unsubscribe:after', {
|
|
@@ -474,7 +515,7 @@ class HotelClerk {
|
|
|
474
515
|
* on the room if it does not already exists.
|
|
475
516
|
*
|
|
476
517
|
*/
|
|
477
|
-
async subscribeToRoom(roomId, request) {
|
|
518
|
+
async subscribeToRoom(roomId, request, afterSubscribeCallback) {
|
|
478
519
|
let subscribed = false;
|
|
479
520
|
let notifyPromise;
|
|
480
521
|
const { scope, users, propagate } = request.input.args;
|
|
@@ -492,6 +533,7 @@ class HotelClerk {
|
|
|
492
533
|
}
|
|
493
534
|
global.kuzzle.entryPoint.joinChannel(channel.name, connectionId);
|
|
494
535
|
room.createChannel(channel);
|
|
536
|
+
await afterSubscribeCallback(subscribed, channel.cluster);
|
|
495
537
|
await notifyPromise;
|
|
496
538
|
return {
|
|
497
539
|
channel: channel.name,
|