kuzzle 2.50.3 → 2.51.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.
@@ -46,7 +46,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
46
46
  * See the License for the specific language governing permissions and
47
47
  * limitations under the License.
48
48
  */
49
- const http_1 = require("http");
49
+ const node_http_1 = require("node:http");
50
50
  const Cookie = __importStar(require("cookie"));
51
51
  const bluebird_1 = __importDefault(require("bluebird"));
52
52
  const lodash_1 = require("lodash");
@@ -59,6 +59,7 @@ const formatProcessing_1 = __importDefault(require("../../core/auth/formatProces
59
59
  const user_1 = require("../../model/security/user");
60
60
  const apiKey_1 = __importDefault(require("../../model/storage/apiKey"));
61
61
  const securityController_1 = __importDefault(require("./securityController"));
62
+ const securityError = kerror.wrap("security", "token");
62
63
  class AuthController extends baseController_1.NativeController {
63
64
  /**
64
65
  * @param {Kuzzle} kuzzle
@@ -87,7 +88,7 @@ class AuthController extends baseController_1.NativeController {
87
88
  "validateMyCredentials",
88
89
  ]);
89
90
  this.anonymousId = null;
90
- this.logger = global.kuzzle.log.child("api:controllers:auth");
91
+ this.logger = globalThis.kuzzle.log.child("api:controllers:auth");
91
92
  }
92
93
  /**
93
94
  * Controller initialization: we need the anonymous user identifier for the
@@ -96,7 +97,7 @@ class AuthController extends baseController_1.NativeController {
96
97
  * @returns {Promise}
97
98
  */
98
99
  async init() {
99
- const anonymous = await global.kuzzle.ask("core:security:user:anonymous:get");
100
+ const anonymous = await globalThis.kuzzle.ask("core:security:user:anonymous:get");
100
101
  this.anonymousId = anonymous._id;
101
102
  }
102
103
  async createToken(request) {
@@ -191,24 +192,24 @@ class AuthController extends baseController_1.NativeController {
191
192
  * @returns {Promise<object>}
192
193
  */
193
194
  async logout(request) {
194
- if (!global.kuzzle.config.http.cookieAuthentication ||
195
+ if (!globalThis.kuzzle.config.http.cookieAuthentication ||
195
196
  !request.getBoolean("cookieAuth")) {
196
197
  this.assertIsAuthenticated(request);
197
198
  }
198
- if (global.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
199
+ if (globalThis.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
199
200
  // Unlink connection so the connection will not be notified when the token expires.
200
- global.kuzzle.tokenManager.unlink(request.context.token, request.context.connection.id);
201
+ globalThis.kuzzle.tokenManager.unlink(request.context.token, request.context.connection.id);
201
202
  }
202
203
  if (request.context.user._id !== this.anonymousId) {
203
204
  if (request.getBoolean("global")) {
204
- await global.kuzzle.ask("core:security:token:deleteByKuid", request.getKuid(), { keepApiKeys: true });
205
+ await globalThis.kuzzle.ask("core:security:token:deleteByKuid", request.getKuid(), { keepApiKeys: true });
205
206
  }
206
207
  else if (request.context.token &&
207
208
  request.context.token.type !== "apiKey") {
208
- await global.kuzzle.ask("core:security:token:delete", request.context.token);
209
+ await globalThis.kuzzle.ask("core:security:token:delete", request.context.token);
209
210
  }
210
211
  }
211
- if (global.kuzzle.config.http.cookieAuthentication &&
212
+ if (globalThis.kuzzle.config.http.cookieAuthentication &&
212
213
  request.getBoolean("cookieAuth")) {
213
214
  request.response.configure({
214
215
  headers: {
@@ -234,7 +235,7 @@ class AuthController extends baseController_1.NativeController {
234
235
  // otherwise we should send a normal response because
235
236
  // even if the SDK / Browser can handle the cookie,
236
237
  // Kuzzle would not be capable of doing anything with it
237
- if (global.kuzzle.config.http.cookieAuthentication &&
238
+ if (globalThis.kuzzle.config.http.cookieAuthentication &&
238
239
  request.getBoolean("cookieAuth")) {
239
240
  // Here we are not sending auth token when cookieAuth is set to true
240
241
  // This allow us to detect if kuzzle does support cookie as auth token directly from the SDK
@@ -262,7 +263,7 @@ class AuthController extends baseController_1.NativeController {
262
263
  */
263
264
  async login(request) {
264
265
  const strategy = request.getString("strategy");
265
- const passportRequest = new http_1.IncomingMessage(null);
266
+ const passportRequest = new node_http_1.IncomingMessage(null);
266
267
  // Even in http, the url and the method are not pushed back to the request object
267
268
  // set some arbitrary values to get a pseudo-valid object.
268
269
  passportRequest.url = `/login?strategy=${strategy}`;
@@ -278,10 +279,10 @@ class AuthController extends baseController_1.NativeController {
278
279
  passportRequest.rawHeaders.push(passportRequest.headers[h]);
279
280
  }
280
281
  passportRequest.original = request;
281
- if (!(0, safeObject_1.has)(global.kuzzle.pluginsManager.strategies, strategy)) {
282
+ if (!(0, safeObject_1.has)(globalThis.kuzzle.pluginsManager.strategies, strategy)) {
282
283
  throw kerror.get("security", "credentials", "unknown_strategy", strategy);
283
284
  }
284
- const content = await global.kuzzle.passport.authenticate(passportRequest, strategy);
285
+ const content = await globalThis.kuzzle.passport.authenticate(passportRequest, strategy);
285
286
  // do not trigger the "auth:strategyAutenticated" pipe if the result is
286
287
  // not a User object, i.e. if we are a intermediate step of a multi-step
287
288
  // authentication strategy
@@ -300,7 +301,7 @@ class AuthController extends baseController_1.NativeController {
300
301
  if (request.input.args.expiresIn) {
301
302
  options.expiresIn = request.input.args.expiresIn;
302
303
  }
303
- const existingToken = global.kuzzle.tokenManager.getConnectedUserToken(authResponse.content._id, request.context.connection.id);
304
+ const existingToken = globalThis.kuzzle.tokenManager.getConnectedUserToken(authResponse.content._id, request.context.connection.id);
304
305
  /**
305
306
  * If a previous token from the same User is linked to this connection
306
307
  * and the token is either an API Key or an infinite duration token
@@ -313,11 +314,11 @@ class AuthController extends baseController_1.NativeController {
313
314
  }
314
315
  const token = await this.ask("core:security:token:create", authResponse.content, options);
315
316
  if (existingToken) {
316
- global.kuzzle.tokenManager.refresh(existingToken, token);
317
+ globalThis.kuzzle.tokenManager.refresh(existingToken, token);
317
318
  }
318
- if (global.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
319
+ if (globalThis.kuzzle.config.internal.notifiableProtocols.includes(request.context.connection.protocol)) {
319
320
  // Link the connection with the token, this way the connection can be notified when the token has expired.
320
- global.kuzzle.tokenManager.link(token, request.context.connection.id);
321
+ globalThis.kuzzle.tokenManager.link(token, request.context.connection.id);
321
322
  }
322
323
  return this._sendToken(token, request);
323
324
  }
@@ -338,8 +339,8 @@ class AuthController extends baseController_1.NativeController {
338
339
  promises.push(bluebird_1.default.resolve([]));
339
340
  }
340
341
  else {
341
- for (const strategy of global.kuzzle.pluginsManager.listStrategies()) {
342
- const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
342
+ for (const strategy of globalThis.kuzzle.pluginsManager.listStrategies()) {
343
+ const existsMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
343
344
  promises.push(existsMethod(request, userId, strategy)
344
345
  .then((exists) => (exists ? strategy : null))
345
346
  .catch((err) => wrapPluginError(err)));
@@ -371,7 +372,7 @@ class AuthController extends baseController_1.NativeController {
371
372
  */
372
373
  async checkToken(request) {
373
374
  let token = "";
374
- if (global.kuzzle.config.http.cookieAuthentication &&
375
+ if (globalThis.kuzzle.config.http.cookieAuthentication &&
375
376
  request.getBoolean("cookieAuth")) {
376
377
  token = request.input.jwt;
377
378
  }
@@ -414,7 +415,7 @@ class AuthController extends baseController_1.NativeController {
414
415
  * @returns {Promise.<string[]>}
415
416
  */
416
417
  getStrategies() {
417
- return bluebird_1.default.resolve(global.kuzzle.pluginsManager.listStrategies());
418
+ return bluebird_1.default.resolve(globalThis.kuzzle.pluginsManager.listStrategies());
418
419
  }
419
420
  /**
420
421
  * @param {KuzzleRequest} request
@@ -424,7 +425,7 @@ class AuthController extends baseController_1.NativeController {
424
425
  this.assertIsAuthenticated(request);
425
426
  const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
426
427
  this.assertIsStrategyRegistered(strategy);
427
- const createMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "create"), validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
428
+ const createMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "create"), validateMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
428
429
  return validateMethod(request, credentials, userId, strategy, false)
429
430
  .then(() => createMethod(request, credentials, userId, strategy))
430
431
  .catch((err) => wrapPluginError(err));
@@ -437,7 +438,7 @@ class AuthController extends baseController_1.NativeController {
437
438
  this.assertIsAuthenticated(request);
438
439
  const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
439
440
  this.assertIsStrategyRegistered(strategy);
440
- const updateMethod = global.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "update"), validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "validate");
441
+ const updateMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "update"), validateMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(request.input.args.strategy, "validate");
441
442
  return validateMethod(request, credentials, userId, strategy, true)
442
443
  .then(() => updateMethod(request, credentials, userId, strategy))
443
444
  .catch((err) => wrapPluginError(err));
@@ -450,7 +451,7 @@ class AuthController extends baseController_1.NativeController {
450
451
  this.assertIsAuthenticated(request);
451
452
  const userId = request.getKuid(), strategy = request.getString("strategy");
452
453
  this.assertIsStrategyRegistered(strategy);
453
- const existsMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
454
+ const existsMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "exists");
454
455
  return existsMethod(request, userId, strategy).catch((err) => wrapPluginError(err));
455
456
  }
456
457
  /**
@@ -461,7 +462,7 @@ class AuthController extends baseController_1.NativeController {
461
462
  this.assertIsAuthenticated(request);
462
463
  const userId = request.getKuid(), strategy = request.getString("strategy"), credentials = request.getBody();
463
464
  this.assertIsStrategyRegistered(strategy);
464
- const validateMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
465
+ const validateMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "validate");
465
466
  return validateMethod(request, credentials, userId, strategy, false).catch((err) => wrapPluginError(err));
466
467
  }
467
468
  /**
@@ -472,7 +473,7 @@ class AuthController extends baseController_1.NativeController {
472
473
  this.assertIsAuthenticated(request);
473
474
  const userId = request.getKuid(), strategy = request.getString("strategy");
474
475
  this.assertIsStrategyRegistered(strategy);
475
- const deleteMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "delete");
476
+ const deleteMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "delete");
476
477
  return deleteMethod(request, userId, strategy)
477
478
  .then(() => ({ acknowledged: true }))
478
479
  .catch((err) => wrapPluginError(err));
@@ -485,10 +486,10 @@ class AuthController extends baseController_1.NativeController {
485
486
  this.assertIsAuthenticated(request);
486
487
  const userId = request.getKuid(), strategy = request.getString("strategy");
487
488
  this.assertIsStrategyRegistered(strategy);
488
- if (!global.kuzzle.pluginsManager.hasStrategyMethod(strategy, "getInfo")) {
489
+ if (!globalThis.kuzzle.pluginsManager.hasStrategyMethod(strategy, "getInfo")) {
489
490
  return bluebird_1.default.resolve({});
490
491
  }
491
- const getInfoMethod = global.kuzzle.pluginsManager.getStrategyMethod(strategy, "getInfo");
492
+ const getInfoMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "getInfo");
492
493
  return getInfoMethod(request, userId, strategy).catch((err) => wrapPluginError(err));
493
494
  }
494
495
  /**
@@ -496,6 +497,25 @@ class AuthController extends baseController_1.NativeController {
496
497
  */
497
498
  async refreshToken(request) {
498
499
  this.assertIsAuthenticated(request);
500
+ const strategy = request.input.args?.strategy;
501
+ if (request.input.args?.strategy) {
502
+ try {
503
+ const refreshTokenMethod = globalThis.kuzzle.pluginsManager.getStrategyMethod(strategy, "refreshToken");
504
+ await refreshTokenMethod(request);
505
+ }
506
+ catch (err) {
507
+ /**
508
+ * Every strategies does not implement a standard way of returning errors.
509
+ * Which mean we cannot properly catch any errors in the catch block.
510
+ * Meaning if we arrive here, the refresh token did not work as planned
511
+ * We can safely ensure that the user refresh token is not active anymore
512
+ */
513
+ this.logger.error(`Error while refreshing the token with the strategy ${strategy} with ERROR: ${err}`);
514
+ // Adding some debug information to better known our target here.
515
+ this.logger.debug(`Error when refreshing token with request: ${JSON.stringify(request)}`);
516
+ throw securityError.get("refresh_forbidden", request.context.token.jwt);
517
+ }
518
+ }
499
519
  const token = await this.ask("core:security:token:refresh", request.context.user, request.context.token, request.input.args.expiresIn);
500
520
  return this._sendToken(token, request);
501
521
  }
@@ -30,6 +30,7 @@ export type StrategyDefinition = {
30
30
  getById?: string;
31
31
  getInfo?: string;
32
32
  search?: string;
33
+ refreshToken?: string;
33
34
  update: string;
34
35
  validate: string;
35
36
  verify: string;
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kuzzle",
3
3
  "author": "The Kuzzle Team <support@kuzzle.io>",
4
- "version": "2.50.3",
4
+ "version": "2.51.0",
5
5
  "description": "Kuzzle is an open-source solution that handles all the data management through a secured API, with a large choice of protocols.",
6
6
  "scripts": {
7
7
  "build": "rm -Rf ./dist && tsc && node ./bin/copy-protobuf.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kuzzle",
3
3
  "author": "The Kuzzle Team <support@kuzzle.io>",
4
- "version": "2.50.3",
4
+ "version": "2.51.0",
5
5
  "description": "Kuzzle is an open-source solution that handles all the data management through a secured API, with a large choice of protocols.",
6
6
  "scripts": {
7
7
  "build": "rm -Rf ./dist && tsc && node ./bin/copy-protobuf.js",