kuzzle 2.16.8 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/lib/api/controllers/adminController.js +7 -6
- package/lib/api/controllers/authController.js +11 -11
- package/lib/api/controllers/baseController.js +60 -3
- package/lib/api/controllers/clusterController.js +1 -1
- package/lib/api/controllers/collectionController.js +7 -5
- package/lib/api/controllers/documentController.js +130 -17
- package/lib/api/controllers/indexController.js +1 -1
- package/lib/api/controllers/memoryStorageController.js +39 -38
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +49 -49
- package/lib/api/controllers/serverController.js +73 -27
- package/lib/api/documentExtractor.js +3 -3
- package/lib/api/funnel.js +40 -21
- package/lib/api/httpRoutes.js +9 -4
- package/lib/api/openapi/OpenApiManager.d.ts +11 -0
- package/lib/api/openapi/OpenApiManager.js +96 -0
- package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
- package/lib/api/openapi/{document → components/document}/index.js +7 -2
- package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
- package/lib/api/openapi/components/document/validate.yaml +42 -0
- package/lib/api/openapi/components/index.d.ts +2 -0
- package/lib/api/openapi/components/index.js +18 -0
- package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
- package/lib/api/openapi/index.d.ts +1 -2
- package/lib/api/openapi/index.js +1 -5
- package/lib/api/openapi/openApiGenerator.d.ts +7 -0
- package/lib/api/openapi/openApiGenerator.js +133 -0
- package/lib/api/request/kuzzleRequest.d.ts +11 -11
- package/lib/api/request/kuzzleRequest.js +38 -48
- package/lib/cluster/node.js +9 -9
- package/lib/cluster/publisher.js +1 -1
- package/lib/cluster/subscriber.js +1 -1
- package/lib/cluster/workers/IDCardRenewer.js +13 -4
- package/lib/config/default.config.js +1 -0
- package/lib/config/index.js +6 -6
- package/lib/core/auth/passportResponse.js +6 -6
- package/lib/core/auth/passportWrapper.js +5 -5
- package/lib/core/backend/backend.d.ts +5 -1
- package/lib/core/backend/backend.js +12 -8
- package/lib/core/backend/backendConfig.d.ts +5 -1
- package/lib/core/backend/backendConfig.js +4 -0
- package/lib/core/backend/backendOpenApi.d.ts +9 -0
- package/lib/core/backend/backendOpenApi.js +69 -0
- package/lib/core/backend/index.d.ts +1 -0
- package/lib/core/backend/index.js +1 -0
- package/lib/core/network/accessLogger.js +6 -6
- package/lib/core/network/clientConnection.js +1 -1
- package/lib/core/network/entryPoint.js +5 -5
- package/lib/core/network/httpRouter/index.js +5 -5
- package/lib/core/network/httpRouter/routeHandler.js +3 -3
- package/lib/core/network/httpRouter/routePart.js +5 -5
- package/lib/core/network/protocolManifest.js +1 -1
- package/lib/core/network/protocols/httpMessage.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +207 -46
- package/lib/core/network/protocols/mqttProtocol.js +3 -3
- package/lib/core/network/protocols/protocol.js +3 -3
- package/lib/core/network/router.js +7 -6
- package/lib/core/plugin/plugin.js +38 -64
- package/lib/core/plugin/pluginContext.d.ts +10 -1
- package/lib/core/plugin/pluginContext.js +2 -0
- package/lib/core/plugin/pluginManifest.js +3 -3
- package/lib/core/plugin/pluginRepository.js +5 -5
- package/lib/core/plugin/pluginsManager.js +29 -28
- package/lib/core/realtime/notification/server.js +1 -1
- package/lib/core/realtime/notification/user.js +1 -1
- package/lib/core/realtime/notifier.js +5 -5
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +176 -0
- package/lib/core/security/profileRepository.js +426 -443
- package/lib/core/security/roleRepository.js +16 -16
- package/lib/core/security/securityLoader.js +3 -3
- package/lib/core/security/tokenRepository.js +18 -21
- package/lib/core/security/userRepository.js +8 -8
- package/lib/core/shared/abstractManifest.js +4 -4
- package/lib/core/shared/repository.js +6 -6
- package/lib/core/shared/sdk/funnelProtocol.js +1 -1
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +30 -23
- package/lib/core/statistics/statistics.js +17 -17
- package/lib/core/storage/clientAdapter.js +45 -10
- package/lib/core/validation/baseType.js +5 -5
- package/lib/core/validation/types/anything.js +1 -1
- package/lib/core/validation/types/boolean.js +2 -2
- package/lib/core/validation/types/date.js +9 -9
- package/lib/core/validation/types/email.js +5 -5
- package/lib/core/validation/types/enum.js +6 -6
- package/lib/core/validation/types/geoPoint.js +2 -2
- package/lib/core/validation/types/geoShape.js +28 -25
- package/lib/core/validation/types/integer.js +4 -4
- package/lib/core/validation/types/ipAddress.js +7 -6
- package/lib/core/validation/types/numeric.js +4 -4
- package/lib/core/validation/types/object.js +5 -5
- package/lib/core/validation/types/string.js +5 -5
- package/lib/core/validation/types/url.js +7 -6
- package/lib/core/validation/validation.js +95 -84
- package/lib/kerror/codes/1-services.json +12 -0
- package/lib/kerror/codes/2-api.json +12 -0
- package/lib/kerror/codes/3-network.json +12 -0
- package/lib/kerror/codes/4-plugin.json +6 -0
- package/lib/kerror/codes/index.js +11 -11
- package/lib/kerror/index.js +1 -1
- package/lib/kuzzle/dumpGenerator.js +3 -3
- package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
- package/lib/kuzzle/event/pipeRunner.js +1 -1
- package/lib/kuzzle/event/waterfall.js +6 -6
- package/lib/kuzzle/kuzzle.js +36 -5
- package/lib/kuzzle/log.js +3 -3
- package/lib/kuzzle/vault.js +3 -3
- package/lib/model/security/profile.d.ts +54 -0
- package/lib/model/security/profile.js +174 -233
- package/lib/model/security/rights.js +1 -1
- package/lib/model/security/role.d.ts +40 -0
- package/lib/model/security/role.js +159 -191
- package/lib/model/security/user.d.ts +29 -0
- package/lib/model/security/user.js +84 -52
- package/lib/model/storage/apiKey.js +2 -2
- package/lib/model/storage/baseModel.js +3 -3
- package/lib/service/cache/redis.js +7 -7
- package/lib/service/storage/elasticsearch.js +152 -90
- package/lib/service/storage/esWrapper.js +2 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/ControllerRights.d.ts +22 -0
- package/lib/types/ControllerRights.js +23 -0
- package/lib/types/HttpStream.d.ts +32 -0
- package/lib/types/HttpStream.js +70 -0
- package/lib/types/OpenApiDefinition.d.ts +43 -0
- package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
- package/lib/types/Policy.d.ts +25 -0
- package/lib/types/Policy.js +23 -0
- package/lib/types/PolicyRestrictions.d.ts +21 -0
- package/lib/types/PolicyRestrictions.js +23 -0
- package/lib/types/Target.d.ts +15 -0
- package/lib/types/Target.js +23 -0
- package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
- package/lib/types/index.d.ts +7 -1
- package/lib/types/index.js +7 -1
- package/lib/util/array.d.ts +11 -0
- package/lib/util/array.js +57 -0
- package/lib/util/assertType.js +6 -6
- package/lib/util/bufferedPassThrough.d.ts +76 -0
- package/lib/util/bufferedPassThrough.js +161 -0
- package/lib/util/deprecate.js +7 -5
- package/lib/util/didYouMean.js +1 -1
- package/lib/util/dump-collection.d.ts +3 -0
- package/lib/util/dump-collection.js +265 -0
- package/lib/util/extractFields.js +2 -2
- package/lib/util/inflector.d.ts +8 -0
- package/lib/util/inflector.js +16 -0
- package/lib/util/requestAssertions.js +7 -7
- package/lib/util/wildcard.js +55 -0
- package/package-lock.json +881 -431
- package/package.json +23 -20
- package/lib/api/openApiGenerator.d.ts +0 -7
- package/lib/api/openApiGenerator.js +0 -197
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
|
|
24
24
|
const os = require('os');
|
|
25
25
|
const jsonToYaml = require('json2yaml');
|
|
26
|
+
const packagejson = require('../../../package.json');
|
|
26
27
|
|
|
27
28
|
const { NativeController } = require('./baseController');
|
|
28
|
-
const { generateOpenApi } = require('../openApiGenerator');
|
|
29
29
|
|
|
30
30
|
const kerror = require('../../kerror');
|
|
31
31
|
|
|
@@ -33,9 +33,10 @@ const kerror = require('../../kerror');
|
|
|
33
33
|
* @class ServerController
|
|
34
34
|
*/
|
|
35
35
|
class ServerController extends NativeController {
|
|
36
|
-
constructor() {
|
|
36
|
+
constructor () {
|
|
37
37
|
super([
|
|
38
38
|
'adminExists',
|
|
39
|
+
'capabilities',
|
|
39
40
|
'getAllStats',
|
|
40
41
|
'getConfig',
|
|
41
42
|
'getLastStats',
|
|
@@ -48,12 +49,28 @@ class ServerController extends NativeController {
|
|
|
48
49
|
'openapi',
|
|
49
50
|
]);
|
|
50
51
|
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
this._info = {
|
|
53
|
+
elasticsearch: null,
|
|
54
|
+
redis: null,
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Init ServerController
|
|
60
|
+
* Used to perform asynchronous initialization safely: the funnel will wait
|
|
61
|
+
* for all controllers to be initialized before accepting requests.
|
|
62
|
+
*
|
|
63
|
+
* @returns {Promise}
|
|
64
|
+
*/
|
|
65
|
+
async init () {
|
|
66
|
+
const [storageInfo, cacheInfo] = await Promise.all([
|
|
67
|
+
global.kuzzle.ask('core:storage:public:info:get'),
|
|
68
|
+
global.kuzzle.ask('core:cache:public:info:get'),
|
|
69
|
+
]);
|
|
70
|
+
this._info.elasticsearch = storageInfo;
|
|
71
|
+
this._info.redis = cacheInfo;
|
|
72
|
+
}
|
|
73
|
+
|
|
57
74
|
/**
|
|
58
75
|
* Returns the statistics frame from a date
|
|
59
76
|
*
|
|
@@ -110,6 +127,39 @@ class ServerController extends NativeController {
|
|
|
110
127
|
return config;
|
|
111
128
|
}
|
|
112
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Returns the Kuzzle capabilities
|
|
132
|
+
* @returns {Promise<Object>}
|
|
133
|
+
*/
|
|
134
|
+
async capabilities () {
|
|
135
|
+
const config = JSON.parse(JSON.stringify(global.kuzzle.config));
|
|
136
|
+
const publicApi = await this.publicApi();
|
|
137
|
+
const services = {};
|
|
138
|
+
const plugins = {};
|
|
139
|
+
|
|
140
|
+
for (const plugin of config.plugins.common.include) {
|
|
141
|
+
plugins[plugin] = {
|
|
142
|
+
version: packagejson.dependencies[plugin]
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
for (const [name, info] of Object.entries(config.services)) {
|
|
147
|
+
if (info.backend !== undefined) {
|
|
148
|
+
services[name] = {
|
|
149
|
+
backend: info.backend,
|
|
150
|
+
version: this._info[info.backend].version,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
limits: config.limits,
|
|
157
|
+
plugins: plugins,
|
|
158
|
+
routes: publicApi,
|
|
159
|
+
services: services,
|
|
160
|
+
version: config.version,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
113
163
|
/**
|
|
114
164
|
* Checks if an admin user Exists
|
|
115
165
|
*
|
|
@@ -140,7 +190,7 @@ class ServerController extends NativeController {
|
|
|
140
190
|
if (typeof request.input.args.services === 'string') {
|
|
141
191
|
services = request.input.args.services.split(',');
|
|
142
192
|
}
|
|
143
|
-
if (!services || services.includes('internalCache')) {
|
|
193
|
+
if (! services || services.includes('internalCache')) {
|
|
144
194
|
try {
|
|
145
195
|
await global.kuzzle.ask('core:cache:internal:info:get');
|
|
146
196
|
result.services.internalCache = 'green';
|
|
@@ -151,7 +201,7 @@ class ServerController extends NativeController {
|
|
|
151
201
|
result.status = 'red';
|
|
152
202
|
}
|
|
153
203
|
}
|
|
154
|
-
if (!services || services.includes('memoryStorage')) {
|
|
204
|
+
if (! services || services.includes('memoryStorage')) {
|
|
155
205
|
try {
|
|
156
206
|
await global.kuzzle.ask('core:cache:public:info:get');
|
|
157
207
|
result.services.memoryStorage = 'green';
|
|
@@ -162,7 +212,7 @@ class ServerController extends NativeController {
|
|
|
162
212
|
result.status = 'red';
|
|
163
213
|
}
|
|
164
214
|
}
|
|
165
|
-
if (!services || services.includes('storageEngine')) {
|
|
215
|
+
if (! services || services.includes('storageEngine')) {
|
|
166
216
|
try {
|
|
167
217
|
const response = await global.kuzzle.ask('core:storage:public:info:get');
|
|
168
218
|
|
|
@@ -247,7 +297,19 @@ class ServerController extends NativeController {
|
|
|
247
297
|
|
|
248
298
|
async openapi (request) {
|
|
249
299
|
const format = request.getString('format', 'json');
|
|
250
|
-
const
|
|
300
|
+
const scope = request.getString('scope', 'kuzzle');
|
|
301
|
+
|
|
302
|
+
let definition;
|
|
303
|
+
|
|
304
|
+
if (scope === 'kuzzle') {
|
|
305
|
+
definition = await global.kuzzle.ask('core:api:openapi:kuzzle');
|
|
306
|
+
}
|
|
307
|
+
else if (scope === 'app') {
|
|
308
|
+
definition = await global.kuzzle.ask('core:api:openapi:app');
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
throw kerror.get('api', 'assert', 'unexpected_argument', scope, ['kuzzle', 'app']);
|
|
312
|
+
}
|
|
251
313
|
|
|
252
314
|
request.response.configure({
|
|
253
315
|
format: 'raw',
|
|
@@ -255,23 +317,7 @@ class ServerController extends NativeController {
|
|
|
255
317
|
status: 200,
|
|
256
318
|
});
|
|
257
319
|
|
|
258
|
-
return
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Lazy loading of OpenAPI definition.
|
|
263
|
-
*
|
|
264
|
-
* Mainly because we need to wait all plugin to be loaded
|
|
265
|
-
* to generate the definition.
|
|
266
|
-
*/
|
|
267
|
-
getOpenApiDefinition (format) {
|
|
268
|
-
if (! this._openApiDefinition[format]) {
|
|
269
|
-
this._openApiDefinition[format] = format === 'json'
|
|
270
|
-
? generateOpenApi()
|
|
271
|
-
: jsonToYaml.stringify(generateOpenApi());
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return this._openApiDefinition[format];
|
|
320
|
+
return format === 'json' ? definition : jsonToYaml.stringify(definition);
|
|
275
321
|
}
|
|
276
322
|
|
|
277
323
|
/**
|
|
@@ -293,7 +339,7 @@ class ServerController extends NativeController {
|
|
|
293
339
|
const actionList = {};
|
|
294
340
|
|
|
295
341
|
for (const action of controller._actions) {
|
|
296
|
-
actionList[action] = { action
|
|
342
|
+
actionList[action] = { action, controller: name };
|
|
297
343
|
|
|
298
344
|
// resolve associated http route for each actions
|
|
299
345
|
const routes = httpRoutes.filter(route => {
|
|
@@ -229,7 +229,7 @@ const extractors = ([
|
|
|
229
229
|
}, {});
|
|
230
230
|
|
|
231
231
|
class DocumentExtractor {
|
|
232
|
-
constructor(request) {
|
|
232
|
+
constructor (request) {
|
|
233
233
|
this.request = request;
|
|
234
234
|
|
|
235
235
|
const extractor = extractors[request.input.action];
|
|
@@ -248,11 +248,11 @@ class DocumentExtractor {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
extract() {
|
|
251
|
+
extract () {
|
|
252
252
|
return this.extractMethod(this.request);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
insert(documents) {
|
|
255
|
+
insert (documents) {
|
|
256
256
|
return this.insertMethod(documents, this.request);
|
|
257
257
|
}
|
|
258
258
|
}
|
package/lib/api/funnel.js
CHANGED
|
@@ -61,7 +61,7 @@ const SKIP_TOKEN_VERIF_ACTIONS = ['login', 'checkToken', 'logout'];
|
|
|
61
61
|
* @param {Object} context
|
|
62
62
|
*/
|
|
63
63
|
class PendingRequest {
|
|
64
|
-
constructor(request, fn, context) {
|
|
64
|
+
constructor (request, fn, context) {
|
|
65
65
|
this.request = request;
|
|
66
66
|
this.fn = fn;
|
|
67
67
|
this.context = context;
|
|
@@ -132,7 +132,7 @@ class Funnel {
|
|
|
132
132
|
return Bluebird.all(initPromises);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
loadDocumentEventAliases() {
|
|
135
|
+
loadDocumentEventAliases () {
|
|
136
136
|
this.documentEventAliases = documentEventAliases;
|
|
137
137
|
this.documentEventAliases.mirrorList = {};
|
|
138
138
|
|
|
@@ -223,13 +223,13 @@ class Funnel {
|
|
|
223
223
|
throw error;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
if (!this.pendingRequestsById.has(request.internalId)) {
|
|
226
|
+
if (! this.pendingRequestsById.has(request.internalId)) {
|
|
227
227
|
this.pendingRequestsById.set(
|
|
228
228
|
request.internalId,
|
|
229
229
|
new PendingRequest(request, fn, context));
|
|
230
230
|
this.pendingRequestsQueue.push(request.internalId);
|
|
231
231
|
|
|
232
|
-
if (!this.overloaded) {
|
|
232
|
+
if (! this.overloaded) {
|
|
233
233
|
this.overloaded = true;
|
|
234
234
|
|
|
235
235
|
/*
|
|
@@ -262,23 +262,39 @@ class Funnel {
|
|
|
262
262
|
* @returns {Number} -1: request delayed, 0: request processing, 1: error
|
|
263
263
|
*/
|
|
264
264
|
execute (request, callback) {
|
|
265
|
-
if (!request.input.controller || !request.input.controller.length) {
|
|
265
|
+
if (! request.input.controller || ! request.input.controller.length) {
|
|
266
266
|
callback(
|
|
267
267
|
kerror.get('api', 'assert', 'missing_argument', 'controller'),
|
|
268
268
|
request);
|
|
269
269
|
return 1;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
if (!request.input.action || !request.input.action.length) {
|
|
272
|
+
if (! request.input.action || ! request.input.action.length) {
|
|
273
273
|
callback(
|
|
274
274
|
kerror.get('api', 'assert', 'missing_argument', 'action'),
|
|
275
275
|
request);
|
|
276
276
|
return 1;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
// If there is a body, retrieve the targets if any
|
|
280
|
+
const targets = request.getArray('targets', []);
|
|
281
|
+
/**
|
|
282
|
+
* Only index and collection as a pair or the targets parameter is allowed at the same time
|
|
283
|
+
* otherwise we throw an error because we don't know which one to use to verify the rights
|
|
284
|
+
*/
|
|
285
|
+
if ( targets.length > 0
|
|
286
|
+
&& (request.input.args.index
|
|
287
|
+
|| request.input.args.collection)
|
|
288
|
+
) {
|
|
289
|
+
callback(
|
|
290
|
+
kerror.get('api', 'assert', 'mutually_exclusive', 'index, collection', 'targets'),
|
|
291
|
+
request);
|
|
292
|
+
return 1;
|
|
293
|
+
}
|
|
294
|
+
|
|
279
295
|
if (request.input.headers
|
|
280
296
|
&& has(request.input.headers, 'origin')
|
|
281
|
-
&& !this._isOriginAuthorized(request.input.headers.origin)
|
|
297
|
+
&& ! this._isOriginAuthorized(request.input.headers.origin)
|
|
282
298
|
) {
|
|
283
299
|
debug('Reject request, unauthorized origin %s', request.input.headers.origin);
|
|
284
300
|
return this._executeError(
|
|
@@ -292,7 +308,7 @@ class Funnel {
|
|
|
292
308
|
const executing = this.throttle(req => {
|
|
293
309
|
// if the connection is closed there is no need to execute the request
|
|
294
310
|
// => discarding it
|
|
295
|
-
if (!global.kuzzle.router.isConnectionAlive(req.context)) {
|
|
311
|
+
if (! global.kuzzle.router.isConnectionAlive(req.context)) {
|
|
296
312
|
debug('Client connection dead: dropping request: %a', req.input);
|
|
297
313
|
callback(processError.get('connection_dropped'), req);
|
|
298
314
|
return;
|
|
@@ -314,7 +330,7 @@ class Funnel {
|
|
|
314
330
|
return this.rateLimiter.isAllowed(_request);
|
|
315
331
|
})
|
|
316
332
|
.then(allowed => {
|
|
317
|
-
if (!allowed) {
|
|
333
|
+
if (! allowed) {
|
|
318
334
|
if (request.input.controller === 'auth' && request.input.action === 'login') {
|
|
319
335
|
throw processError.get('too_many_logins_requests');
|
|
320
336
|
}
|
|
@@ -346,7 +362,8 @@ class Funnel {
|
|
|
346
362
|
}, this, request);
|
|
347
363
|
|
|
348
364
|
return executing ? 0 : -1;
|
|
349
|
-
}
|
|
365
|
+
}
|
|
366
|
+
catch (error) {
|
|
350
367
|
request.setError(error);
|
|
351
368
|
callback(error, request);
|
|
352
369
|
return 1;
|
|
@@ -374,11 +391,11 @@ class Funnel {
|
|
|
374
391
|
// JSON.stringify(new NativeError()) === '{}'
|
|
375
392
|
// i.e. Error, SyntaxError, TypeError, ReferenceError, etc.
|
|
376
393
|
global.kuzzle.log.error(
|
|
377
|
-
err instanceof Error && !(err instanceof KuzzleError)
|
|
394
|
+
err instanceof Error && ! (err instanceof KuzzleError)
|
|
378
395
|
? `${err.message}\n${err.stack}`
|
|
379
396
|
: err);
|
|
380
397
|
|
|
381
|
-
if (!this.lastDumpedErrors[errorType]
|
|
398
|
+
if (! this.lastDumpedErrors[errorType]
|
|
382
399
|
|| this.lastDumpedErrors[errorType] < now - handledErrors.minInterval
|
|
383
400
|
) {
|
|
384
401
|
// simplify error message to use it in folder dump name
|
|
@@ -432,7 +449,7 @@ class Funnel {
|
|
|
432
449
|
cookie = Cookie.parse(request.input.headers.cookie);
|
|
433
450
|
}
|
|
434
451
|
catch (error) {
|
|
435
|
-
throw kerror.get('security','cookie', 'invalid');
|
|
452
|
+
throw kerror.get('security', 'cookie', 'invalid');
|
|
436
453
|
}
|
|
437
454
|
|
|
438
455
|
// if cookie is present and not null, and a token is present we should throw because we don't know which one to use
|
|
@@ -546,7 +563,7 @@ class Funnel {
|
|
|
546
563
|
responseData,
|
|
547
564
|
{ status: _request.status === 102 ? 200 : _request.status });
|
|
548
565
|
|
|
549
|
-
if (!this.isNativeController(_request.input.controller) && !_request.response.raw) {
|
|
566
|
+
if (! this.isNativeController(_request.input.controller) && ! _request.response.raw) {
|
|
550
567
|
// check if the plugin response can be serialized
|
|
551
568
|
try {
|
|
552
569
|
JSON.stringify(responseData);
|
|
@@ -591,9 +608,9 @@ class Funnel {
|
|
|
591
608
|
controller === 'document'
|
|
592
609
|
&& this.documentEventAliases.mirrorList[action]
|
|
593
610
|
&& ( prefix !== 'before'
|
|
594
|
-
|| !this.documentEventAliases.notBefore.includes(action));
|
|
611
|
+
|| ! this.documentEventAliases.notBefore.includes(action));
|
|
595
612
|
|
|
596
|
-
if (!mustTrigger) {
|
|
613
|
+
if (! mustTrigger) {
|
|
597
614
|
return request;
|
|
598
615
|
}
|
|
599
616
|
|
|
@@ -680,7 +697,7 @@ class Funnel {
|
|
|
680
697
|
? 'ms'
|
|
681
698
|
: request.input.controller;
|
|
682
699
|
|
|
683
|
-
return`${event}:${prefix}${capitalize(request.input.action)}`;
|
|
700
|
+
return `${event}:${prefix}${capitalize(request.input.action)}`;
|
|
684
701
|
}
|
|
685
702
|
|
|
686
703
|
/**
|
|
@@ -823,10 +840,12 @@ class Funnel {
|
|
|
823
840
|
try {
|
|
824
841
|
if (this.throttle(pendingItem.fn, pendingItem.context, pendingItem.request)) {
|
|
825
842
|
this.pendingRequestsQueue.shift();
|
|
826
|
-
}
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
827
845
|
break;
|
|
828
846
|
}
|
|
829
|
-
}
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
830
849
|
break;
|
|
831
850
|
}
|
|
832
851
|
}
|
|
@@ -857,7 +876,7 @@ class Funnel {
|
|
|
857
876
|
* @returns {KuzzleError}
|
|
858
877
|
*/
|
|
859
878
|
_wrapError (request, error) {
|
|
860
|
-
if (!this.isNativeController(request) && !(error instanceof KuzzleError)) {
|
|
879
|
+
if (! this.isNativeController(request) && ! (error instanceof KuzzleError)) {
|
|
861
880
|
return kerror.getFrom(
|
|
862
881
|
error,
|
|
863
882
|
'plugin',
|
|
@@ -916,7 +935,7 @@ function capitalize (string) {
|
|
|
916
935
|
function doAction (controller, request) {
|
|
917
936
|
const ret = controller[request.input.action](request);
|
|
918
937
|
|
|
919
|
-
if (!ret || typeof ret.then !== 'function') {
|
|
938
|
+
if (! ret || typeof ret.then !== 'function') {
|
|
920
939
|
return kerror.reject(
|
|
921
940
|
'plugin',
|
|
922
941
|
'controller',
|
package/lib/api/httpRoutes.js
CHANGED
|
@@ -34,7 +34,8 @@ const {
|
|
|
34
34
|
OpenApiDocumentGet,
|
|
35
35
|
OpenApiDocumentCreate,
|
|
36
36
|
OpenApiDocumentCreateOrReplace,
|
|
37
|
-
|
|
37
|
+
OpenApiDocumentValidate,
|
|
38
|
+
} = require('./openapi/components/document');
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
const routes = [
|
|
@@ -53,6 +54,7 @@ const routes = [
|
|
|
53
54
|
// We need to expose a GET method for "login" action in order to make authentication protocol like Oauth2 or CAS work:
|
|
54
55
|
{ verb: 'get', path: '/_login/:strategy', controller: 'auth', action: 'login' },
|
|
55
56
|
|
|
57
|
+
{ verb: 'get', path: '/:index/:collection/_export', controller: 'document', action: 'export' },
|
|
56
58
|
{ verb: 'get', path: '/:index/:collection/_exists', controller: 'collection', action: 'exists' },
|
|
57
59
|
{ verb: 'get', path: '/:index/:collection/_mapping', controller: 'collection', action: 'getMapping' },
|
|
58
60
|
{ verb: 'get', path: '/:index/:collection/_search', controller: 'document', action: 'search' },
|
|
@@ -74,6 +76,7 @@ const routes = [
|
|
|
74
76
|
{ verb: 'get', path: '/:index/:collection/:_id', controller: 'document', action: 'get', openapi: OpenApiDocumentGet },
|
|
75
77
|
{ verb: 'get', path: '/:index/:collection/_mGet', controller: 'document', action: 'mGet' },
|
|
76
78
|
{ verb: 'get', path: '/:index/:collection/:_id/_exists', controller: 'document', action: 'exists', openapi: OpenApiDocumentExists },
|
|
79
|
+
{ verb: 'get', path: '/:index/:collection/_mExists', controller: 'document', action: 'mExists' },
|
|
77
80
|
{ verb: 'get', path: '/_scroll/:scrollId', controller: 'document', action: 'scroll', openapi: OpenApiDocumentScroll },
|
|
78
81
|
|
|
79
82
|
{ verb: 'get', path: '/:index/_exists', controller: 'index', action: 'exists' },
|
|
@@ -104,6 +107,7 @@ const routes = [
|
|
|
104
107
|
{ verb: 'get', path: '/_adminExists', controller: 'server', action: 'adminExists' },
|
|
105
108
|
{ verb: 'get', path: '/_getAllStats', controller: 'server', action: 'getAllStats', deprecated: { since: 'auto-version', message: 'Use this route instead: http://kuzzle:7512/_metrics' } }, // @deprecated
|
|
106
109
|
{ verb: 'get', path: '/_getConfig', controller: 'server', action: 'getConfig' },
|
|
110
|
+
{ verb: 'get', path: '/_capabilities', controller: 'server', action: 'capabilities' },
|
|
107
111
|
{ verb: 'get', path: '/_getLastStats', controller: 'server', action: 'getLastStats', deprecated: { since: 'auto-version', message: 'Use this route instead: http://kuzzle:7512/_metrics' } }, // @deprecated
|
|
108
112
|
{ verb: 'get', path: '/_getStats', controller: 'server', action: 'getStats', deprecated: { since: 'auto-version', message: 'Use this route instead: http://kuzzle:7512/_metrics' } }, // @deprecated
|
|
109
113
|
{ verb: 'get', path: '/', controller: 'server', action: 'info' },
|
|
@@ -171,7 +175,7 @@ const routes = [
|
|
|
171
175
|
{ verb: 'get', path: '/ms/_zscan/:_id', controller: 'ms', action: 'zscan' },
|
|
172
176
|
{ verb: 'get', path: '/ms/_zscore/:_id/:member', controller: 'ms', action: 'zscore' },
|
|
173
177
|
{ verb: 'get', path: '/ms/:_id', controller: 'ms', action: 'get' },
|
|
174
|
-
{ verb: 'get', path: '/cluster/_status', controller:'cluster', action: 'status' },
|
|
178
|
+
{ verb: 'get', path: '/cluster/_status', controller: 'cluster', action: 'status' },
|
|
175
179
|
|
|
176
180
|
|
|
177
181
|
// POST
|
|
@@ -202,12 +206,13 @@ const routes = [
|
|
|
202
206
|
{ verb: 'post', path: '/:index/:collection/_create', controller: 'document', action: 'create', openapi: OpenApiDocumentCreate },
|
|
203
207
|
{ verb: 'post', path: '/:index/:collection/:_id/_create', controller: 'document', action: 'create' },
|
|
204
208
|
{ verb: 'post', path: '/:index/:collection/_publish', controller: 'realtime', action: 'publish' },
|
|
209
|
+
{ verb: 'post', path: '/:index/:collection/_export', controller: 'document', action: 'export' },
|
|
205
210
|
{ verb: 'post', path: '/:index/:collection/_search', controller: 'document', action: 'search' },
|
|
206
211
|
{ verb: 'post', path: '/:index/:collection/_mGet', controller: 'document', action: 'mGet' },
|
|
207
212
|
{ verb: 'post', path: '/:index/:collection/_mCreate', controller: 'document', action: 'mCreate' },
|
|
208
213
|
{ verb: 'post', path: '/:index/:collection/_mUpsert', controller: 'document', action: 'mUpsert' },
|
|
209
|
-
{ verb: 'post', path: '/:index/:collection/:_id/_upsert', controller: 'document', action: 'upsert'},
|
|
210
|
-
{ verb: 'post', path: '/:index/:collection/_validate', controller: 'document', action: 'validate' },
|
|
214
|
+
{ verb: 'post', path: '/:index/:collection/:_id/_upsert', controller: 'document', action: 'upsert' },
|
|
215
|
+
{ verb: 'post', path: '/:index/:collection/_validate', controller: 'document', action: 'validate', openapi: OpenApiDocumentValidate },
|
|
211
216
|
|
|
212
217
|
{ verb: 'post', path: '/_createFirstAdmin/:_id', controller: 'security', action: 'createFirstAdmin' },
|
|
213
218
|
{ verb: 'post', path: '/_createFirstAdmin', controller: 'security', action: 'createFirstAdmin' },
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OpenApiDefinition } from '../../types/OpenApiDefinition';
|
|
2
|
+
export declare class OpenApiManager {
|
|
3
|
+
kuzzleDefinition: OpenApiDefinition;
|
|
4
|
+
applicationDefinition: OpenApiDefinition;
|
|
5
|
+
/**
|
|
6
|
+
* @param applicationDefinition Application OpenApi definition
|
|
7
|
+
* @param pluginsManager PluginsManager instance
|
|
8
|
+
*/
|
|
9
|
+
constructor(applicationDefinition: OpenApiDefinition, kuzzleRoutes: any[], pluginsRoutes: any[]);
|
|
10
|
+
registerAskEvents(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Kuzzle, a backend software, self-hostable and ready to use
|
|
4
|
+
* to power modern apps
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2015-2020 Kuzzle
|
|
7
|
+
* mailto: support AT kuzzle.io
|
|
8
|
+
* website: http://kuzzle.io
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
* you may not use this file except in compliance with the License.
|
|
12
|
+
* You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.OpenApiManager = void 0;
|
|
24
|
+
const components_1 = require("./components");
|
|
25
|
+
const package_json_1 = require("../../../package.json");
|
|
26
|
+
const openApiGenerator_1 = require("./openApiGenerator");
|
|
27
|
+
class OpenApiManager {
|
|
28
|
+
/**
|
|
29
|
+
* @param applicationDefinition Application OpenApi definition
|
|
30
|
+
* @param pluginsManager PluginsManager instance
|
|
31
|
+
*/
|
|
32
|
+
constructor(applicationDefinition, kuzzleRoutes, pluginsRoutes) {
|
|
33
|
+
/* eslint-disable sort-keys */
|
|
34
|
+
this.kuzzleDefinition = {
|
|
35
|
+
swagger: '2.0',
|
|
36
|
+
info: {
|
|
37
|
+
title: 'Kuzzle API',
|
|
38
|
+
description: 'Kuzzle HTTP API definition',
|
|
39
|
+
contact: {
|
|
40
|
+
name: 'Kuzzle team',
|
|
41
|
+
url: 'https://kuzzle.io',
|
|
42
|
+
email: 'support@kuzzle.io',
|
|
43
|
+
discord: 'http://join.discord.kuzzle.io'
|
|
44
|
+
},
|
|
45
|
+
license: {
|
|
46
|
+
name: 'Apache 2',
|
|
47
|
+
url: 'http://opensource.org/licenses/apache2.0'
|
|
48
|
+
},
|
|
49
|
+
version: package_json_1.version
|
|
50
|
+
},
|
|
51
|
+
externalDocs: {
|
|
52
|
+
description: 'Kuzzle API Documentation',
|
|
53
|
+
url: 'https://docs.kuzzle.io/core/2/api/'
|
|
54
|
+
},
|
|
55
|
+
servers: [
|
|
56
|
+
{
|
|
57
|
+
url: 'https://{baseUrl}:{port}',
|
|
58
|
+
description: 'Kuzzle Base Url',
|
|
59
|
+
variables: {
|
|
60
|
+
baseUrl: { default: 'localhost' },
|
|
61
|
+
port: { default: 7512 }
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
tags: [],
|
|
66
|
+
schemes: ['https', 'http'],
|
|
67
|
+
paths: {},
|
|
68
|
+
components: {
|
|
69
|
+
...components_1.OpenApiPayloadsDefinitions,
|
|
70
|
+
document: {
|
|
71
|
+
...components_1.OpenApiDocumentCountComponent,
|
|
72
|
+
...components_1.OpenApiDocumentDeleteByQueryComponent,
|
|
73
|
+
...components_1.OpenApiDocumentDeleteComponent,
|
|
74
|
+
...components_1.OpenApiDocumentScrollComponent,
|
|
75
|
+
...components_1.OpenApiDocumentExistsComponent,
|
|
76
|
+
...components_1.OpenApiDocumentUpdateComponent,
|
|
77
|
+
...components_1.OpenApiDocumentReplaceComponent,
|
|
78
|
+
...components_1.OpenApiDocumentGetComponent,
|
|
79
|
+
...components_1.OpenApiDocumentCreateOrReplaceComponent,
|
|
80
|
+
...components_1.OpenApiDocumentCreateComponent,
|
|
81
|
+
...components_1.OpenApiDocumentValidateComponent,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
this.applicationDefinition = applicationDefinition;
|
|
86
|
+
(0, openApiGenerator_1.generateOpenApi)(kuzzleRoutes, this.kuzzleDefinition);
|
|
87
|
+
(0, openApiGenerator_1.generateOpenApi)(pluginsRoutes, this.applicationDefinition);
|
|
88
|
+
this.registerAskEvents();
|
|
89
|
+
}
|
|
90
|
+
registerAskEvents() {
|
|
91
|
+
global.kuzzle.onAsk('core:api:openapi:kuzzle', () => this.kuzzleDefinition);
|
|
92
|
+
global.kuzzle.onAsk('core:api:openapi:app', () => this.applicationDefinition);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.OpenApiManager = OpenApiManager;
|
|
96
|
+
//# sourceMappingURL=OpenApiManager.js.map
|
|
@@ -16,12 +16,12 @@ DocumentCount:
|
|
|
16
16
|
description: "Counts documents in a collection."
|
|
17
17
|
required: true
|
|
18
18
|
schema:
|
|
19
|
-
$ref: "#/components/
|
|
19
|
+
$ref: "#/components/document/DocumentCountRequest"
|
|
20
20
|
responses:
|
|
21
21
|
200:
|
|
22
22
|
description: "Counts documents in a collection."
|
|
23
23
|
schema:
|
|
24
|
-
$ref: "#/components/
|
|
24
|
+
$ref: "#/components/document/DocumentCountResponse"
|
|
25
25
|
|
|
26
26
|
components:
|
|
27
27
|
schemas:
|
|
@@ -16,12 +16,12 @@ DocumentCreate:
|
|
|
16
16
|
description: "Creates a new document in the persistent data storage."
|
|
17
17
|
required: true
|
|
18
18
|
schema:
|
|
19
|
-
$ref: "#/components/
|
|
19
|
+
$ref: "#/components/document/DocumentCreateRequest"
|
|
20
20
|
responses:
|
|
21
21
|
200:
|
|
22
22
|
description: "Creates a new document in the persistent data storage."
|
|
23
23
|
schema:
|
|
24
|
-
$ref: "#/components/
|
|
24
|
+
$ref: "#/components/document/DocumentCreateResponse"
|
|
25
25
|
|
|
26
26
|
components:
|
|
27
27
|
schemas:
|
|
@@ -28,12 +28,12 @@ DocumentCreateOrReplace:
|
|
|
28
28
|
description: "Creates a new document in the persistent data storage, or replaces its content if it already exists."
|
|
29
29
|
required: true
|
|
30
30
|
schema:
|
|
31
|
-
$ref: "#/components/
|
|
31
|
+
$ref: "#/components/document/DocumentCreateOrReplaceRequest"
|
|
32
32
|
responses:
|
|
33
33
|
200:
|
|
34
34
|
description: "Creates a new document in the persistent data storage, or replaces its content if it already exists."
|
|
35
35
|
schema:
|
|
36
|
-
$ref: "#/components/
|
|
36
|
+
$ref: "#/components/document/DocumentCreateOrReplaceResponse"
|
|
37
37
|
|
|
38
38
|
components:
|
|
39
39
|
schemas:
|
|
@@ -47,12 +47,12 @@ DocumentDeleteByQuery:
|
|
|
47
47
|
description: "Deletes documents matching the provided search query."
|
|
48
48
|
required: true
|
|
49
49
|
schema:
|
|
50
|
-
$ref: "#/components/
|
|
50
|
+
$ref: "#/components/document/DocumentDeleteByQueryRequest"
|
|
51
51
|
responses:
|
|
52
52
|
200:
|
|
53
53
|
description: "Deletes documents matching the provided search query."
|
|
54
54
|
schema:
|
|
55
|
-
$ref: "#/components/
|
|
55
|
+
$ref: "#/components/document/DocumentDeleteByQueryResponse"
|
|
56
56
|
|
|
57
57
|
components:
|
|
58
58
|
schemas:
|
|
@@ -18,3 +18,5 @@ export declare const OpenApiDocumentDelete: any;
|
|
|
18
18
|
export declare const OpenApiDocumentDeleteComponent: any;
|
|
19
19
|
export declare const OpenApiDocumentDeleteByQuery: any;
|
|
20
20
|
export declare const OpenApiDocumentDeleteByQueryComponent: any;
|
|
21
|
+
export declare const OpenApiDocumentValidate: any;
|
|
22
|
+
export declare const OpenApiDocumentValidateComponent: any;
|