kuzzle 2.17.8 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +3 -0
  3. package/lib/api/controllers/adminController.js +9 -0
  4. package/lib/api/controllers/authController.js +8 -2
  5. package/lib/api/controllers/debugController.d.ts +59 -0
  6. package/lib/api/controllers/debugController.js +285 -0
  7. package/lib/api/controllers/documentController.js +49 -31
  8. package/lib/api/controllers/index.js +1 -0
  9. package/lib/api/controllers/indexController.js +10 -6
  10. package/lib/api/controllers/securityController.js +81 -43
  11. package/lib/api/controllers/serverController.js +2 -1
  12. package/lib/api/documentExtractor.js +51 -9
  13. package/lib/api/funnel.js +30 -8
  14. package/lib/api/httpRoutes.js +8 -1
  15. package/lib/api/openapi/OpenApiManager.js +3 -0
  16. package/lib/api/openapi/components/document/get.yaml +1 -1
  17. package/lib/api/openapi/components/document/update.yaml +1 -1
  18. package/lib/api/openapi/components/index.d.ts +1 -0
  19. package/lib/api/openapi/components/index.js +1 -0
  20. package/lib/api/openapi/components/security/index.d.ts +2 -0
  21. package/lib/api/openapi/components/security/index.js +10 -0
  22. package/lib/api/openapi/components/security/upsertUser.yaml +59 -0
  23. package/lib/api/request/kuzzleRequest.d.ts +58 -4
  24. package/lib/api/request/kuzzleRequest.js +163 -31
  25. package/lib/api/request/requestResponse.js +25 -0
  26. package/lib/cluster/idCardHandler.js +1 -1
  27. package/lib/config/default.config.js +3 -0
  28. package/lib/config/documentEventAliases.d.ts +7 -0
  29. package/lib/config/documentEventAliases.js +26 -12
  30. package/lib/core/backend/backend.d.ts +4 -0
  31. package/lib/core/backend/backend.js +9 -0
  32. package/lib/core/backend/backendController.d.ts +7 -1
  33. package/lib/core/backend/backendController.js +15 -3
  34. package/lib/core/network/protocols/httpwsProtocol.js +14 -6
  35. package/lib/core/plugin/plugin.js +7 -0
  36. package/lib/core/shared/sdk/embeddedSdk.d.ts +3 -3
  37. package/lib/core/shared/sdk/embeddedSdk.js +33 -0
  38. package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -2
  39. package/lib/kerror/codes/0-core.json +35 -0
  40. package/lib/kerror/codes/1-services.json +1 -1
  41. package/lib/kerror/codes/2-api.json +6 -0
  42. package/lib/kerror/errors/kuzzleError.d.ts +1 -1
  43. package/lib/kuzzle/kuzzle.d.ts +1 -1
  44. package/lib/kuzzle/kuzzle.js +27 -8
  45. package/lib/model/security/user.js +5 -6
  46. package/lib/model/storage/apiKey.js +1 -6
  47. package/lib/service/storage/elasticsearch.js +143 -47
  48. package/lib/types/DebugModule.d.ts +23 -0
  49. package/lib/types/DebugModule.js +39 -0
  50. package/lib/types/config/SecurityConfiguration.d.ts +10 -0
  51. package/lib/types/index.d.ts +0 -1
  52. package/lib/types/index.js +0 -1
  53. package/lib/util/crypto.d.ts +1 -0
  54. package/lib/util/crypto.js +12 -0
  55. package/lib/util/dump-collection.d.ts +35 -0
  56. package/lib/util/dump-collection.js +11 -8
  57. package/lib/util/name-generator.d.ts +79 -0
  58. package/lib/util/name-generator.js +1409 -1345
  59. package/lib/util/time.d.ts +1 -0
  60. package/lib/util/time.js +9 -0
  61. package/package.json +19 -21
  62. package/lib/core/security/README.md +0 -224
  63. package/lib/core/shared/README.md +0 -3
  64. package/package-lock.json +0 -8403
@@ -31,13 +31,18 @@ const { NativeController } = require('./baseController');
31
31
  const formatProcessing = require('../../core/auth/formatProcessing');
32
32
  const ApiKey = require('../../model/storage/apiKey');
33
33
  const kerror = require('../../kerror');
34
- const { has, get } = require('../../util/safeObject');
35
- const { generateRandomName } = require('../../util/name-generator');
34
+ const { has } = require('../../util/safeObject');
35
+ const { NameGenerator } = require('../../util/name-generator');
36
36
 
37
37
  /**
38
38
  * @class SecurityController
39
39
  */
40
40
  class SecurityController extends NativeController {
41
+
42
+ static userOrSdk (userId) {
43
+ return userId === null ? 'EmbeddedSDK' : `User "${userId}"`;
44
+ }
45
+
41
46
  constructor () {
42
47
  super([
43
48
  'checkRights',
@@ -92,6 +97,7 @@ class SecurityController extends NativeController {
92
97
  'updateRoleMapping',
93
98
  'updateUser',
94
99
  'updateUserMapping',
100
+ 'upsertUser',
95
101
  'validateCredentials'
96
102
  ]);
97
103
 
@@ -149,7 +155,7 @@ class SecurityController extends NativeController {
149
155
  refresh,
150
156
  });
151
157
 
152
- global.kuzzle.log.info(`[SECURITY] User "${creatorId}" applied action "${request.input.action}" on user "${userId}."`);
158
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(creatorId)} applied action "${request.input.action}" on user "${userId}."`);
153
159
  return apiKey.serialize({ includeToken: true });
154
160
  }
155
161
 
@@ -371,7 +377,7 @@ class SecurityController extends NativeController {
371
377
  userId,
372
378
  });
373
379
 
374
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on role "${role._id}."`);
380
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on role "${role._id}."`);
375
381
  return formatProcessing.serializeRole(role);
376
382
  }
377
383
 
@@ -392,7 +398,7 @@ class SecurityController extends NativeController {
392
398
  userId,
393
399
  });
394
400
 
395
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on role "${role._id}."`);
401
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on role "${role._id}."`);
396
402
  return formatProcessing.serializeRole(role);
397
403
  }
398
404
 
@@ -409,7 +415,7 @@ class SecurityController extends NativeController {
409
415
  refresh: request.getRefresh('wait_for')
410
416
  });
411
417
 
412
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action} on role "${id}."`);
418
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action} on role "${id}."`);
413
419
 
414
420
  // @todo This avoids a breaking change... but we should really return
415
421
  // an acknowledgment.
@@ -472,7 +478,7 @@ class SecurityController extends NativeController {
472
478
  userId,
473
479
  });
474
480
 
475
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on profile "${profile._id}."`);
481
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on profile "${profile._id}."`);
476
482
 
477
483
  return formatProcessing.serializeProfile(profile);
478
484
  }
@@ -501,7 +507,7 @@ class SecurityController extends NativeController {
501
507
  userId,
502
508
  });
503
509
 
504
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on profile "${profile._id}."`);
510
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on profile "${profile._id}."`);
505
511
 
506
512
  return formatProcessing.serializeProfile(profile);
507
513
  }
@@ -522,7 +528,7 @@ class SecurityController extends NativeController {
522
528
 
523
529
  await this.ask('core:security:profile:delete', id, options);
524
530
 
525
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on profile "${id}."`);
531
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on profile "${id}."`);
526
532
 
527
533
  // @todo - replace by an acknowledgement
528
534
  return { _id: id };
@@ -602,7 +608,8 @@ class SecurityController extends NativeController {
602
608
  ids = request.getBodyArray('ids');
603
609
  }
604
610
  else {
605
- ids = request.getString('ids').split(',');
611
+ // @deprecated Should be replaced with request.getArray('ids')
612
+ ids = request.getArrayLegacy('ids');
606
613
  }
607
614
 
608
615
  const users = await this.ask('core:security:user:mGet', ids);
@@ -757,7 +764,7 @@ class SecurityController extends NativeController {
757
764
 
758
765
  await this.ask('core:security:user:delete', id, options);
759
766
 
760
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action}" on user "${id}."`);
767
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action}" on user "${id}."`);
761
768
 
762
769
  return { _id: id };
763
770
  }
@@ -770,17 +777,9 @@ class SecurityController extends NativeController {
770
777
  */
771
778
  async createUser (request) {
772
779
  const content = request.getBodyObject('content');
773
- const profileIds = get(content, 'profileIds');
780
+ const profileIds = request.getBodyArray('content.profileIds');
774
781
  const humanReadableId = request.getString('kuid', 'human') !== 'uuid';
775
782
 
776
- if (profileIds === undefined) {
777
- throw kerror.get('api', 'assert', 'missing_argument', 'body.content.profileIds');
778
- }
779
-
780
- if (! Array.isArray(profileIds)) {
781
- throw kerror.get('api', 'assert', 'invalid_type', 'body.content.profileIds', 'array');
782
- }
783
-
784
783
  return this._persistUser(request, profileIds, content, { humanReadableId });
785
784
  }
786
785
 
@@ -819,20 +818,38 @@ class SecurityController extends NativeController {
819
818
  ? null
820
819
  : request.getBodyArray('profileIds');
821
820
 
822
- const updated = await this.ask(
823
- 'core:security:user:update',
824
- id,
825
- profileIds,
826
- content,
827
- {
828
- refresh: request.getRefresh('wait_for'),
829
- retryOnConflict: request.getInteger('retryOnConflict', 10),
830
- userId,
831
- });
821
+ return this._changeUser(request, id, content, userId, profileIds);
822
+ }
832
823
 
833
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on user "${id}."`);
824
+ /**
825
+ * Applies a partial update to an existing user.
826
+ * If the user doesn't already exist, a new user is created.
827
+ *
828
+ * @param {Request} request
829
+ * @returns {Promise}
830
+ */
831
+ async upsertUser (request) {
832
+ const id = request.getId();
833
+ const content = request.getBodyObject('content');
834
+ const userId = request.getKuid();
835
+ const profileIds = request.getBodyArray('content.profileIds');
836
+ const defaultValues = request.getBodyObject('default', {});
834
837
 
835
- return formatProcessing.serializeUser(updated);
838
+ try {
839
+ return await this._changeUser(request, id, content, userId, profileIds);
840
+ }
841
+ catch (error) {
842
+ if (error.id && error.id === 'security.user.not_found') {
843
+ const creatingContent = {
844
+ ...defaultValues,
845
+ ...content, // Order important, content erase default duplicates
846
+ };
847
+
848
+ return this._persistUser(request, profileIds, creatingContent);
849
+ }
850
+
851
+ throw error;
852
+ }
836
853
  }
837
854
 
838
855
  /**
@@ -854,7 +871,7 @@ class SecurityController extends NativeController {
854
871
  content,
855
872
  { refresh: request.getRefresh('wait_for'), userId });
856
873
 
857
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on user "${id}."`);
874
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on user "${id}."`);
858
875
 
859
876
  return formatProcessing.serializeUser(user);
860
877
  }
@@ -877,7 +894,7 @@ class SecurityController extends NativeController {
877
894
  userId,
878
895
  });
879
896
 
880
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on profile "${id}."`);
897
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on profile "${id}."`);
881
898
  return formatProcessing.serializeProfile(updated);
882
899
  }
883
900
 
@@ -899,7 +916,7 @@ class SecurityController extends NativeController {
899
916
  userId,
900
917
  });
901
918
 
902
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}" on role "${id}."`);
919
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on role "${id}."`);
903
920
 
904
921
  return formatProcessing.serializeRole(updated);
905
922
  }
@@ -940,7 +957,7 @@ class SecurityController extends NativeController {
940
957
  }
941
958
  }
942
959
 
943
- global.kuzzle.log.info(`[SECURITY] User "${userId}" applied action "${request.input.action}".`);
960
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}".`);
944
961
 
945
962
  return user;
946
963
  }
@@ -1029,7 +1046,7 @@ class SecurityController extends NativeController {
1029
1046
 
1030
1047
  const createMethod = this.getStrategyMethod(strategy, 'create');
1031
1048
 
1032
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action}" on user "${id}."`);
1049
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action}" on user "${id}."`);
1033
1050
  return createMethod(request, body, id, strategy);
1034
1051
  }
1035
1052
 
@@ -1053,7 +1070,7 @@ class SecurityController extends NativeController {
1053
1070
 
1054
1071
  const updateMethod = this.getStrategyMethod(strategy, 'update');
1055
1072
 
1056
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action}" on user "${id}."`);
1073
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action}" on user "${id}."`);
1057
1074
 
1058
1075
  return updateMethod(request, body, id, strategy);
1059
1076
  }
@@ -1106,7 +1123,7 @@ class SecurityController extends NativeController {
1106
1123
 
1107
1124
  await deleteMethod(request, id, strategy);
1108
1125
 
1109
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action}" on user "${id}."`);
1126
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action}" on user "${id}."`);
1110
1127
 
1111
1128
  return { acknowledged: true };
1112
1129
  }
@@ -1217,15 +1234,36 @@ class SecurityController extends NativeController {
1217
1234
  }
1218
1235
 
1219
1236
  if (successes.length > 1000) {
1220
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" deleted the following ${type}s: ${successes.slice(0, 1000).join(', ')}... (${successes.length - 1000} more users deleted)."`);
1237
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} deleted the following ${type}s: ${successes.slice(0, 1000).join(', ')}... (${successes.length - 1000} more users deleted)."`);
1221
1238
  }
1222
1239
  else {
1223
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" deleted the following ${type}s: ${successes.join(', ')}."`);
1240
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} deleted the following ${type}s: ${successes.join(', ')}."`);
1224
1241
  }
1225
1242
 
1226
1243
  return successes;
1227
1244
  }
1228
1245
 
1246
+ /**
1247
+ * @returns {Promise}
1248
+ * @private
1249
+ */
1250
+ async _changeUser (request, id, content, userId, profileIds) {
1251
+ const updated = await this.ask(
1252
+ 'core:security:user:update',
1253
+ id,
1254
+ profileIds,
1255
+ content,
1256
+ {
1257
+ refresh: request.getRefresh('wait_for'),
1258
+ retryOnConflict: request.getInteger('retryOnConflict', 10),
1259
+ userId,
1260
+ });
1261
+
1262
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(userId)} applied action "${request.input.action}" on user "${id}."`);
1263
+
1264
+ return formatProcessing.serializeUser(updated);
1265
+ }
1266
+
1229
1267
  /**
1230
1268
  * @param {Request} request
1231
1269
  * @returns {Promise}
@@ -1235,7 +1273,7 @@ class SecurityController extends NativeController {
1235
1273
  const credentials = request.getBodyObject('credentials', {});
1236
1274
  const strategies = Object.keys(credentials);
1237
1275
  const generator = humanReadableId
1238
- ? () => generateRandomName('kuid')
1276
+ ? () => NameGenerator.generateRandomName({ prefix: 'kuid' })
1239
1277
  : () => 'kuid-' + uuidv4();
1240
1278
 
1241
1279
  let id = '';
@@ -1315,7 +1353,7 @@ class SecurityController extends NativeController {
1315
1353
  }
1316
1354
 
1317
1355
  if (creationFailure === null) {
1318
- global.kuzzle.log.info(`[SECURITY] User "${request.getKuid()}" applied action "${request.input.action}" on user "${id}."`);
1356
+ global.kuzzle.log.info(`[SECURITY] ${SecurityController.userOrSdk(request.getKuid())} applied action "${request.input.action}" on user "${id}."`);
1319
1357
  return createdUser;
1320
1358
  }
1321
1359
 
@@ -188,7 +188,8 @@ class ServerController extends NativeController {
188
188
 
189
189
  let services;
190
190
  if (typeof request.input.args.services === 'string') {
191
- services = request.input.args.services.split(',');
191
+ // @deprecated Should be replaced with request.getArray('services')
192
+ services = request.getArrayLegacy('services');
192
193
  }
193
194
  if (! services || services.includes('internalCache')) {
194
195
  try {
@@ -26,6 +26,27 @@ const kerror = require('../kerror');
26
26
  const assertionError = kerror.wrap('api', 'assert');
27
27
 
28
28
  const extractors = ([
29
+ {
30
+ methods: {
31
+ extractFromRequest: request => [
32
+ {
33
+ _id: request.input.args._id,
34
+ _source: request.input.body.fields,
35
+ },
36
+ ],
37
+ extractFromResult: request => [request.result],
38
+ insertInRequest: ([documents], request) => {
39
+ request.input.args._id = documents._id;
40
+ request.input.body.fields = documents._source;
41
+ return request;
42
+ },
43
+ insertInResult: ([document], request) => {
44
+ request.setResult(document, { status: request.status });
45
+ return request;
46
+ },
47
+ },
48
+ targets: [ 'deleteFields' ]
49
+ },
29
50
  {
30
51
  methods: {
31
52
  extractFromRequest: request => [{ _id: request.input.args._id }],
@@ -39,7 +60,7 @@ const extractors = ([
39
60
  return request;
40
61
  }
41
62
  },
42
- targets: ['delete', 'get']
63
+ targets: [ 'delete', 'get', 'exists' ]
43
64
  },
44
65
  {
45
66
  methods: {
@@ -56,7 +77,8 @@ const extractors = ([
56
77
  ids = request.input.args.ids;
57
78
  }
58
79
  else if (typeof request.input.args.ids === 'string') {
59
- ids = request.input.args.ids.split(',');
80
+ // @deprecated Should be replaced with request.getArray('ids')
81
+ ids = request.getArrayLegacy('ids');
60
82
  }
61
83
  else {
62
84
  throw assertionError.get(
@@ -117,7 +139,7 @@ const extractors = ([
117
139
  return request;
118
140
  }
119
141
  },
120
- targets: ['mDelete', 'mGet']
142
+ targets: [ 'mDelete', 'mGet', 'mExists' ]
121
143
  },
122
144
  {
123
145
  methods: {
@@ -127,21 +149,41 @@ const extractors = ([
127
149
  for (let it = 0; it < request.input.body.documents.length; it++) {
128
150
  const document = request.input.body.documents[it];
129
151
 
130
- documents.push({ _id: document._id, _source: document.body });
152
+ if (request.input.action === 'mUpsert') {
153
+ documents.push({
154
+ _id: document._id,
155
+ _source: document.changes,
156
+ });
157
+ }
158
+ else {
159
+ documents.push({ _id: document._id, _source: document.body });
160
+ }
131
161
  }
132
162
 
133
163
  return documents;
134
164
  },
135
165
  extractFromResult: request => request.result.successes,
136
166
  insertInRequest: (documents, request) => {
167
+ const tmpDocuments = request.input.body.documents;
168
+
137
169
  request.input.body.documents = [];
138
170
 
139
171
  for (let it = 0; it < documents.length; it++) {
140
172
  const document = documents[it];
141
173
 
142
- request.input.body.documents.push({
143
- _id: document._id,
144
- body: document._source });
174
+ if (request.input.action === 'mUpsert') {
175
+ request.input.body.documents.push({
176
+ _id: document._id,
177
+ changes: document._source,
178
+ default: tmpDocuments[it].default,
179
+ });
180
+ }
181
+ else {
182
+ request.input.body.documents.push({
183
+ _id: document._id,
184
+ body: document._source,
185
+ });
186
+ }
145
187
  }
146
188
 
147
189
  return request;
@@ -157,7 +199,7 @@ const extractors = ([
157
199
  return request;
158
200
  }
159
201
  },
160
- targets: ['mCreate', 'mCreateOrReplace', 'mReplace', 'mUpdate', 'updateByQuery']
202
+ targets: [ 'mCreate', 'mCreateOrReplace', 'mReplace', 'mUpdate', 'updateByQuery', 'mUpsert' ]
161
203
  },
162
204
  {
163
205
  methods: {
@@ -177,7 +219,7 @@ const extractors = ([
177
219
  return request;
178
220
  },
179
221
  },
180
- targets: ['search', 'deleteByQuery'],
222
+ targets: [ 'search', 'deleteByQuery', 'export' ],
181
223
  },
182
224
  {
183
225
  methods: {
package/lib/api/funnel.js CHANGED
@@ -33,6 +33,7 @@ const {
33
33
  BulkController,
34
34
  ClusterController,
35
35
  CollectionController,
36
+ DebugController,
36
37
  DocumentController,
37
38
  IndexController,
38
39
  MemoryStorageController,
@@ -40,7 +41,7 @@ const {
40
41
  SecurityController,
41
42
  ServerController,
42
43
  } = require('./controllers');
43
- const documentEventAliases = require('../config/documentEventAliases');
44
+ const { documentEventAliases } = require('../config/documentEventAliases');
44
45
  const DocumentExtractor = require('./documentExtractor');
45
46
  const sdkCompatibility = require('../config/sdkCompatibility');
46
47
  const RateLimiter = require('./rateLimiter');
@@ -115,6 +116,7 @@ class Funnel {
115
116
  this.controllers.set('bulk', new BulkController());
116
117
  this.controllers.set('cluster', new ClusterController());
117
118
  this.controllers.set('collection', new CollectionController());
119
+ this.controllers.set('debug', new DebugController());
118
120
  this.controllers.set('document', new DocumentController());
119
121
  this.controllers.set('index', new IndexController());
120
122
  this.controllers.set('realtime', new RealtimeController());
@@ -344,19 +346,39 @@ class Funnel {
344
346
  modifiedRequest.id,
345
347
  processResult);
346
348
 
347
- callback(null, processResult);
348
-
349
- // disables a bluebird warning in dev. mode triggered when
350
- // a promise is created and not returned
351
- return null;
349
+ return global.kuzzle.pipe(
350
+ 'request:afterExecution',
351
+ {
352
+ request: _request,
353
+ result: processResult,
354
+ success: true,
355
+ })
356
+ .then(pipeEvent => {
357
+ callback(null, pipeEvent.result);
358
+
359
+ // disables a bluebird warning in dev. mode triggered when
360
+ // a promise is created and not returned
361
+ return null;
362
+ });
352
363
  }).catch(err => {
353
364
  debug('Error processing request %s: %a', modifiedRequest.id, err);
354
- return this._executeError(err, modifiedRequest, true, callback);
365
+ return global.kuzzle.pipe(
366
+ 'request:afterExecution',
367
+ {
368
+ error: err,
369
+ request: modifiedRequest,
370
+ success: false,
371
+ }).then(pipeEvent => this._executeError(pipeEvent.error, pipeEvent.request, true, callback));
355
372
  });
356
373
  })
357
374
  .catch(err => {
358
375
  debug('Error processing request %s: %a', req.id, err);
359
- return this._executeError(err, req, true, callback);
376
+ return global.kuzzle.pipe('request:afterExecution',
377
+ {
378
+ error: err,
379
+ request: req,
380
+ success: false,
381
+ }).then(pipeEvent => this._executeError(pipeEvent.error, pipeEvent.request, true, callback));
360
382
  });
361
383
  });
362
384
  }, this, request);
@@ -35,10 +35,10 @@ const {
35
35
  OpenApiDocumentCreate,
36
36
  OpenApiDocumentCreateOrReplace,
37
37
  OpenApiDocumentValidate,
38
+ OpenApiSecurityUpsertUser,
38
39
  OpenApiDocumentmCreateOrReplace,
39
40
  } = require('./openapi/components');
40
41
 
41
-
42
42
  const routes = [
43
43
  // GET (idempotent)
44
44
  { verb: 'get', path: '/_me', controller: 'auth', action: 'getCurrentUser' },
@@ -52,6 +52,12 @@ const routes = [
52
52
  { verb: 'get', path: '/credentials/:strategy/_me', controller: 'auth', action: 'getMyCredentials', deprecated: { since: '2.4.0', message: 'Use this route instead: http://kuzzle:7512/_me/credentials/:strategy' } }, // @deprecated
53
53
  { verb: 'get', path: '/credentials/:strategy/_me/_exists', controller: 'auth', action: 'credentialsExist', deprecated: { since: '2.4.0', message: 'Use this route instead: http://kuzzle:7512/_me/credentials/:strategy/_exists' } }, // @deprecated
54
54
 
55
+ { verb: 'get', path: '/debug/_nodeVersion', controller: 'debug', action: 'nodeVersion' },
56
+ { verb: 'post', path: '/debug/_post', controller: 'debug', action: 'post' },
57
+ { verb: 'post', path: '/debug/_enable', controller: 'debug', action: 'enable' },
58
+ { verb: 'post', path: '/debug/_disable', controller: 'debug', action: 'disable' },
59
+
60
+
55
61
  // We need to expose a GET method for "login" action in order to make authentication protocol like Oauth2 or CAS work:
56
62
  { verb: 'get', path: '/_login/:strategy', controller: 'auth', action: 'login' },
57
63
 
@@ -235,6 +241,7 @@ const routes = [
235
241
  { verb: 'post', path: '/roles/_search', controller: 'security', action: 'searchRoles' },
236
242
  { verb: 'post', path: '/users/_search', controller: 'security', action: 'searchUsers' },
237
243
  { verb: 'post', path: '/credentials/:strategy/users/_search', controller: 'security', action: 'searchUsersByCredentials' },
244
+ { verb: 'post', path: '/users/:_id/_upsert', controller: 'security', action: 'upsertUser', openapi: OpenApiSecurityUpsertUser },
238
245
  { verb: 'post', path: '/credentials/:strategy/:_id/_validate', controller: 'security', action: 'validateCredentials' },
239
246
  { verb: 'post', path: '/_checkRights', controller: 'auth', action: 'checkRights' },
240
247
  { verb: 'post', path: '/_checkRights/:userId', controller: 'security', action: 'checkRights' },
@@ -79,6 +79,9 @@ class OpenApiManager {
79
79
  ...components_1.OpenApiDocumentCreateOrReplaceComponent,
80
80
  ...components_1.OpenApiDocumentCreateComponent,
81
81
  ...components_1.OpenApiDocumentValidateComponent,
82
+ },
83
+ security: {
84
+ ...components_1.OpenApiSecurityUpsertUserComponent,
82
85
  ...components_1.OpenApiDocumentmCreateOrReplaceComponent,
83
86
  }
84
87
  }
@@ -14,7 +14,7 @@ DocumentGet:
14
14
  type: string
15
15
  required: true
16
16
  - in: path
17
- name: documentId
17
+ name: _id
18
18
  schema:
19
19
  type: string
20
20
  required: true
@@ -75,4 +75,4 @@ components:
75
75
  type: "integer"
76
76
  _source:
77
77
  type: string
78
- description: "partial or entire document"
78
+ description: "partial or entire document"
@@ -1,2 +1,3 @@
1
1
  export * from './document';
2
+ export * from './security';
2
3
  export declare const OpenApiPayloadsDefinitions: any;
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.OpenApiPayloadsDefinitions = void 0;
18
18
  const readYamlFile_1 = require("../../../util/readYamlFile");
19
19
  __exportStar(require("./document"), exports);
20
+ __exportStar(require("./security"), exports);
20
21
  // Document definitions (reusable object for KuzzleRequest and KuzzleResponse)
21
22
  exports.OpenApiPayloadsDefinitions = (0, readYamlFile_1.readYamlFile)(__dirname + '/payloads.yaml').definitions;
22
23
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ export declare const OpenApiSecurityUpsertUser: any;
2
+ export declare const OpenApiSecurityUpsertUserComponent: any;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenApiSecurityUpsertUserComponent = exports.OpenApiSecurityUpsertUser = void 0;
4
+ const readYamlFile_1 = require("../../../../util/readYamlFile");
5
+ // reading the description of the UpsertUser action in the controller security.
6
+ // The yaml objects are then stored in the variables below
7
+ const upsertUserObject = (0, readYamlFile_1.readYamlFile)(__dirname + '/upsertUser.yaml');
8
+ exports.OpenApiSecurityUpsertUser = upsertUserObject.SecurityUpsertUser;
9
+ exports.OpenApiSecurityUpsertUserComponent = upsertUserObject.components.schemas;
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,59 @@
1
+ SecurityUpsertUser:
2
+ summary: "Update or create a user."
3
+ tags:
4
+ - user
5
+ parameters:
6
+ - in: path
7
+ name: _id
8
+ schema:
9
+ type: string
10
+ required: true
11
+ - in: path
12
+ name: refresh
13
+ schema:
14
+ type: string
15
+ description: " if set to wait_for, Kuzzle will not respond until the deletion has been indexed"
16
+ required: false
17
+ - in: path
18
+ name: retryOnConflict
19
+ schema:
20
+ type: integer
21
+ description: "conflicts may occur if the same user gets updated multiple times within a short timespan, in a database cluster. You can set the retryOnConflict optional argument (with a retry count), to tell Kuzzle to retry the failing updates the specified amount of times before rejecting the request with an error."
22
+ required: false
23
+ - name: content
24
+ in: "body"
25
+ description: "Updates a user content."
26
+ required: true
27
+ schema:
28
+ $ref: "#/components/security/SecurityUpsertUserRequest"
29
+ responses:
30
+ 200:
31
+ description: "Updates or creates a user."
32
+ schema:
33
+ $ref: "#/components/security/SecurityUpsertUserResponse"
34
+
35
+ components:
36
+ schemas:
37
+ SecurityUpsertUserRequest:
38
+ allOf:
39
+ - type: "object"
40
+ description: "user changes"
41
+ SecurityUpsertUserResponse:
42
+ allOf:
43
+ - $ref: "#/components/ResponsePayload"
44
+ - type: "object"
45
+ properties:
46
+ result:
47
+ type: "object"
48
+ properties:
49
+ _id:
50
+ type: "string"
51
+ description: "userId"
52
+ _version:
53
+ type: "integer"
54
+ _source:
55
+ type: "object"
56
+ description: " (optional) actualized user content. This property appears only if the \"source\" option is set to true"
57
+ created:
58
+ type: "boolean"
59
+